存储引擎
ENGINE = InnoDS
什么是存储引擎?
存储引擎就是将数据以不同技术存储在文件(内存)中
每一种存储引擎都使用不同的机制,大有不同
锁:
- 读锁:共享锁
- 写锁:任何时候只能有一个用户写入资源,阻塞其他的读锁和写锁操作
锁的颗粒:
- 表锁:
- 行锁:
存储引擎的种类(9种)
三个范式是什么
-
首先要明确的是:满足着第三范式,那么就一定满足第二范式、满足着第二范式就一定满足第一范式
-
第一范式:字段是最小的的单元不可再分
- 学生信息组成学生信息表,有年龄、性别、学号等信息组成。这些字段都不可再分,所以它是满足第一范式的(字段值还可以继续拆分的,就不满足1NF)
address 中国陕西西安(不满足1NF,中国陕西西安应该拆分开来)
范式设计的越详细,对于某些操作可能会更好,但不一定!,以实际开发为主
-
第二范式:满足第一范式,除主键外的每一列都比必须完全依赖于主键。
- 其他字段组成的这行记录和主键表示的是同一个东西,而主键是唯一的,它们只需要依赖于主键,也就成了唯一的(依赖唯一,然后成为唯一)
- 学号为1024的同学,姓名为Java3y,年龄是22岁。姓名和年龄字段都依赖着学号主键。
如果主键是两个字段组成的,也就是说有的字段可能只依赖于一部分的主键,那么就得拆分才能满足2NF!!!
-
第三范式:满足第二范式,非主键外的所有字段必须互不依赖
- 就是数据只在一个地方存储,不重复出现在多张表中,可以认为就是消除传递依赖
- 比如,我们大学分了很多系(中文系、英语系、计算机系……),这个系别管理表信息有以下字段组成:系编号,系主任,系简介,系架构。那我们能不能在学生信息表添加系编号,系主任,系简介,系架构字段呢?不行的,因为这样就冗余了,非主键外的字段形成了依赖关系(依赖到学生信息表了)!正确的做法是:学生表就只能增加一个系编号字段。
BC 范式
什么是事务?
事务简单来说:一个最小的不可分割的工作单元,事务保证一个业务的完整性
多条sql语句,要么会同时成功,要么同时失败!!
事务提供了一个返回的机会
insert ;commit ; //手动提交rollback;set autocommit=0begin start transaction //开启手动提交
ACID — 数据库事务正确执行的四个基本要素
-
包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(就是提交之后不能再回滚)。
- 原子性:事务是最小的单位,不可以再分割
- 一致性:同意事务中的sql语句,要么同时成功,要么同时失败!!
- 隔离性:事务1和事务2无关
- 持久性:事务一旦结束(
commit),就不能rollback
一个支持事务(Transaction)中的数据库系统,必需要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易。
事务隔离级别
数据库定义了4个隔离级别:
- Serializable【可避免脏读,不可重复读,虚读】 串行化
- Repeatable read【可避免脏读,不可重复读】 可以重复读
- Read committed【可避免脏读】 读取已经提交的
- Read uncommitted【级别最低,什么都避免不了】 读未提交的
如何查看隔离级别?
如何修改隔离级别?
set global transaction idolation level read uncommitted
1. 脏读:一个事务读取到另外一个事务未提交的数据(read uncommitted)
例子:A向B转账,A执行了转账语句,但A还没有提交事务,B读取数据,发现自己账户钱变多了!B跟A说,我已经收到钱了。A回滚事务【rollback】,等B再查看账户的钱时,发现钱并没有多。
实际开发中绝对不允许脏读
2. 不可重复读:一个事务读取到另外一个事务已经提交的数据,也就是说一个事务可以看到其他事务所做的修改(read commmited)
注:A查询数据库得到数据,B去修改数据库的数据,导致A多次查询数据库的结果都不一样【危害:A每次查询的结果都是受B的影响的,那么A查询出来的信息就没有意思了】
3. 虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(Repeatable read)
事务a和事务b同时操作一张表,事务a提交的数据 事务B select 查不出来,但是当insert 相同数据时就会报错!!!
4. 串行化:(Serializable)
不允许同时写入,直到另一端的事务 commit 完成
会存在等待超时
串行化三个字比较形象!!!!
性能:隔离级别越高,性能越差
mysql 默认:Repeatable read
SQL 约束有哪几种?
- NOT NULL: 用于控制字段的内容一定不能为空(NULL)。
- UNIQUE: 控制字段内容不能重复,一个表允许有多个 Unique 约束。
- PRIMARY KEY: 也是用于控件字段内容不能重复不能为空,唯一确定一条记录。(联合与单个, auto_increment )
- FOREIGN KEY: 用于预防破坏表之间连接的动作,也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
- CHECK: 用于控制字段的值范围。
主键约束,自赠约束,唯一约束,非空约束,默认约束(DEFAULT),外键约束,check约束
主键的修改和删除
alter table user add primary key(id);
alter table user drop primary key;
alter table user modfiy id int primary key;
SQL的四种连接查询
1. 内联连接
inner join或者join
内联查询,其实就是两张表中的数据,通过某个字段相对,查询出相关记录数据.
select * from person inner join card on person.cardId = card.id;
2. 外连接
- 左连接:
left join/left outer join
select * from person left join card on person.cardId = card.id;
-
右连接:
right join/right outer join -
完全外连接:
full join/full outer join(mysql 不支持)
什么是索引?
索引是一种数据结构
索引的目地在于提高查询效率,类比字典
如果要查"mysql",通过索引就可以直接定位在"m"字母的范围,然后依次往下找就行了
如果没有索引.肯定就是要遍历了a-z
索引:快速查找+排序
缺点:
- 索引占空间
- 更新索引
索引的分类:
- 单值索引:一个索引只包含单个列,一个表可以有多个单列索引.
- 唯一索引:索引列的值必须唯一,允许有空值(主键自动创建唯一索引)
- 复合索引:一个索引包含多个列
单值索引
//创建索引
create [unique] index indexName on tableName(columnname(collength));
// create [unique] index indexName on tableName(col);
//如果是CHAR,VARCHAR类型,length可以小于字段实际长度;
//如果是BLOB和TEXT类型,必须指定 length。
//添加索引
alter table tableName add [UNIQUE] index indexName(indexName);
//–创建表的时候同时创建索引
CREATE TABLE tb2 (
id int(11) NOT NULL AUTO_INCREMENT ,
title char(255) ,
content varchar(20),
time int DEFAULT NULL ,
[UNIQUE] INDEX index_name (title(length))//重点在这里
)
//删除索引
DROP INDEX index_name ON table
show index from tablename ; \G(格式化)
唯一索引:(见上面)
复合索引(一般都是用这个):
create [unique] index indexName on tableName(col1,col2);
将索引节点加载到内存,经过二分查找,找到下一阶段的物理位置,然后在经过一次IO,找到下一节点,最终找到叶子节点的数据.
创建索引的考虑:
SQL优化分析:
explain select * from tablename
explain + SQL语句
参考:
https://www.bilibili.com/video/av39807944/?p=12