事务
逻辑工作单元,包含一系列操作,满足ACID
ACID
原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
- A 一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成
- C 并发(AI), 非并发(A), 在事务开始之前和事务结束以后,数据库的完整性没有被破坏
- I 锁 防止多个事务并发执行时由于交叉执行而导致数据的不一致
- D 断电, log回滚
并发一致性问题
- 丢失修改,修改叠加
- 读脏数据,改后回滚时被读
- 不可重复读,改的前后读
- 幻影读,增的前后读
锁
共享锁(读)、排它锁(写)
InnoDB引擎的锁机制:InnoDB支持事务,支持行锁和表锁用的比较多,Myisam不支持事务,只支持表锁。
- 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
- 排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁。
- 意向共享锁(IS):事务打算给数据行加行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁。
- 意向排他锁(IX):事务打算给数据行加行排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁。
乐观锁、悲观锁
- 悲观锁:先锁再操作,选用于竞争激烈的情况,如果只是读则不利。
begin;
select … for update
commit; - 乐观锁:先假定不冲突,直接操作,commit时再根据版本来判定是否冲突,返回给用户处理。
两段加锁协议
- 扩展阶段
在对任何数据项的读、写之前,要申请并获得该数据项的封锁。 - 收缩阶段
每个事务中,所有的封锁请求必须先于解锁请求,不能交替。
三级封锁协议
读写完没有被修改的风险,若有则先commit后unlock,否则反之。
两段锁协议(加锁归前解锁归后)->可串行化调度(并发效果与串行相同)
InnoDB采用两段锁协议
隔离级别
- 未提交读:在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
- 提交读:它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
- 可重复读MVCC:这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
- 可串行化:这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
MVCC 第次事务新建一条快照,create_time delete_time select是从快照中选择事务介于create_time和delete_time中间
关系
学号 姓名 学院 院长 课程分数
范式
- 1NF 属性不可分
- 2NF 每个非主属性完全函数依赖于键码(学号,姓名),键码拆开
table1 学号->姓名,学院,(学院->)院长
table2 学号,课程->分数 - 3NF 不传递函数依赖于键码
(学院->)院长 单独成表
ER
ER: 实体、属性、联系
- 多对多 课程——学号
- 一对多 院长——>学号
- 一对一 姓名<——>学号
索引
结构
- B+
空间: 高度小(vs AVL),结点密度大(vs B),减少IO
时间: 叶子结点顺序,遍历 - 哈希索引
基于哈希表实现,优点是查找非常快。
在 MySQL 中只有 Memory 引擎显式支持哈希索引。
哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行。 - 空间索引
MyISAM 存储引擎支持空间索引,可以用于地理数据存储。
空间索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。 - 全文索引
MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较索引中的值。
分类
InnoDB 的 B+Tree 索引分为主索引(聚簇索引)和辅助索引
主索引 key=>主键, value=>data
辅助索引 key=>索引列(city…) value=>主键,查找到主键后再主索引
优点
- 减少了服务器需要扫描的数据行数
- 减少排序order和分组group时间
需要
- 主键自动建立唯一索引
- where order group
- 与其他表关联的字段
不需要
- 表记录太少或重复,如性别
- 常增删改的,需要重建索引
优化
索引优化
- 索引是独立的列,不能是函数的参数,WHERE actor_id + 1 = 5;
- 多列索引 where中的参数都设为索引
- 索引列的顺序,选择性最强的索引列放在前面。
索引的选择性, 索引数/总数,比如唯一索引ID总数等于表项 - 前辍索引,文本
- 覆盖索引 select只查where中的属性,减少数据访问,MyISAM缓存中可以读索引,InnoDB无需主索引
查询优化
- limit
- 忌SELECT *
- 缓存
- 化大为小减少锁竞争
其他
InnoDB和MyISAM
- 事务:MyISAM不支持事务和外键,InnoDB 是事务型的,可以使用 Commit 和 Rollback 语句。
- 锁:MyISAM 只支持表级锁,而InnoDB还支持行级锁(where主键)。
- 行数保存: MyISAM
- 索引:MyISAM索引和数据分开,可压缩,支持全文索引; InnoDB有缓存池
- 备份:InnoDB必须导出SQL来备份,MyISAM的数据是以文件的形式存储,跨平台方便
数据类型
- DECIMAL(18, 9) 18总长9小数
- VARCHAR 变长
- DATETIME 时间string 8字节
- TIMESTAMP 时间int 4字节
- MyISAM 建议使用CHAR减少碎片
- InnoDB 建议使用VARCHAR减少空间
概念
- 主键: 唯一标识一条记录的属性(组)
- 外键: A表中的stuid是B表的主键,stuid是表A的外键,用于联系B表
- 超键: 主键的基础上加些冗余属性
- 候选键: 多个候选的属性(组)都能成为主键,主键是人为选定
- 约束: 对某个字段的规则,保证数据的完整性。比如唯一约束要求每个字段都不同,像主键约束,但可以有一个NULL。
- 索引: 唯一索引同维一约束,mysql中唯一约束会建立唯一索引
- 视图: 集多表部分内容于一起的虚拟表
- 存储过程: 一个预编译的代码块,执行效率比较高
- 事务: 是并发控制的基本单位, 一个操作序列
- delete 数据 有where 回滚 (删除某行)
- truncate 数据 没where 没回滚(删表留结构)
- drop 数据和结构 没回滚(全删)
NoSQL
- 存储方式: SQL数据存在特定结构的表中;
NoSQL则更加灵活和可扩展,存储方式可以省是JSON文档、哈希表或者其他方式。 - 表/数据集合的数据的关系:
在SQL中,必须定义好表和字段结构后才能添加数据,例如定义表的主键(primary key),索引(index),触发器(trigger),存储过程(stored procedure)等。表结构可以在被定义之后更新,但是如果有比较大的结构变更的话就会变得比较复杂。
在NoSQL中,数据可以在任何时候任何地方添加,不需要先定义表。 NoSQL可能更加适合初始化数据还不明确或者未定的项目中。
SQL提供了Join查询,可以将多个关系数据表中的数据用一条查询语句查询出来。NoSQL没有提供。
SQL删数据为了数据完整性,比如外键,不能随便删,而NoSQL是可以随意删除的。
在处理非结构化/半结构化的大数据时;在水平方向上进行扩展时;随时应对动态增加的数据项时可以优先考虑使用NoSQL数据库。 - NoSQL缺点:
事务支持较弱,join等复杂操作能力较弱,通用性较差