数据库

JDBC访问数据库的基本步骤

  1. 加载驱动(可省略,static,com.mysql.cj.jdbc.Driver
  2. (通过DriverManager)获取Connection连接
  3. (通过连接)获取PrepareStatement对象(可传入模板)
  4. (通过PrepareStatement)执行SQL语句
  5. 处理结果集
  6. 释放资源

DELETE 与 TRUNCATE 删除表记录区别

  • DELETE每次从表中删除一行,并将该操作作为事务记录在日志中以便回滚,不清空 AUTO_INCREMENT 记录
  • TRUNCATE直接删除表并重新创建新表,不能回滚, AUTO_INCREMENT置为0效率比DELETE高

事务四大特性(ACID)

  • 原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
  • 一致性(Consistency):在事务开始之前和事务结束以后,数据库状态保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
  • 隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
  • 持久性(Durability):一旦事务提交成功,它对数据的改变必须是永久的,即使出现系统故障。

并发事务问题与隔离级别

问题:

  • 脏读:一个事务读取到另一个事务未提交的数据
  • 不可重复读:一个事务中两次读取的数据内容不一致。这是事务中 update 时引发的问题。
  • 幻读:一个事务中两次读取的数据的数量不一致,这是 insert 或 delete 时引发的问题。

四大隔离级别(“×”表示会出现这种问题;“ ”表示不会出现这种问题)

级别 名称 隔离级别 脏读 不可重复读 幻读 数据库默认隔离级别
1 读未提交 read uncommitted × × ×
2 读已提交 read committed × × Oracle 和 SQL Server
3 可重复读 repeatable read × MySQL
4 串行化 serializable

上面的级别最低,下面的级别最高。隔离级别越高,性能越差,安全性越高。

如何进行事务管理

Connection的三个方法与事务相关:

  • setAutoCommit(boolean):设置是否为自动提交事务,如果true(默认值就是true)表示自动提交,也就是每条执行的SQL语句都是一个单独的事务,如果设置false,那么就相当于开启了事务了;
  • commit():提交事务
  • rollback():回滚事务

还可以设置Savepoint,允许通过代码设置保存点并让事务回滚到指定的保存点

#{} 和 ${} 区别

  • #{} 表示占位符,实现preparedStatement向占位符中赋值的操作,可以防止SQL注入
  • ${} 表示拼接字符串,不能防止SQL注入

MyBatis 的一级、二级缓存

  • 一级缓存是 SqlSession 对象的缓存,当调用SqlSession的添加,删除,修改,commit(),close(),clearCache()等方法时,就会清空一级缓存。 默认开启。

  • 二级缓存是值SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享

    二级缓存存储的只是数据,当被查询时创建对象并返回(以至于Hash值不同)

存储过程

一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中,可以通过存储过程名称调用

procedure

索引

对数据库中一或多个列值的排序,帮助数据库高效获取数据的数据结构。有:普通索引、唯一索引、主键索引、全文索引

  • 优点:
    • 加快检索速度
    • 唯一索引确保每行数据的唯一性
    • 在使用索引的过程可以优化隐藏器,提高系统性能
  • 缺点:插入、删除、修改、维护速度下降,且用物理和数据空间

视图

视图就是封装了(复杂)查询的虚拟表,但是不包含数据,只包含查询SQL

封装,隐藏细节,保护数据;视图不能被索引。

-- 创建视图
CREATE VIEW myview
AS
SELECT ...
-- 修改视图
CREATE OR REPLACE VIEW myview
AS
SELECT ...
-- 也可以这样修改
ALTER VIEW myview 
AS
SELECT ...
-- 删除视图
DROP VIEW myview,myview1...

SQL 优化

  • 查询结果不要用*来查询所有字段,要明确指明结果字段

  • 对查询进行优化,避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引

  • 索引不是越多越好。提高select效率同时,降低了insert和update效率(可能会重建索引)。一个表索引数最好不要超过6个

    根据查询条件,建立索引,如果查询条件不止一个时,使用组合索引

    避免在 where 子句中对字段进行 null 值判断、使用!=或<>操作符、使用 or 来连接条件、in 和 not in 也要慎用,否则将导致引擎放弃使用索引而进行全表扫描

    在查询条件表达式的左侧尽量不要使用函数,否则索引失效

    如果有 like 话,最右%可以使用索引

  • 大数据量中分页限制

MySQL 数据库优化

  • EXPLAIN 你的 SELECT 查询
  • 当只要一行数据时使用 LIMIT 1
  • 使用 ENUM不是 VARCHAR
  • 固定长度的表会更

常用工具

慢查询日志-Mysqldumpslow

Explain 执行计划

  • 有众多指标
    • type
    • ref

Query Profiling 查询性能瓶颈

查询SQL执行时间

数据库连接进程表

show processlist;

引擎

InnoDB

  • 支持事务
  • 行级锁,只在where主键时有用
  • 外键约束
  • 容灾性(通过bin-log恢复)
  • 用于经常更新的表

MyIsam

  • 上述三条都不支持
  • 没有容灾性,不能恢复,需经常备份
  • 保存了行数,做count计算,如日志、调查等,不需要像InnoDB需查询全表
  • 支持组合索引,而InnoDB不支持
  • 读取操作很快,用于读取操作远多于写操作且不需要事务支持的表

主从复制Master/Slave

  • 数据同步备份
  • 读写分离:把写操作放入Master;读操作放入Slave,减轻单一数据库压力
  • 分布式部署,高可用

master库的更新事件,被写入bin-log,master的binlog线程把bin-log发送到slave,从库启动后先写入relaylog将更新内容写入DB