1.引擎
首先在Dos命令窗口中可以查看mysql支持的存储引擎:
这里只简单介绍常用的三种:
- MyISAM:不支持事务。每个表会拆分成三个文件,.frm(表结构文件),MYD(数据文件),MYI(索引文件)。可以把表压缩成只读表,节省空间。
- Memory:不支持事务,将数据存储在内存中,容易丢失数据;每行的长度固定,检索速度快。
- InnoDB:MySQL数据库默认的引擎。支持事务,支持级联操作,支持行级锁,服务器崩溃后会自动恢复。
2.事务
首先,先看一个生活化的例子,银行转账,必须是一个账户扣钱成功,和一个账户收钱成功,才叫完成了一个转账操作,使用sql语句操作的化需要两条DML语句(update)。事务就是一组sql语句,要么全部成功,要么全部失败。
MySQL是默认开启自动提交的,即每条sql语句执行都会提交并且将数据库中的数据进行持久化操作。
- 所以要先关闭自动提交:
#手动开启一个事务就会默认关闭自动提交
start transaction;
- 然后书写一组sql语句。
- 如果成功了的话,就执行提交操作:
commit();
- 如果有其中任何一条sql语句失败了,就执行回滚操作:
rollback();
事务的四大特性(ACID):
- A(原子性):事务中的sql语句要么全成功,要么全失败。
- C(一致性):事务开始前后,数据库保持一致状态。
- I(隔离性):多个事务之间是隔离的,互不干扰。
- D(持久性):事务一旦提交,会持久化到数据库中。
事务的隔离级别:
首先,有A,B两个事务
- 读未提交:A只是执行了sql语句,还没有执行commit操作,B就已经可以读取到A刚刚操作的数据了;会发生脏读问题。
- 读已提交:B只能读取到A执行并提交了的数据,并且B一直不commit,也可以一直读取到A执行并提交的数据;会发生不可重复读问题。
- 可重复读:B可以读取到A执行并且commit的数据,但是当A重新开启一个事务再执行sql语句时,B就不能读取到此时的数据了,除非B执行commit之后,再开启一个新的事务;会发生幻读的问题。MySQL默认隔离级别。
- 序列化(串行化):A,B排队操作,只有A操作完了,B才可以操作。
3.索引
索引就是用来加快数据的查询效率的。就好比一本书的目录。
如果没有索引的话,会全表进行扫描。就相当于一本书没有目录就得从第一页开始查找一样,效率很低。
MyISAM和InnoDB的索引数据结构都是B+tree。
主键会自动添加索引。所以尽量适用主键字段来进行查询,效率会比较高。
- 所以索引适用于:
数据量大的字段;
经常被检索的字段(经常出现在where子句中的字段);
- 不适用于:
经常出现在DML语句中的字段(就相当于整本书发生了变化,就必须要重新生成一个目录了)
索引的实现原理:
具有索引的字段,会自动该字段下的所有数据按照一定的顺序备份到硬盘或者是内存中,并且会进行分区,然后存储数据库数据中的物理地址。在执行sql语句select时,首先会查看被查询的字段是否有索引,如果没有的话,就会进行全表查询;如果有索引的话,就会按照字段的名字去备份中指定的区中查找,此时的sql语句的条件也转变成了where 物理地址 = 'xxx'。
4.视图
视图就是数据库中表的一部分。可以通过操作视图来操作原表。
像公安局,需要你帮他实现一个业务,但是表里面的数据很多又是保密的,所以此时就会将需要你操作的表的一部分生成一个视图让你去操作。
#创建视图
create view view_name as (select...);
#修改视图
alter view view_name as (select...);
#删除视图
drop view if exists view_name;
三大范式
三大范式是用来设计数据库的。
第一范式
每张表中都需要又一个主键。
第二范式
在第一范式的基础上,不能产生部分依赖。每个非主键字段必须完全依赖主键字段。
部分依赖的例子:
学生编号(pk) | 学生姓名 | 老师编号(pk) | 老师姓名 |
1001 | Tom | 001 | Rose |
1002 | Jerry | 002 | Jack |
此时学生姓名部分依赖了学生编号,却没有依赖另外一个主键老师编号,老师姓名也部分依赖了老师编号,没有依赖另外一个主键学生编号。
修改表的设计:
学生表:
学生编号(pk) | 学生姓名 |
1001 | Tom |
1002 | Jerry |
教师表:
老师编号(pk) | 老师姓名 |
001 | Rose |
002 | Jack |
关系表
学生编号(pk) fk:学生表的学生编号 | 老师编号(pk) fk:教师表的教师编号 |
1001 | 001 |
1002 | 002 |
第三范式
在第二范式的基础上,不能产生传递依赖。非主键字段不能传递依赖于主键。
什么是传递依赖呢?
学生编号(pk) | 学生姓名 | 班级编号 | 班级名称 |
1001 | zhansan | 101 | 一年级一班 |
1002 | lisi | 102 | 一年级二班 |
此时班级名称依赖于班级编号,而班级编号依赖于学生编号。
修改:
学生表:
学生编号(pk) | 学生姓名 | 班级编号 |
1001 | zhansan | 101 |
1002 | lisi | 102 |
班级表:
班级编号 | 班级名称 |
101 | 一年级一班 |
102 | 一年级二班 |
数据库的设计应该尽量的去遵循三大范式;
但是还是得取决于实际的需求,有时候会存在拿冗余度去换速度的情况。