MySQL数据库表的约束

发布于:2025-05-13 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

1.null属性

2.默认值约束(default)

3.comment

4.zerofill

5.主键(primary key)

6.自增长(auto_increment)

7.唯一键(unique)

​编辑

8.外键


        约束是为了安全插入数据,保证数据的合法性,防止无效数据进入数据库。它类似编译器语法提示,减少防止程序员在不知情的情况下插入错误数据。其中数据类型本身就是一种约束。

        表的约束:表中一定要有各种约束,通过约束让我们未来插入数据库表中的数据是否合法的预期。本质通过技术手段倒逼程序员插入正确的数据。而站在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> 


网站公告

今日签到

点亮在社区的每一天
去签到