之前写的太乱了,翻出来从新整理下mysql
小系列目录:sql
(一) MySQL入门,问题不大数据库
https://segmentfault.com/a/11...segmentfault
想要讲解约束,就要知道约束用在哪里,用来干吗?微信
SQL 语言经过定义一个关系所对应的基本表来完成关系模式的定义,其语句格式为:测试
CREATE TABLE 表名( <列名1> <数据类型1> [<列级完整约束条件>], [<列名2> <数据类型2> [<列级完整约束条件>],...], [<表级完整约束条件>] );
符号规定:下面展现一些定义的时候,为简便理解,使用中文配合符号表述(会有具体举例,不用担忧理解不了)spa
<>
中的内容为实际的语义[]
中的内容为任选项(不填写也可){}
中的内容必须显式的指定|
为选项符[,...n]
表示前面的项能够重复屡次约束,就是针对属性值的一些约束条件,只针对某一列,叫作列级约束、针对多列属性的约束,叫作表级约束操作系统
怎么理解呢?就例如某一列叫作 学号,咱们就指定约束,这一行不容许为 NULL ,同时咱们还能指定它为主键,这样经过学号就能够查找到一条惟一的学生记录了,还有例如外键知识等等...code
总结起来就一句话:约束用来对表中的数据进行限定,保证数据的正确性、有效性和完整性blog
一样,有了约束知识的铺垫,咱们就能够引伸出后面的一些知识,例如多表操做等等,因此约束虽然简单,仍是很是重要的哈~
在关系模型中,主键的本质其实就是一个候选键
理解很是简单,就是能经过这个主键,肯定一个惟一的记录:例如学号是学生实体的候选键,一个学号就能肯定这个学生到底哪一个学生,而咱们不选择姓名,这是由于,姓名在实际的状况中,不能做为一个惟一的标识,确认一个惟一的学生记录
候选键:关系中能惟一标志一个元组的最小属性集
肯定为主键的列,不能为空,也不能重复!!!
指定主键约束,使用的是 PRIMARY KEY 关键字
通常来讲,主键约束主要用在建立表时,指定约束的方式有两种:
CREATE TABLE students ( sid INT(8) PRIMARY KEY, sname VARCHAR(5), department VARCHAR(32), birthday date )
CREATE TABLE students ( sid INT(8), sname VARCHAR(5), department VARCHAR(32), birthday date, PRIMARY KEY (sid) )
若是在表已经建立好的前提下,还能够经过下列两种方式进行主键的指定和删除
ALTER TABLE students DROP PRIMARY KEY;
ALTER TABLE students ADD PRIMARY KEY(sid); ALTER TABLE students MODIFY sid INT PRIMARY KEY;
提到主键,就必须提到主键自增了,这个功能也是很是经常使用的,当设置主动自增后,例如你使用高级语言,操做数据库,向学生表插入一条记录后,即便不给出主键值,主键值也会自动生成出来,而且会在最大主键值的基础上 + 1,例如 0,1,2 ... ,n
最重要的一点,主键必须是整型,才能实现自增喔~
若是主键例如 sid 为 varchar 类型,就会有这样的报错:Incorrect column specifier for column 'sid'
一样,主键自增通常用在建立表的时候,使用 AUTO_INCREMENT,直接跟在列名后便可
CREATE TABLE students ( sid INT(8) PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(5), department VARCHAR(32), birthday date )
若是表已经建立好了,还能够进行是否自增的修改
ALTER TABLE students CHANGE sid sid INT AUTO_INCREMENT; ALTER TABLE students MODIFY sid INT AUTO_INCREMENT;
ALTER TABLE students CHANGE sid sid INT; ALTER TABLE students MODIFY sid INT;
说明:上面设置以及删除都给出了 CHANGE 和 MODIFY 两种,有什么区别呢?
其实细心的朋友也能够看出来, CHANGE 后要多一个列名 sid(能够修改) ,因此总结以下:
非空约束很好理解,就是指定非空约束列的值不能为空,咱们使用 NOT NULL 来实现这个功能
CREATE TABLE students ( sid INT(8) PRIMARY KEY AUTO_INCREMENT, sname varchar(5) NOT NULL, -- sname 不为空 department varchar(32), birthday date );
很简单吧,咱们已经将 sname 这个字段(列)在建立时添加了非空约束,若是 sname 在插入时为NULL ,则会报错 Column 'sname' cannot be null
若是表已经建立好了怎么办呢?
ALTER TABLE students MODIFY sname VARCHAR(5) NOT NULL;
ALTER TABLE students MODIFY sname VARCHAR(5);
惟一约束,就是指定这个字段(列)的值必须是惟一的,这种感受就相似主键,例如咱们下面要求建立表的时候,指定 sname 不能重名
CREATE TABLE students ( sid INT(8) PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(5) NOT NULL UNIQUE, -- sname惟一 department VARCHAR(32), birthday date );
若是添加两条重名的记录,就会报错
INSERT INTO students VALUES (NULL,'张三','计算机系','2020-06-16'); INSERT INTO students VALUES (NULL,'张三','工商管理系','2019-06-16');
错误信息:Duplicate entry '张三' for key 'sname'
一样,若是已经建立表后,又该怎么设置或者删除惟一约束呢?
ALTER TABLE students MODIFY sname VARCHAR(8) UNIQUE;
ALTER TABLE students DROP INDEX sname; -- 这两种方法都是能够的 drop index sname on students;
外键的理论定义是比较复杂的,我在之前公众号写过的一篇数据库理论文章中有说起过,可是这一篇咱们重点讲解 MySQL 的使用,因此,咱们把理论都换成例子和通俗的大白话,先来看个问题:
学生实体和课程实体分别用关系“学生”和“课程”来表示,它们之间的联系用关系“选课”来表示
学生(学号,姓名,所在系,生日)
课程(课程编号,课程名,授课老师)
选课(学号,课程编号,成绩)
问题:判断各关系的候选键、主键、外键
答:
模拟了几张简单的表,给你们直观的理解
看完这个例子,是否是从理解上感受清晰了不少,那么接下来,咱们就实际操做一下:
CREATE TABLE 表名( .... CONSTRAINT 外键名称 FOREIGN KEY (外键列名称) REFERENCES 主表名称(主表列名称) ); -- 建立表以后,删除外键 ALTER TABLE 表名 DROP FOREIGN KEY 外键名称; -- 建立表以后,添加外键 ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
咱们下面,就按照这张图的规划来作
CREATE TABLE students ( sid INT(8) PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(5) NOT NULL UNIQUE, department VARCHAR(32), birthday date );
CREATE TABLE course ( cid INT(8) PRIMARY KEY AUTO_INCREMENT, cname VARCHAR(5), teacher VARCHAR(32) );
CREATE TABLE sc_relation ( sid INT(8), cid INT(8), cscore VARCHAR(5), CONSTRAINT sc_sid FOREIGN KEY (sid) REFERENCES students(sid), CONSTRAINT sc_cid FOREIGN KEY (cid) REFERENCES course(cid) );
随便提供一些数据,方便你们测试
-- 插入学生数据 INSERT INTO students VALUES (1001, '王五', '工商管理系', '2020-06-16'); INSERT INTO students VALUES (1002, '汤姆', '音乐与舞蹈系', '2020-06-16'); INSERT INTO students VALUES (1003, '杰克', '美术系', '2020-06-16'); -- 插入课程数据 INSERT INTO course VALUES (1, '大学英语', '老师1'); INSERT INTO course VALUES (2, '大学物理', '老师2'); INSERT INTO course VALUES (3, '数据库', '老师3'); INSERT INTO course VALUES (4, '操做系统', '老师4'); INSERT INTO course VALUES (5, '高等数学', '老师5'); -- 插入选课数据 INSERT INTO sc_relation VALUES (1001, 2, '88'); INSERT INTO sc_relation VALUES (1001, 3, '92'); INSERT INTO sc_relation VALUES (1001, 4, '78'); INSERT INTO sc_relation VALUES (1001, 5, '83'); INSERT INTO sc_relation VALUES (1002, 1, '77'); INSERT INTO sc_relation VALUES (1002, 2, '90'); INSERT INTO sc_relation VALUES (1002, 5, '89'); INSERT INTO sc_relation VALUES (1003, 1, '86'); INSERT INTO sc_relation VALUES (1003, 6, '88'); INSERT INTO sc_relation VALUES (1003, 6, '82');
有什么用呢?这个时候学生表以及课程表,就同选课表之间造成了关系,可视化软件编辑插入的时候,就会默认的给出一些可插入的选择,这是软件基于你设置的外键关系而自动寻找的
建立表后又怎么操做呢?
ALTER TABLE sc_relation DROP FOREIGN KEY sc_sid;
ALTER TABLE sc_relation ADD CONSTRAINT sc_sid FOREIGN KEY (sid) REFERENCES students(sid)
若是在上述选课表中已经存储着 关于学号为 1001 学生的相关选课信息,若是这个时候,在学生表中修改或者删除这条记录,就会直接报错
Cannot add or update a child row: a foreign key constraint fails (`mysql_grammar_test`.`sc_relation`, CONSTRAINT `sc_sid` FOREIGN KEY (`sid`) REFERENCES `students` (`sid`))
因此咱们使用级联操做就能够达到同时更新或者删除多张表内的相关数据
先给出基本格式:
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE;
例如测试一下
ALTER TABLE sc_relation ADD CONSTRAINT sc_sid FOREIGN KEY (sid) REFERENCES students(sid) ON UPDATE CASCADE ON DELETE CASCADE;
以前不能操做的内容,如今已经能够了,例如咱们在学生表中将 1001学号修改成 1008 ,这样选课表中相关的内容就会自动根据修改变化了哈
若是文章中有什么不足,欢迎你们留言交流,感谢朋友们的支持!
若是能帮到你的话,那就来关注我吧!若是您更喜欢微信文章的阅读方式,能够关注个人公众号
在这里的咱们素不相识,却都在为了本身的梦而努力 ❤一个坚持推送原创开发技术文章的公众号:理想二旬不止