存储引擎
储存引擎就是表中数据的存储方式,不同的存储引擎有不同的存储方式。
常见的储存引擎有:
- MyISAM 存储引擎- InnoDB 存储引擎 (Msql 默认的存储引擎)- MEMORY 存储引擎
MyISAM 存储引擎
MyISAM 存储引擎有一下几个特点:
- 使用三个文件来表示每个表:- 格式文件 - 储存表结构的定义(.frm 后缀)- 数据文件 - 储存表中的数据 (.MYD 后缀)- 索引文件 - 储存表上索引 (.MYI 后缀)- 灵活的 AUTO_INCREMENT 字段处理- 可被转化为压缩、只读表来节省空间
MyISAM 缺点是不支持事务。
InnoDB 存储引擎
InnoDB 是 Mysql 默认的存储引擎,它具有一下特点:
- InnoDB 表在在数据库目录以 .frm 后缀结尾。- InnoDB 表空间 tablespace 被用于存储表的内容。- 支持事务、行级锁。- 数据库崩溃时提供自动恢复机制。
缺点时 tablespace 这样的表空间,无法被压缩,只能转换为只读。
MEMORY 存储引擎
MEMORY 存储引擎的优点时数据存储在内存中,查询速度快,缺点是不支持事务、数据容易丢失。
事务
比如:银行转账,需要执行两条 update 语句,减少金额和增加金额,这两条 update 语句必须同时成功或者同时失败,如果一个成功另一个失败就会出现问题,如果想要保证这件事就需要使用到数据库的 事务机制。
和事务相关的语句只有 DML 语句 (insert、update、delete),因为这三个语句都是和数据库表中当前数据有关的,事务的存在是为了保证数据的完整性、安全性。
事务的过程
假设有一个任务执行过程是:create -> update -> delete。
首先开启事务机制----------------insert 操作 ---update 操作 | > 这些操作不会影响到数据库表中的数据.delete 操作 ---提交事务 / 回滚事务-------------事务结束
在事务进行的过程中所有的操作都不会影响到数据库表中的数据,而是把这些执行记录到数据库到操作历史中,当提交事务的时候才会将执行真正的操作修改表中的数据。
事务的特性
事务包含四大特性:ACID;
A(原子性):一个事务是一个完整的业务逻辑单元,不可再分。
C(一致性):事务必须保证多条 DML 语句,同时成功或同时失败。
I(隔离性):事务A和事务B之间存在隔离性。
D(持久性):最终数据必须持久化到硬盘文件中,事务才算成功结束。
事务之间的隔离性分为四个级别:
第一级别:读未提交(read uncommitted)
事务A还没有提交,事务B中也能够访问到事务A中做出的 DML 语句操作,读未提交存在脏读(Dirty Read)现象:读到了脏数据。
第二级别:读已提交(read committed)
事务A还没有提交时,访问不到事务A中做的 DML 操作,只有提交后才能够访问到,解决了脏读问题,但是存在问题是不可重复读,在事务 B 还没有结束前,读到的数据应该都是事务刚开始时候的数据,但是事务A提交了新的更改时,事务B中读到的时新数据,这就是不可重复读(不能重复读到以前的数据)。
第三级别:可重复读(repeatable read)
解决了不可重复读的问题,但其实读到的数据是幻象,真的的数据已经被修改了,此时读到只不过是一层备份而已。
第四级别:序列话读/串行读 (serializable)
解决了上面所有的问题,但是事务需要排队处理。
Mysql 中默认的隔离级别为:可重复读。
-- 修改事务隔离级别$ set global transaction isolation level read uncommitted; -- 读未提交$ set global transaction isolation level read committed; -- 读已提交$ set global transaction isolation level repeatable read; -- 可重复读$ set global transaction isolation level serializable; -- 串行读-- 查看当前的隔离级别$ select @@global.tx_isolation;
使用事务
在 Mysql 中事务是默认提交的,执行任意一条 DML 语句则提交一次,使用 start transaction 可以关闭自动提交,开启一个新事务。
$ start transaction;-- 执行 DML 语句-- 执行 DML 语句commit(提交事务) / rollback(回退事务)
- commit 提交事务就是把事务中提交的操作同步到数据库中。
- rollback 回退事务就是撤销这次事务中的操作,不会同步到数据库中。
索引
索引就相当于一本书的目录,通过目录可以快速找到对应的资源,在数据库中查询一张表有两种方式检索方式:
第一种方式:全表搜索
第二种方式:根据索引检索(效率很高)
索引能够提高检索效率是因为它缩小了扫描的范围。
索引虽然能够提高检索效率,但是也能够随意的添加,因为索引也是数据库中的对象,也需要数据库不断的维护,是存在维护成本的,比如:表中的数据经常被修改就不适合添加索引,因为数据一旦修改,索引就需要重新排序。
在什么时候添加索引呢?
— 删除索引语句: $ drop index 索引名称 on 表名;
例如: — sal 字段添加索引 $ create index sal_index on emp(sal);
— sal deptno 复合索引 $ create index sal_deptno_index on emp(sal, deptno);
— 删除索引 $ drop index sal_index on emp;
<a name="NsEfW"></a>### 索引失效在下面的语句中索引是失效的,因为模糊查询无法匹配索引。```sql$ select * from emp where ename like '%A%';
视图
视图就是站在不同的角度去看数据,同一张表通过不同的角度去看待。
-- 创建视图$ create view 视图名称 as select(查询语句);-- 删除视图$ drop view 视图名;例如:$ create view emp_view as select * from emp;$ drop view emp_view;
视图依然可以使用 select、delete、update、insert 语句,并且会影响到原表数据。
视图的作用:
视图可以隐藏表的实现细节,保密级别高的系统,数据库之对外提供相关的视图,只对视图进行 CRUD 操作。
数据库设计三范式
设计范式就是设计表的依据,按照三范式设计的表不会出现数据冗余。
第一范式:
任何表都应该有主键,且每个字段原子性不可再分。
第二范式:
建立在第一范式基础之上,所有非主键字段完全依赖主键,不能产生部分依赖,也就是多对多的情况,这时候需要使用三张表,关系表两个外键。
第三范式:
建立在第二范式基础之上,非主键字段不能传递依赖于主键字段(不直接依赖主键,而是字段依赖字段再依赖主键,这就是传递依赖),也就是一对多,这时候使用两张表,一对多,多的表加外键。
