数据库

事务

逻辑工作单元,包含一系列操作,满足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等复杂操作能力较弱,通用性较差