目录
一、数据库的约束
1.1、NOT NULL
1.2、UNIQUE
1.3、default
1.4、primary key
1.5、foreign key
1.6、check
二、对于数据库表中的构建
2.1、一对一关系
2.2、一对多关系
2.3、多对多关系
三、索引和事务
3.1、索引
3.2、事务
3.3、隔离性以及并发编程中产生的问题
3.3.1、脏读
3.3.2、不可重复读
3.3.3、幻读
3.3.4、MySQL中的隔离级别
一、数据库的约束
什么是约束?
数据库中的约束是为了让数据库中插入的数据规范化,对插入的数据进行限制,可以更好的保证数据的有效性和完整性。
约束的类型:
NOT NULL:指示某列不能存储 NULL 值。
UNIQUE:保证某列的每行必须有唯一的值。
DEFAULT:规定没有给列赋值时的默认值。
PRIMARY KEY :NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
FOREIGN KEY:保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK:保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句
1.1、NOT NULL
not null就如它的意思一样,加入not null 插入的数据就不能为空,不加not null时默认为空。
示例:
1.2、UNIQUE
加入unique这列值就不能是重复的,不加unique的话这列就可以重复插入
示例:
1.3、default
default的作用是当为null时,自动添加默认值
示例:
1.4、primary key
primary key是主键,表示一个身份标识,相当于同时使用not null和unique
示例:
注意:一张表只能有一个主键。
一般来说主键一般搭配auto_increment来使用,它的作用是默认为空的话就递增。
1.5、foreign key
foreign是外键的意思,它可以关联其他表的主键和唯一值。
注意:外键链接的两个表中父表的记录不能直接删除,我们要通过逻辑思维的方式修改,我们在表中引入新的字段,通过修改字段的值来进行删除。
1.6、check
check约束可以定向指定填入的数据。
二、对于数据库表中的构建
2.1、一对一关系
一对一关系就是在每个表中一个信息都对应一组数据。
表一:
ID | 姓名 |
1901 | 张三 |
1902 | 李四 |
1903 | 王五 |
表二:
ID | 姓名 | 手机号 |
1901 | 张三 | 158******** |
1902 | 李四 | 134******** |
1903 | 王五 | 189******** |
以上这两张表就是一一对应的关系
2.2、一对多关系
表一:
ID | 姓名 | 班级 |
1901 | 张三 | 1班 |
1902 | 李四 | 2班 |
1903 | 王五 | 1班 |
表二:
班级 | 班主任 |
1班 | 李老师 |
2班 | 王老师 |
由上图可知多个学生可以有一个班主任,这就是一对多。
2.3、多对多关系
表一:
ID | 姓名 | 班级 |
1901 | 张三 | 1班 |
1902 | 李四 | 2班 |
1903 | 王五 | 1班 |
表二:
ID | 比赛 |
1 | 拔河 |
2 | 跳水 |
3 | 跑步 |
4 | 游泳 |
表三:
班级 | 比赛ID |
1班 | 1 |
2班 | 1 |
1班 | 2 |
1班 | 3 |
2班 | 4 |
1班 | 4 |
像这样一个班级有多个学生,一个班级可能参加多个项目,这样的情况就是多对多。
三、索引和事务
3.1、索引
mysql中搜索常用索引,索引对提升数据库的性能有很大的改变。
注意:
如果用哈希表来表示,对于< > <= >=这些操作不太方便
如果用红黑树/AVL树来表示,由于都是二叉树,搜索效率是由树的高度来决定的
这时候我们就引入了一个数据结构B树(B-树)
结构:
B树是个N叉搜索树
特点:
1、N叉搜索树,每个节点都存在N个子树
2、每个节点都存在多个值
3、左子树小于又子树
在这个基础上我们又引出的B+树:
结构:
相对于B树来说:
1、非叶子节点的值会出现重复的值
2、叶子节点通过类似于链表的方式链接起来
我们通常对多次查询,删除修改较少的适合索引,在Mysql中最常见的索引就是B+树。
B+树的优势:
1、擅长进行范围查找
2、所有查询结果是在叶子节点上的,查询速度比较稳定
3、由于叶子节点是数据的全集,因此可以把叶子节点放硬盘上,非叶子节点直接存放到内存中,降低了硬盘的读取速度
聚簇索引和非聚簇索引的区别:
聚簇索引就是像B+树这样的数据本身通过B+树来组织,每个节点存入的是多个数据。
非聚簇索引和B+树差不多,但是数据储存在一个表中,每个节点存入的是表中具体位置的地址。
聚簇索引的效率更高,非聚簇索引产生的硬盘碎片更少
3.2、事务
当你进行转账操作时,你会开始发起转账,你的账户上会减钱,别人的账户上会加钱,如果发生错误钱就会返回到你的账户上,像这样逻辑上组成的一组操作,要么全部成功要么全部失败,这样的操作叫做事务。
事务具有的特性:
1、原子性
将一组操作打包在一起,要么都做完,要么一个不做。
2、一致性
执行任务之前和执行完任务之后,操作的状态要合理。
3、持久性
事务操作的数据都是直接在硬盘上的,硬盘可以持久的存储数据。
4、隔离性
多个事务,(多线程)并发执行时,事务中间不能互相干扰(本质上是线程安全问题)
3.3、隔离性以及并发编程中产生的问题
从原则上来看隔离性和并发编程是相反的两个概念,隔离是为了保证事务的准确性,并发是为了提高事务的效率。
如果多个事务之间的隔离性越强,并发编程就越低,效率就会越低。
如果多个事务之间的隔离性越弱,并发编程就越高,效率就会越高。
我们要尽可能在数据准确的情况下,尽可能的优化效率。
并发编程时产生的问题:
3.3.1、脏读
什么是脏读?
脏读就是当老师在写代码时创建一个student类写了一个add方法,有一个同学过来看了看老师写的代码发现老师代码中有add方法就记住,然后记得自己懂了就去干别的事情去了,老师后来就把这个方法删掉了,这个时候学生看到的方法这个信息就是脏读。
如果一个事务A在本地修改数据,另外一个事务B读取了它的修改内容,这样B的操作就是脏读。
解决脏读的方法:
给写操作加上锁。
当A在修改数据的时候,如果B读取内容就会阻塞,直到阻塞到A把数据上传之后B才能读取。
当我们引入写加锁时,事务的并发程度就降低了,效率也降低了,但是隔离性就提高了。
3.3.2、不可重复读
当我们将上面写的代码提交之后,大家开始读取老师写的代码,老师在学生读取的代码的时候,进行修改操作并且重新上传,这时候部分学生读取的代码一样,这样就会出现不可重复读。
一个事务A在执行的过程中,两次读取到不同的数据就叫不可重复读。
解决不可重复读的方法:
将读取操作也加上锁
当事务A进行读取的时候上锁,事务B想要进行修改就会阻塞。
当我们引入读加锁,事务的并发程度就降低了,效率也降低了,隔离性更高了。
3.3.3、幻读
当学生在进行读取操作的时候,老师虽然不能修改student类,但是老师添加和删除其他的类,这样的情况就叫幻读。
同一事务中,两次读到的结果集不一样这样的情况叫做幻读。
解决幻读问题的方法:
我们通过串行化来解决问题
让修改操作和读取操作彻底执行串行化,当修改的时候不能读取,当读取的时候不能修改。
这时并发编程度最低,效率也是最低的,隔离性最高,数据的可靠性最高。
3.3.4、MySQL中的隔离级别
隔离级别 | 理解 |
read uncommitted | 允许读取未提交的数据(隔离程度最低,并发性最高,有脏读问题) |
read committed | 只允许读取已提交的数据(隔离性提高了一点,并发性降低一点,有不可重复读问题) |
repratable read | (Mysql中默认的隔离级别)给读也加上锁(隔离性更加高,并发性更加的低,有幻读问题) |
serializable | 严格执行串行化(隔离性最高,并发性最低,解决了幻读问题) |