数据库
JDBC访问数据库的基本步骤
- 加载驱动(可省略,static,
com.mysql.cj.jdbc.Driver
) - (通过DriverManager)获取Connection连接
- (通过连接)获取PrepareStatement对象(可传入模板)
- (通过PrepareStatement)执行SQL语句
- 处理结果集
- 释放资源
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