目录
一、数据库约束
1、约束类型
二、NULL 约束
三、unique 约束
四、default 约束
五、primary key 约束
自增主键
六、foreign key 外键约束
七、check 约束
我们使用数据库来存储数据,一般是希望这里存储的数据是靠谱的,那么如何来保证数据是否靠谱呢?
那么MySQL就提供了一些机制,辅助我们自动的依赖程序,对数据进行检查,这类检查数据的机制,就是“约束”,一旦把约束确定好了,MySQL就会自动的对修改的数据做出检查,看看你此处的这个数据是否靠谱,如果不靠谱,不满足约束,就会直接报错。
YES 表示这两列允许为空,因此可以向表中插入null
那么现在我们重新创建一个 student 表,并加入 not nul 约束,再来看看结果
注意:not null 是对 列名 进行的一个约束,是给列名来指定的,写到列后面
此时我们会发现,id 可以为 null ,但是 name 不能为 null,那么现在,我们尝试插入一个name 为 null 的数据又会发生什么呢?
此时,会给我们一个明显的提示: name 这一列不能为 null
当 name 不为null 的时候,便可以正常插入数据了
不允许存在两行数据,再这个指定列上重复
此处的限制不能重复,指的是,指定列,不同行之间
同一行 不同列之间 或者 不同行 不同列之间 可以重复
和 not null 类似,unique 也是放在后面
我们现在,重新创建一个student表
那么此时,是可以插入重复的数据的
现在,我们再重新创建一个表
此时会发现在表的结构中,出现了一个UNI 的标志,它是unique 的前三个首字母,代表了唯一
当我们往表中插入两个编号一样的学生的时候,就会发生报错
针对带有unique 约束的数据,在插入记录的时候,就会先进行查询,看看结果是否以及存在,存在才插入,不存在则不会进行插入。同理,修改也是一样的
规定没有给列赋值时的默认值
我们先重新创建一个student 表
然后对其进行指定列插入
使用指定列插入的时候,未被指定的列就会按照默认值来进行填充,其中如果我们不修改默认值,那么默认情况下的默认值就是NULL
那么如何修改这个默认值呢?
只需要在创建表的时候在后面加上default 默认值便可
所以,此时,我们能看到defult 那一栏中name 所对应的默认值 便是 ‘未命名’
插入数据的时候,大多数情况下,都还是需要手动指定插入值的,使用默认值,会让代码看起来没有那么的直观。
比如这个代码,和‘未命名’三个字没有任何的关联,但是数据库的内容 的确包含 ‘未命名’
主键约束,主键就是一条数据的身份标识
通过这个约束,来指定某个列作为主键
1、非空
2、不能重复
一个表,只能有一个主键
同样的,我们重新创建一个 student 表,此时,让id 成为主键
此时,我们再烂看看这个表的属性就能发现,id 在NULL 这一栏是不能为空的,Key这一栏中的PRI 是primary 的缩写,这个时候,id 便被我们标记成了主键
此时,我们再插入两条一样的数据,或者插入了 id 为 NULL 的数据就会发生报错。
那么现在,我们来尝试创建一个有两个主键的表:
此时,它就会提示我们当前的主键已经被多次定义
因此,主键只能有一个,但是一个主键可以对应一个列或者多个列
主键,往往是一个 整数 类型的 Id,要求不能重复
允许客户端,再插入数据的时候,不手动指定主键的值,而是交给MySQL自行分配,确保分配出来的这个主键的值,是和之前不重复的
那么现在我们来看一下这个自增主键是怎么样进行使用的
其中 auto_increment 的意思就是 自动增加
此时,这个主键就变成了自增主键,并且auto_increment 必须搭配整数类型的主键使用
注意:这样的插入操作是OK的
这是因为,此时的 id 列是自增主键,设置成NULL 是让数据库自行分配一个 id
这时,我们能看到刚才的 id 是1
当我们再插入两条数据之后, id 依旧会按照自增的方式自行分配
自增主键 也是可以手动指定值的
那么如果下次再插入数据 按照NULL 让数据库自己分配的方式 此时新的记录是 4 还是 11 呢?
很明显,答案是11
那么这个 id 咋分配的呢?
MySQL 会记录当前 id 中的最大值,下一个分配的 id 就会在之前的最大值的基础上,继续自增
MySQL 是会维护这样的最大值的
如果MySQL 是一个单个节点的系统,基于上述策略,没有啥问题
如果MySQL 是一个分布式系统,此时,自增主键就无法保证唯一性
(每个主机上的MySQL只知道自己这个主机上存储的最大值,不知道其它节点的情况)
对于分布式系统下,要想分配这种表示唯一性的id,就不能依赖MySQL 的自增主键了
为了解决上述问题,也有很多分布式 id 的生成算法
核心公式:
目标是为了保证系统中每个节点 生成的id 都是唯一的
把 id 作为一个字符串,这个字符串由下列几个部分拼接而成:
涉及到两个表之间的约束
我们将约束别人的表称为: 父表
将被别人约束的表称为: 子表
我们先创建一个class 表,并向其中插入几条数据:
在这个代码中,需要明确交代,谁(哪个表的哪一列) 要受到 谁 (哪个表的哪一列)的约束
创建外键约束的时候,是修改子表的代码,父表的代码是不受影响的
1、进行插入或者修改子表中受约束的这一列数据,就需要确保 插入/修改 后的结果 在父表中存在
(针对这种带有外键约束的 插入/修改 就会触发查找操作,在父表中进行查询)
2、删除/修改 父表中的记录,就要看看这个记录是否在子表中被使用了,如果被使用了,则不能进行删除或者修改
3、删除父表之前必须要先删除子表
4、primary key 和 unique 这两个约束自带索引,没有索引就不能建立外键
现在我们来考虑一下下面这个场景:
那么在上述场景中,如何实现商品下架这个功能呢?
针对这样的场景,我们一般使用逻辑删除
如果要实现商品下架,直接 update 把商品表中的 ok 改成 0.
实现获取商品列表,就在select 的时候加个条件 and ok = 1
写一个具体的条件表达式,当前的记录符合条件就可以进行 插入/修改 ,不符合条件就失败
对于MySQL5 来说,check 并不支持,写上不会报错,但是并没用什么用