不是吧,阿Sir,MySQL常见约束你居然还不知道吗?

之前写的太乱了,翻出来从新整理下mysql

小系列目录:sql

(一) MySQL入门,问题不大数据库

https://segmentfault.com/a/11...segmentfault

(一) 引入约束

(1) 约束出如今哪里?

想要讲解约束,就要知道约束用在哪里,用来干吗?微信

SQL 语言经过定义一个关系所对应的基本表来完成关系模式的定义,其语句格式为:测试

CREATE TABLE 表名(
    <列名1> <数据类型1> [<列级完整约束条件>],
    [<列名2> <数据类型2> [<列级完整约束条件>],...],
    [<表级完整约束条件>]
);

符号规定:下面展现一些定义的时候,为简便理解,使用中文配合符号表述(会有具体举例,不用担忧理解不了)spa

  • <> 中的内容为实际的语义
  • [] 中的内容为任选项(不填写也可)
  • {} 中的内容必须显式的指定
  • | 为选项符
  • [,...n] 表示前面的项能够重复屡次

(2) 约束用来干吗?

约束,就是针对属性值的一些约束条件,只针对某一列,叫作列级约束针对多列属性的约束,叫作表级约束操作系统

怎么理解呢?就例如某一列叫作 学号,咱们就指定约束,这一行不容许为 NULL ,同时咱们还能指定它为主键,这样经过学号就能够查找到一条惟一的学生记录了,还有例如外键知识等等...code

总结起来就一句话:约束用来对表中的数据进行限定,保证数据的正确性、有效性和完整性blog

一样,有了约束知识的铺垫,咱们就能够引伸出后面的一些知识,例如多表操做等等,因此约束虽然简单,仍是很是重要的哈~

(二) 常见约束

(1) 主键约束

A:基本概念

在关系模型中,主键的本质其实就是一个候选键

理解很是简单,就是能经过这个主键,肯定一个惟一的记录:例如学号是学生实体的候选键,一个学号就能肯定这个学生到底哪一个学生,而咱们不选择姓名,这是由于,姓名在实际的状况中,不能做为一个惟一的标识,确认一个惟一的学生记录

候选键:关系中能惟一标志一个元组的最小属性集

B:特色

肯定为主键的列,不能为空,也不能重复!!!

C:具体操做

指定主键约束,使用的是 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;

D:主键自增

提到主键,就必须提到主键自增了,这个功能也是很是经常使用的,当设置主动自增后,例如你使用高级语言,操做数据库,向学生表插入一条记录后,即便不给出主键值,主键值也会自动生成出来,而且会在最大主键值的基础上 + 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(能够修改) ,因此总结以下:

  • 只修改类型用 MODIFY
  • 既修改列名,也修改类型用 CHANGE

(2) 非空约束

非空约束很好理解,就是指定非空约束列的值不能为空,咱们使用 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;
  • 删除 sname 的非空约束
ALTER TABLE students MODIFY sname VARCHAR(5);

(3) 惟一约束

惟一约束,就是指定这个字段(列)的值必须是惟一的,这种感受就相似主键,例如咱们下面要求建立表的时候,指定 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;

(4) 外键约束

A:概念理解

外键的理论定义是比较复杂的,我在之前公众号写过的一篇数据库理论文章中有说起过,可是这一篇咱们重点讲解 MySQL 的使用,因此,咱们把理论都换成例子和通俗的大白话,先来看个问题:

学生实体和课程实体分别用关系“学生”和“课程”来表示,它们之间的联系用关系“选课”来表示

学生(学号,姓名,所在系,生日)
课程(课程编号,课程名,授课老师)
选课(学号,课程编号,成绩)

问题:判断各关系的候选键、主键、外键

答:

  • 学生中(students) 学号能够确认惟一的学生是候选键,可作主键,姓名须要在不重名的状况下也能够,可是实际状况不能保证没有重名不合适,课程中(course) 课程编号能够确认惟一的课程是候选键,可作主键,而选课中(sc_relation),须要由学号和课程编号共同才能肯定惟一的值,因此二者共同构成候选键,并作主键
  • 选课关系中的 学号(sc_relation.sid)课程号(sc_relation.cid) ,分别表明选课关系的外键,他们分别对应 学生关系的学号(students.sid)课程关系的课程号(course.sid)(不必定要同名,可是为了好理解,通常写成同名)
  • 模拟了几张简单的表,给你们直观的理解

    • 说明:第一张为 学生表 students ,第二张为 课程表 course,第三张为 选课表 sc_relation

看完这个例子,是否是从理解上感受清晰了不少,那么接下来,咱们就实际操做一下:

C:基本格式

CREATE TABLE 表名(
        ....
        CONSTRAINT 外键名称 FOREIGN KEY (外键列名称) REFERENCES 主表名称(主表列名称)
);

-- 建立表以后,删除外键
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

-- 建立表以后,添加外键
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);

B:具体操做

咱们下面,就按照这张图的规划来作

  • 建立学生表 students,学号 sid 为主键
CREATE TABLE students (
    sid INT(8) PRIMARY KEY AUTO_INCREMENT,
    sname VARCHAR(5) NOT NULL UNIQUE,
    department VARCHAR(32),
    birthday date
);
  • 建立课程表 course,课程号 cid 为主键
CREATE TABLE course (
    cid INT(8) PRIMARY KEY AUTO_INCREMENT,
    cname VARCHAR(5),
    teacher VARCHAR(32)
);
  • 建立选课关系表,sc_sid、sc_cid 分别为外键,指向学生表中的学号 sid 和 课程表中的课程号 cid
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)

C:级联操做

若是在上述选课表中已经存储着 关于学号为 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;
  • A:级联更新:ON UPDATE CASCADE
  • B:级联删除: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 ,这样选课表中相关的内容就会自动根据修改变化了哈

(三) 结尾

若是文章中有什么不足,欢迎你们留言交流,感谢朋友们的支持!

若是能帮到你的话,那就来关注我吧!若是您更喜欢微信文章的阅读方式,能够关注个人公众号

在这里的咱们素不相识,却都在为了本身的梦而努力 ❤

一个坚持推送原创开发技术文章的公众号:理想二旬不止

相关文章
相关标签/搜索