前言
对数据库的常见知识点总结下,方便日后学习和复习。
参考文章:
1. 事务(ACID)
事务:
事务就是被绑定在一起作为一个逻辑工作单元的SQL语句分组。
事务是并发控制的基本单元,事务是一个操作序列,要么都执行,要么都不执行,
是一个不可分割的工作单位,事务是维护数据库一致性的单位。
- 原子性(Atomicity)
事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。 - 一致性(Consistency)
事务开始前和结束后,数据库的完整性约束没有被破坏。 - 隔离性(Isolation)
事务之间要相互隔离,互不影响 - 持久性(Durability)
一旦事务提交,对数据的改变就是永久的
事务的语句:
1.开始事务:BEGIN TRANSACTION
2.提交事务:COMMIT TRANSACTION
3.回滚事务:ROLLBACK TRANSACTION
2. 事务的并发及其隔离级别
从理论上来说, 事务应该彼此完全隔离, 以避免并发事务所导致的问题,然而, 那样会对性能产生极大的影响, 因为事务必须按顺序运行, 在实际开发中, 为了提升性能, 事务会以较低的隔离级别运行, 事务的隔离级别可以通过隔离事务属性指定。
事务的并发问题:
- 脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
- 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果因此本事务先后两次读到的数据结果会不一致。
- 幻读:幻读解决了不重复读,保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。
不可重复读侧重于修改,幻读侧重于新增或删除
事务的隔离级别:
-
读未提交 read-uncommitted
另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据脏读 -
读已提交 read-committed
事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果因此本事务先后两次读到的数据结果会不一致。 -
可重复读 repeatable-read
在同一个事务里,SELECT的结果是事务开始时时间点的状态,因此,同样的SELECT操作读到的结果会是一致的。但是,会有幻读现象 -
串行化 serializable
最高的隔离级别,在这个隔离级别下,不会产生任何异常。并发的事务,就像事务是在一个个按照顺序执行一样
MySQL默认的事务隔离级别为repeatable-read
3. 数据库的锁机制
数据库的大并发要考虑锁和锁的性能问题,加锁是为了实现并发控制。
锁机制保证在一个事务释放锁之前其他事务不可以进行修改。
锁:行级锁,表级锁,悲观锁,乐观锁
- 悲观锁:事务每次操作之前假设有其他事务会修改需访问的数据,会要求上锁。
- 乐观锁:事务每次操作之前假设没有其他事务会修改需访问的数据,不会要求上锁。
- 共享锁:对某一资源加共享锁,自身可以读该资源,其他人也可以读该资源
- 共享锁(S锁):如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
- 排他锁(X锁):如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务
既能读数据,又能修改数据。
共享锁下其它用户可以并发读取,查询数据。但不能修改,增加,删除数据。资源共享。
MySQL有三种锁的级别:页级、表级、行级。
- 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
4. 数据库连接池的作用
- 维护一定数量的连接,减少创建连接的时间
- 更快的响应时间
- 统一的管理
5. 数据库三范式
- 1NF:属性不可分或者 列不可再分或者 确保每列保持原子性
- 2NF: 非主键属性,完全依赖于主键属性或 行可以唯一区分,主键约束 或者 确保表中的每列都和主键相关
- 3NF: 非主键属性无传递依赖或表的非主属性不能依赖与其他表的非主属性 外键约束 或者 确保每列都和主键列直接相关,而不是间接相关
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关