数据库三大范式
第一范式:每一列都是不可再分的属性,确保每一列的原子性
两列的属性相似后者一致,尽量合并属性一样的列,确保不产生冗余
第二范式:每一行的数据只能与其中一列相关,每一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来。要求每一个实例必须可以被唯一的区分。
第三范式:数据不能存在传递关系,即每个属性都跟主键有直接关系而不是++9间接关系
三大范式只是一般设计数据库的基本理念,可以建立冗余较小、结构合理的数据库。如果有特殊情况,当然要特殊对待,数据库设计最重要的是看需求跟性能,需求>性能>表结构。所以不能一味的去追求范式建立数据库。
参考自:https://www.cnblogs.com/knowledgesea/p/3667395.html
数据库事物特性
ACID:原子性(Atomicity)、一致性(Correspondence)、隔离性(Isolation)、持久性(Durability)
原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节
一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
隔离性:隔离状态执行事务,相当于同一时间内唯一执行操作
持久性:事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
事物并发问题
脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致
幻读:系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表
参考自:https://www.cnblogs.com/huanongying/p/7021555.html
MySQL事物隔离级别
读未提交:所有的并发问题都没有解决
读已提交:解决了脏读问题(是MySQL的默认级别)
可重复读:解决了不可重复读(是Oracle的默认级别)
串行化:读写数据都会锁住整张表,解决了所有事物问题,但是效率较低
Delete和Truncate
- delete每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作;truncate一次性从表中删除所有的数据,并不把单独的删除操作记录记入日志保存,删除行是不能恢复的
- delete效率较低,truncate效率高
- 有外键越苏的不能用truncate,只能用delete
连接的种类
外连接:
左外连接:left join 返回左边表中的所有行,右边表中符合条件的行
selcect * from a left join b on …
右外连接:right Join 将返回右表的所有行,右表的某行在左表中没有匹配行,则将为左表返回空值
selcect * from a right join b on …
完全外连接:完整外部联接返回左表和右表中的所有行(MySQL不支持)
内连接:
用比较运算符比较要联接列的值的联接
inner join / join
交叉连接:
返回两表的笛卡尔积结果
数据库优化思路
SQL语句优化
索引优化
数据库结构优化
服务器优化
缓存优化
https://www.cnblogs.com/frankielf0921/p/5930743.html
MySQL的MyISAM和InnoDB的区别
- InnoDB支持事物,而MyISAM不支持事物
- InnoDB支持行级锁,而MyISAM支持表级锁
- InnoDB支持MVCC, 而MyISAM不支持
- InnoDB支持外键,而MyISAM不支持
- InnoDB不支持全文索引,而MyISAM支持。
- InnoDB是聚集索引,MyISAM是非聚集索引
索引概念优缺点
索引是一个排序的列表,可以大大提高查询的速度
什么时候使用?
主键自动建立唯一索引;经常作为查询条件在WHERE或者ORDER BY 语句中出现的列要建立索引;作为排序的列要建立索引;查询中与其他表关联的字段,外键关系建立索引
什么时候不使用?
经常增删改的列不要建立索引;有大量重复的列不建立索引;表记录太少不要建立索引;
优点:可以快速检索,减少I/O次数,加快检索速度;根据索引分组和排序,可以加快分组和排序
**缺点:**索引也会占用存储空间,创建和维护也需要成本,而且在修改删除数据时要同时修改索引表
B-Tree和B+Tree索引
B-Tree
B-Tree是平衡搜索多叉树,设树的度尾d,高度为h,那么B-Tree要满足:
- 每个叶子节点高度一样,都是1
- 每个非叶子节点由n-1key和n个指针组成,其中d<=n<=2d,key和point相互间隔,结点两端是key
- 叶子节点指针都为null
- 非叶子节点的key都是[key,data]二元组,key表示作为索引的键,data为键值所在行的数据
B+Tree
B+Tree是BTree的一个变种,设d为树的度数,h为树的高度,B+Tree和BTree的不同主要在于
B+Tree的非叶子节点不存数据,只存储键值
B+Tree的叶子结点没有指针,所有键值都会出现在叶子结点上,且key存储的键值对应的数据的物理地址;
一般来说B+Tree比BTree更适合实现外存的索引结构,因为存储引擎的设计专家巧妙的利用了外存(磁盘)的存储结构,即磁盘的一个扇区是整数倍的page(页),页是存储中的一个单位,通常默认为4K,因此索引结构的节点被设计为一个页的大小,然后利用外存的“**预读取”原则,每次读取的时候,把整个节点的数据读取到内存中,然后在内存中查找,已知内存的读取速度是外存读取I/O速度的几百倍,那么提升查找速度的关键就在于尽可能少的磁盘I/O,**那么可以知道,每个节点中的key个数越多,那么树的高度越小,需要I/O的次数越少,因此一般来说B+Tree比BTree更快,因为B+Tree的非叶节点中不存储data,就可以存储更多的key。
带顺序索引的B+Tree
很多存储引擎在B+Tree的基础上进行了优化,添加了指向相邻叶节点的指针,形成了带有顺序访问指针的B+Tree,这样做是为了提高区间查找的效率,只要找到第一个值那么就可以顺序的查找后面的值。
聚集索引和非聚集索引
MySQL中最常见的两种存储引擎分别是MyISAM和InnoDB,分别实现了非聚簇索引和聚簇索引。
索引的分类中,我们可以按照索引的键是否为主键来分为“主索引”和“辅助索引”,使用主键键值建立的索引称为“主索引”,其它的称为“辅助索引”。因此主索引只能有一个,辅助索引可以有很多个。
MyISAM-非聚集索引
MyISAM存储引擎采用的是非聚簇索引,非聚簇索引的主索引和辅助索引几乎是一样的,只是主索引不允许重复,不允许空值,他们的叶子结点的key都存储指向键值对应的数据的物理地址。
非聚簇索引的数据表和索引表是分开存储的。
非聚簇索引中的数据是根据数据的插入顺序保存。因此非聚簇索引更适合单个数据的查询。插入顺序不受键值影响。
InnoDB-聚集索引
聚簇索引的主索引的叶子结点存储的是键值对应的数据本身,辅助索引的叶子结点存储的是键值对应的数据的主键键值。因此主键的值长度越小越好,类型越简单越好。
聚簇索引的数据和主键索引存储在一起。
聚簇索引的数据是根据主键的顺序保存。因此适合按主键索引的区间查找,可以有更少的磁盘I/O,加快查询速度。但是也是因为这个原因,聚簇索引的插入顺序最好按照主键单调的顺序插入,否则会频繁的引起页分裂,严重影响性能。
MySQL索引的类型
普通索引,唯一索引,主键索引,组合索引,全文索引
普通索引:是最基本的索引,它没有任何限制
create index index_name on table(column(lenght))
唯一索引:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
create unique index indexName table(column(lenght))
主键索引:一个表只能有一个主键,不允许有空值
primary key
组合索引:指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用组合索引时遵循最左前缀集合
ALTER TABLE table ADD INDEX name_city_age (name,city,age)
全文索引:主要用来查找文本中的关键字,而不是直接与索引中的值相比较
复习中,会慢慢补充的~