约束是为了安全插入数据,保证数据的合法性,防止无效数据进入数据库。它类似编译器语法提示,减少防止程序员在不知情的情况下插入错误数据。其中数据类型本身就是一种约束。
表的约束:表中一定要有各种约束,通过约束让我们未来插入数据库表中的数据是否合法的预期。本质通过技术手段倒逼程序员插入正确的数据。而站在mysql视角,插入进来是数据一定是合法的。
为什么要约束:数据库是维护数据的最后一道防线,必须保证数据的完整性和可预期性。
1.null属性
在建表过程中,我们为数据类型添加时可以指定null或not null属性。
- null:表示在插入数据时这一列可以为空,如果不显示添加任何属性,默认就为null。
- not null:表示在插入数据时该列必须填写。
如下:
- 对于null属性的数据,在填写时可以不对该列填写,默认为null。
- 对于not null属性的数据,在填写时不可忽略。
如下:
这样对于必须填写数据的列就可以对空值进行拦截。
2.默认值约束(default)
在建表时可以对类型设置默认值属性,如果进行显示填写,会被默认设置为null。默认值可以是null,或者一个确切的值,比如‘男’,‘张三’,20254063等。
测试:
当我们进行插入数据时,不对某些向插入也是可行的,它会自动带上默认值。
mysql> insert into test2 (name) values('张三'); query ok, 1 row affected (0.01 sec) mysql> select*from test2; +------+--------+--------+ | id | gender | name | +------+--------+--------+ | 0 | 男 | 张三 | +------+--------+--------+ 1 row in set (0.00 sec) mysql>
not null属性和default属性可以同时设置。它们并不冲突,而是一种互补功能。带有not null属性列也可以选择不插入,让它选择默认值,但前提必须是default属性不为null。
mysql> create table test3( -> id int default 0 not null, -> name varchar(20) not null -> ); query ok, 0 rows affected (0.01 sec) mysql> insert into test3 (name) values('李四'); query ok, 1 row affected (0.01 sec) mysql> insert into test3 (id) values(2025302); error 1364 (hy000): field 'name' doesn't have a default value mysql>
not null作用在用户插入的时候。default作用在用户忽略这一列的时候。一般情况下设置not null,不会带default。
3.comment
comment属性是列描述,更像是一种注释,给程序员看的。可以理解为软约束。
如下:
mysql> create table test4( -> id int comment '用户编号', -> name varchar(20) comment '用户名' -> ); query ok, 0 rows affected (0.02 sec) mysql> show create table test4; +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | table | create table | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | test4 | create table `test4` ( `id` int(11) default null comment '用户编号', `name` varchar(20) default null comment '用户名' ) engine=innodb default charset=utf8 | +-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql>
4.zerofill
zerofill是 mysql 中用于数值类型(如 int, smallint, bigint 等)的一个约束,它的主要作用是在显示数值时用前导零填充,以达到指定的字段宽度。
比如在创建数值类型时int(4),其中的4,表示时最小宽度为4位,如果加了zerofill属性,则不足4位的在前面添上0。
mysql> create table test5( -> a int(4) zerofill, -> b int(4) -> ); query ok, 0 rows affected (0.02 sec) mysql> insert into test5 values(231,231); query ok, 1 row affected (0.00 sec) mysql> select*from test5; +------+------+ | a | b | +------+------+ | 0231 | 231 | +------+------+ 1 row in set (0.00 sec) mysql>
当我们不指明对齐长度时,对于int类型默认为11,int unsigned类型默认为10。因为int类型和int unsigned类型最大值分别是四十多亿和二十多亿。都是10位数字,而对于int类型还需要有负号所以为11位。
应用场景:
- 产品编号:如 "00123" 而不是 "123"
- 会员卡号:如 "0000000456"
- 订单编号:保持固定位数便于人工核对
5.主键(primary key)
主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键。主键所在的列通常是整数类型。
在数据库操作中,增删查改通常需要依赖主键,以确保数据的唯一性和操作的准确性。
在插入数据时不允许主键重复。
mysql> create table test_key( -> id int primary key, -> name varchar(20) -> ); query ok, 0 rows affected (0.02 sec) mysql> insert into test_key values(2025401,'张三'); query ok, 1 row affected (0.00 sec) mysql> insert into test_key values(2025401,'李四'); error 1062 (23000): duplicate entry '2025401' for key 'primary' mysql> insert into test_key values(2025402,'李四'); query ok, 1 row affected (0.00 sec) mysql> insert into test_key values(2025403,'李四'); query ok, 1 row affected (0.01 sec) mysql> select*from test_key; +---------+--------+ | id | name | +---------+--------+ | 2025401 | 张三 | | 2025402 | 李四 | | 2025403 | 李四 | +---------+--------+ 3 rows in set (0.00 sec) mysql>
建表后才想起来加主键时,要保证没有重复数据。
只能有一个主键不意味着一个表中的主键只能添加给一列。可以设给多列,称为复合主键。
现在只有id和course_id同时和历史数据重复时才不被允许插入。如上也就是不能让学生的学号和选择的课重复记录。
id和course两者合起来才是一个主键。
6.自增长(auto_increment)
自增长属性主要作用于主键,主键有时候只是单纯的表示数据的唯一性,并不表示一种复杂的信息。此时可以把它设为自增长。也就是主键的信息不用我们自己去维护(插入),而是我们插入数据时会给该行自动添加主键信息。
要实现主键自增长添属性auto_increment即可。
mysql> create table test7( -> id int primary key auto_increment, -> name varchar(20) not null -> ); query ok, 0 rows affected (0.02 sec) mysql> insert into test7 (name) values('李华'); query ok, 1 row affected (0.01 sec) mysql> select*from test7; +----+--------+ | id | name | +----+--------+ | 1 | 李华 | +----+--------+ 1 row in set (0.00 sec) mysql>
如上我们并不需要手动输入id,系统会帮我们自动填充。 当然我们也可以手动插入。
我们再对自增长进行深入理解,观察下面插入结果。
mysql> insert into test7 (name) values('张三'); query ok, 1 row affected (0.00 sec) mysql> insert into test7 (id,name) values(50,'李四'); query ok, 1 row affected (0.00 sec) mysql> insert into test7 (name) values('王五'); query ok, 1 row affected (0.00 sec) mysql> select*from test7; +----+--------+ | id | name | +----+--------+ | 1 | 李华 | | 2 | 张三 | | 50 | 李四 | | 51 | 王五 | +----+--------+ 4 rows in set (0.00 sec) mysql>
可以发现当我们插入50后下一次自动从51开始自增。其实在表结构中存在auto_increment参数会记录次序。在建表时如果不进行设置auto_increment默认为1,也就是在下一次插入时,主键默认值为1。当我们手动插入50后,auto_increment变成51,从51自增。如下查看表的创建属性:
比如我们要给2026届的大一新生进行编号,可以把auto_increment参数设为20260001,即:
mysql> create table student( -> id int primary key auto_increment, -> name varchar(20) not null -> )auto_increment=20260001; query ok, 0 rows affected (0.01 sec)
7.唯一键(unique)
一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键,剩下需要唯一性约束的字段就可以使用唯一键。
唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。
关于唯一键和主键的区别:我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。最好把主键设计成为和当前业务无关的字段,这样,当业务调整的时候,我们可以尽量不会对主键做过大的调整。
唯一键和主键并不冲突而是互补的。
mysql> create table stu( -> id int primary key auto_increment, -> telephone char(11) unique, -> name varchar(20) not null -> ); query ok, 0 rows affected (0.01 sec) mysql> insert into stu values(20250302,18756623304,'张三'); query ok, 1 row affected (0.01 sec) mysql> insert into stu values(20250305,18756623304,'李四'); error 1062 (23000): duplicate entry '18756623304' for key 'telephone' mysql> insert into stu values(20250307,null,'王五'); query ok, 1 row affected (0.00 sec) mysql>
8.外键
外键约束的是表和表之间的关系。比如两个表:一个称为主表,一个称为从表。外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
比如一个学生表和班级表的关系。
- 主表:班级表
- 从表:学生表
对于学生表,在clase_id这一列必须依赖于班级表中的id这一列,学生不能填一个不存在的班级。对于班级表,如果该班级下还有学生不能把该班的id改变或删除。
语法:在从表的列项中加 语法:foreign key (字段名) references 主表(列)
注意:因为外键是在从表上建立,需要主表的信息,所以需要先建主表。
如下:
mysql> create table class( -> id int primary key, -> name varchar(20) not null -> ); query ok, 0 rows affected (0.02 sec) mysql> create table students( -> id int primary key, -> name varchar(20) not null, -> class_id int, -> foreign key(class_id) references class(id) -> ); query ok, 0 rows affected (0.01 sec) mysql>
query ok, 0 rows affected (0.01 sec) mysql> insert into class values(1,'经济统计'); query ok, 1 row affected (0.00 sec) mysql> insert into class values(2,'网络安全'); query ok, 1 row affected (0.00 sec) mysql> insert into class values(3,'机电工程'); query ok, 1 row affected (0.00 sec) mysql> insert into students values(2025023,'张三',1); query ok, 1 row affected (0.00 sec) mysql> insert into students values(2025024,'李四',5); error 1452 (23000): cannot add or update a child row: a foreign key constraint fails (`constrainttest`.`students`, constraint `students_ibfk_1` foreign key (`class_id`) references `class` (`id`)) mysql> delete from class where id=3; query ok, 1 row affected (0.00 sec) mysql> delete from class where id=1; error 1451 (23000): cannot delete or update a parent row: a foreign key constraint fails (`constrainttest`.`students`, constraint `students_ibfk_1` foreign key (`class_id`) references `class` (`id`)) mysql>
到此这篇关于mysql数据库表的约束的文章就介绍到这了,更多相关mysql数据库表约束内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论