MySQL数据库:表的增删改查 [CRUD](进阶)
1. 约束
数据库中的约束是关系型数据库的一个重要功能,它的主要作用是保证数据的完整性,也可以自动地来校验数据的正确性,例如数据本身是否正确,关联关系是否正确等。这样就不需要人工来进行校验。我们一般在建立表的时候在数据类型的后面加上相应的约束。
1.1 约束类型
1.2 NOT NULL(非空约束)
在我们没有指定非空约束时,对某个表进行 desc 操作时,会有一栏称为 NULL 的每一行都会是YES,说明此时是允许存在空(NULL)的。

指定了非空约束那就说明此项为必填项,不填则会报错。这种情况对于成绩表、价格表等常常出现,如果我们要把某一列定义为一个必填项,那么就可以使用 NOT NULL 来约束。但是我们不能直接在原表上进行修改,只能是先删除然后新建一个新表。

可以看到指定了 NOT NULL 后,desc 中 NULL 那一栏就会有 “NO” 的标示了。
1.3 UNIQUE(唯一约束)
UNIQUE 是保证每行的值唯一,即不能有重复值,我们称之为唯一约束。不加唯一约束的时候,某些表可能出现编号相同,但是人名不同的情况,这样不符合逻辑。为了防止这种情况,在我们日常生活也十分常见,例如身份证号、学号等,这种号码都具备唯一性,十分适配 UNIQUE。
就以我们刚刚新建的 exam 表为例,如果没加 UNIQUE 约束,那么在 Key 的那一栏是不显示任何东西的;在加上之后就会有 “UNI” 的标识。

1.4 DEFAULT(默认约束)
DEFAULT 是指规定没有给列赋值时的默认值。以上图为例,在没创建的时候 DEFAULT 会为NULL。创建格式如下:

创建的时候需要在 default 后写上默认值的值,当你为某列设置了默认约束时,如果不给该列指定值就会使用默认约束。


如果我们指定的是一个叫做 NULL 的值时,你觉得会怎么样呢?

1.5 PRIMARY KEY(主键约束)
它是 NOT NULL 和 UNIQUE 的结合,既是非空的也是唯一的。需要注意的是指定了主键之后会有“PRI” 的标识,然后 NULL 的那一栏也会变为 “NO”。

在设置参数的时候,我们往往会在主键类型后面加上 auto_increment ,这个表示的是自增类型,表示以在当前表中上一条记录加1。我以插入张三、李四、王五的数据为例:

可以看到,插入时需要指定列插入,否则会报错;在插入过后,id 那一列就会开始从1自增。这样,就可以让数据库来帮我们维护主键的增长,不需要程序员自己来计算。那么接下来我又有几个问题想考考大家,大家可以把自己的答案先提前想好。
1. 如果是全列插入,不具体指定主键的值,取而代之使用NULL来代替,会怎么样呢?

当我们设置了自增主键时,发现在写入 NULL 时,也可以成功的插入数据;这里其实不是把 NULL 写入数据库了,而是说让数据库帮我们去处理这个列的值。
2. 那么同样在全列插入的情况下,写入数据时我们可不可以主动指定主键值呢?
答案是可以的,如下图:

3. 此时再去指定列插入一个值(不指定主键),这时的 ID 会是多少呢?

可以看到,主键值直接跳过了4,直接从我所指定的100跳到了101。这说明,主键值是在最大值的基础上加1,那么主键值在数据表有可能是不连续的。
1.5.1 复合主键
一个表中不允许有两个主键,若创建了则会直接报错。但是可以存在复合主键。复合主键就是指一个主键同时包含多个列,它在数据库唯一性的校验时,只有复合主键中的所有列都相同才被判定为相同。

这里的 primary key (id,name) 也可放在最后一行再创建,这个就看个人习惯。现在我们插入相同 ID但不同名字的人,来看看会出现什么情况。


可以看到插入成功了,需要注意这一特殊点。
总结:
主键约束帮我们校验了是否非空和唯一,这两个校验在写入数据时对效率虽然会有一定影响,但是比起什么校验都不做,这个样子的性能消耗还是可以承担的。而且在之后的索引部分的内容主键起到了举足轻重的作用。所以强烈建议大家为每张表都创建一个主键。
1.6 FOREIGN KEY (外键约束)
如果有表中某个列的值是别的表中的主键列,或是唯一约束列的值,也就是当前表中的值在别的表中重复存在,这就满足了主键或唯一约束(这个后面说)。

外键比较常用,它是用于关联其他表的主键或唯一键的,语法如下:
foreign key (字段名) references 主表(字段名)在创建好外键后,会显示出 “MUL” 的标识,说明已经创建好了外键关系。



通过外键约束就可以保证数据的完整性和关系的正确性。
当子表中存在主外键约束时,可以删除表中相应的记录吗?(不是指删除表)
![]()
答案是不能,会报出一个主外键关系的错误。如果要删除主表中的记录,子表中不能有对该条记录的依赖,这也就意味着要先删除子表中的记录,再去删除主表中的记录。
这一部分还是概念相对多一些,大家下来要多尽可能看一看,练习目前也还没有。
那么,本篇文章到此结束!希望能对你有帮助。
