<>1. 字段约束

约束:not null、unique、主键、外键

主键:每张表必须有一个主键,非空唯一。
外键:解决了什么问题?表冗余的问题。(数据库三大范式)

引入外键时,会有一个父表和子表的概念
有外键字段的表为子表(或者可以叫主表和从表)

添加外键
alter table 从表 add constraint 外键名 foreign key(外键字段) references 主表(主键字段);
删除外键
alter table 表名 drop foreign key 外键名;
阿里巴巴Java开发手册规定:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。
说明:(概念解释)学生表中的 student_id 是主键,那么成绩表中的 student_id 则为外键。如果更新学生表中的
student_id,同时触发成绩表中的 student_id
更新,则为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

<>2. 索引

索引类别:单一索引、复合索引、主键索引
索引优势:提高检索效率,降低数据排序成本,降低CPU消耗。
索引劣势:索引也是一张表,会占用空间。索引降低了更新表的速率,因为每次更新表都要更新一下索引文件。
平常所说的索引,一般都是指B+树索引。
B树和B+树区别:B树非叶子结点和叶子结点都保存key(索引);B+树只有叶子结点保存key,非叶子结点都是索引部分;B+树的查询效率更加稳定

MySQL对B+树进行了优化,在其基础上增加了一个指向相邻叶子节点的链表指针,提高区间访问的性能。叶子结点从左到右是有序的。
创建索引语法 create index 索引名 on 表名(字段名); 查看索引 show index from 表名; 删除索引 drop index
索引名on 表名;
聚簇索引:数据和索引放到了一块,找到索引就找到了数据。
非聚簇索引:叶子结点不存储数据,存储的是数据行地址。根据索引查找到的数据行地址去磁盘查找数据。

<>3. 索引失效

什么时候索引会失效?

*
不满足“最左前缀法则”:在使用复合索引的时候,查询要从索引的最左前列开始,并且不跳过索引中的列。如果符合最左法则,但是出现跳跃某一列,只有最左列索引生效。
* 如果出现了范围查询,范围查询右边的列索引失效。
* 在索引列上进行运算操作,索引失效。
* 字符串不加单引号,索引失效。
* 尽量使用覆盖查询,避免使用select * 查询(会造成回调查询)
* 用or分割开的条件, 如果or前的列有索引,而后面的列中没有索引,那么索引失效。
* 以%开头的Like模糊查询,索引失效。(科技% 不会失效;%科技 会失效)解决方案:通过覆盖(select)索引来解决。(主键自带索引)
* 在创建索引时,如果MySQL评估使用索引比全表更慢,则索引不创建。再查询时不走索引。
* is NULL , is NOT NULL 有时索引失效(MySQL自动判断,使用索引更慢时全表扫描)
* in走索引,not in索引失效。
尽量使用复合索引,而不是单列索引!

创建复合索引
create index idx_name_sta_address on tb_seller(name, status, address);
就相当于创建了三个索引 :

* name
* name + status
* name + status + address
创建单列索引
create index idx_seller_name on tb_seller(name); create index idx_seller_status
on tb_seller(status); create index idx_seller_address on tb_seller(address);
数据库会选择一个最优的索引(辨识度最高索引)来使用,并不会使用全部索引 。

<>4. 事务

事务:一个完整的业务逻辑,最小的工作单元
只有DML语句才涉及到事务,所以事务也可以理解为多条DML语句同时成功或失败

事务的四个特性(ACID)

* 原子性
一个事务中所有操作要么同时成功要么同时失败
* 一致性
事务从开始到结束,数据库的完整性没有被破坏
* 隔离性
读未提交、读已提交、可重复读、序列化
* 持久性
事务结束后数据保存在硬盘上,系统故障数据不丢失
MySQL默认的事务隔离级别是可重复读,Oracle默认为读已提交。

这里重点讲一下事务的四种隔离级别

<>4.1 读未提交

写事务A还未提交的事务的数据,就被读事务B读取到了,这就叫脏读,指读取到的数据是脏数据,即无效数据。

<>4.2 读已提交(RC)

写事务A提交事务后,读事务B才能读取到写事务A提交的事务数据,这解决了脏读的问题,但是也导致了不可重复读的问题。也就是说读事务B在同一事务内第二次读到的数据,和第一次读到的数据可能不同。

<>4.3 可重复读(RR)

在开启读事务B时,相当于给当前读取到的数据加了写锁,在读事务B提交之前都不会释放写锁,这样之后读取到的这些数据的值都不会变化,解决了不可重复读的问题,但是导致了幻读的问题,也就是说在读事务B拍快照之后,写事务A增加或删除了几条数据,读事务B再次查询时真实的数据库已经发生了变化,但是读事务B却查询不出这种变化。

不可重复读重点在数据值的变化,也就是修改,幻读重点在数据行数的变化,也就是增删。

<>4.4 序列化

数据库事务的最高隔离级别。在此级别下,事务串行执行,一个事务提交后,另一个事务才可以开启。可以避免脏读、不可重复读、幻读等读现象。但是效率低下,耗费数据库性能,不推荐使用。

<>5. 数据库三大范式

* 每张表必须有主键,每一个字段原子性不能再分
* 非主键字段完全依赖主键,不能产生部分依赖
* 非主键字段直接依赖主键,不能产生传递依赖
三大范式强调的是什么问题?表冗余的问题。解决办法:拆表。
拆表一定是好的吗?拆表就一定会导致表之间的联查,可能会造成笛卡尔积的问题,影响效率。
所以有时候我们需要舍弃空间换时间。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信