文章目录
- 前言
- 一、约束类型
- 二、NOT NULL
- 三、UNIQUE
- 四、DEFAULT
- 五、PRIMARY KEY(重点)
- 1, 自增主键
- 六、FOREIGN KEY (重点)
- 1, 插入数据
- 2, 删除数据
- 3, 关于外键约束下删除数据的思考
- 总结
前言
各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你:
📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
📗 Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
📘 JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)
提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说,直接上干货!
一、约束类型
- NOT NULL - 指示某列不能存储 NULL 值。
- UNIQUE - 保证某列的每行必须有唯一的值。
- DEFAULT - 规定没有给列赋值时的默认值。
- PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
- FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
约束需要在创建表的时候给字段加上的, 也可以创建表后使用 alter 修改表结构, 本篇都使用第一种方式
二、NOT NULL
- not null 约束了数据不能为空, 首先创建一张学生表, 学生的字段包含 id 和姓名, 我们给 id 这个字段加上 not null 约束 :
- 查看表结构 :
- 分别插入 id 不为 null , 和 id 为 null 的两条数据看效果 :
三、UNIQUE
- unique 约束了数据不能重复, 把刚才的表删掉, 把学生表中 id 这个字段加上 unique 约束, id 一人一个不能重复, 非常合理 :
- 查看表结构 :
- 分别插入 id 不重复和 id 重复的两条数据看效果 :
设置了 unique 约束之后, 插入某个数据之前, 系统会先查询, 如果已经有了该数据, 则不能再插入
四、DEFAULT
- default 可以设置数据为空时的默认值, 把刚刚的表删掉, 给 name 这个字段加上默认值"无名氏" :
- 查看表结构 :
- 用指定列插入的方式只插入 id, 看效果 :
注意, 如果不手动设定默认值, 那么默认值为 NULL
五、PRIMARY KEY(重点)
primary key (主键约束)是一条数据的身份标识, 类似于通过身份证就能找到唯一的人, 通过快递单号就能找到唯一的包裹, 通过订单号就能找到唯一的订单
一张表只能有一个列为主键!!
- primary key (主键约束) 即不允许为空, 也不允许重复, 所以是 not null 和 unique 这两个约束的结合体, 通过主键能找到唯一的一行数据, 因此主键在索引中至关重要
在学生表中, 我们把 id 设置成主键, 即便有无数个重名的学生, 通过 id 就找到唯一的学生 :
- 查看表结构 :
- 我们分别插入不为空且不重复的数据, 为空的数据, 重复的三条数据, 看效果 :
和 unique 约束一样, 主键的字段插入数据之前, 系统会先进行查询
设置了主键之后, 插入什么数据还是取决于程序员如何编写 sql, 程序员也是有可能写错的, 当主键是数字时, MySQL 就贴心了提供了一个机制 : 自增主键(auto_increment)
1, 自增主键
设置了自增主键之后, 程序员不需要再手动指定主键的值, 插入数据对应字段不给值时, 使用最大值 +1。
- 给 id 设置成自增主键 :
- 查看表结构 :
- 不指定 id 的值(写成 null), 让自增主键机制帮我们分配 :
- 也可以自己分配一个值之后, 再让自增主键帮我们分配 :
- 可以看到主键从 100 开始分配了, 那 3 ~ 100 之间的值就空出来了, 如果再插入一条数据, 把主键的值设置为 4 , 能成功吗 ?
六、FOREIGN KEY (重点)
foreign key (外键)用于关联其他表的主键或唯一键, 在多表查询中也至关重要
sql 语句 : foreign key (列名) references 其他表 (列名);
比如现在有一张学生表和班级表 :
创建班级表和学生表, 设置主键和外键 :
1, 插入数据
- 往学生表中插入数据, 发现报错了
- 所以要先在班级表(父表)中插入主键数据后, 再插入学生表(子表)的主键数据
- 查看表中数据 :
当外键关联了其他表中的主键, 就有了父表子表之分
从子表中插外键数据时, 会先从父表中的主键数据中查询是否存在该记录
2, 删除数据
- 尝试删除班级表(父表)中 classId 为 1 的这条记录 :
在插入数据时, 父表约束子表, 要先插入父表中主键数据
在删除数据时, 子表约束父表, 要先删除子表中外键数据
- 先删除子表, 再删除父表 :
这样的规则其实也比较合理, 如果在子表中还有外键约束的时候就把与之关联的父表中主键的数据删了, 子表中的这个外键就不能再使用了
但是这又引来了一个问题, 如果有时确实需要删除父表中的主键数据怎么办呢?
3, 关于外键约束下删除数据的思考
以电商网站为例, 商家至少要有一张商品表和一张订单信息表, 订单信息表中一定要有购买的商品的信息, 以方便顾客回购商品
如图 :
如果过了一段时间后, 顾客想回购这件商品, 但是这件商品下架了, 商品表的该商品的记录肯定是要删除, 但是订单表的该订单信息不能删除
现在的情况就是, 如何在不删除订单表(子表)中这条数据的前提下, 删除商品表(父表)中的这条数据?
根据外键的约束来看, 确实是没办法删, 而且外键约束也不能撤销, 正确的做法是, 给商品表多加一个"是否下架"的字段来表示该商品是否被删除
这种做法称作"逻辑删除", 如果该商品的"是否下架"这个字段为"已下架", 则不在商品列表中显示即可
总结
以上就是本篇的全部内容, 主要介绍了五种约束类型, 其中主键和外键最重要, 要重点理解他们的 sql 语法和使用时的注意事项
如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~
上山总比下山辛苦
下篇文章见