MySQL 主键约束、非空约束、唯一约束

本文详细讲解了数据库中的核心约束,包括主键约束的定义、添加和删除,非空约束的含义,以及唯一约束的应用。特别介绍了自动增长列和联合主键的概念。适合数据库管理和开发者学习。

关注【郑大钱呀】【公】【众】【号】,我们一起交流,一起学习。

1.1 什么是约束

约束字面意思就是限制,比如我们每一个人的身份证号都是唯一的,不可能出现两个人,身份证是一样的,那么这里的唯一性我们就称之为一种约束,再比如:我们每个人都是有性别的,或男或女或其他,不可能出现一个人他没有性别,那么这里的不能为空同样也是一种约束。在数据库中也有很多约束,数据库的数据必须要满足约束才可正确插入,否则就会报错,下面我们具体学习约束的内容

1.2主键约束

1.2.1 主键约束

主键约束(PRIMARY KEY),简称主键,该约束的作用是定义一个主键来唯一确定表中每一行数据的标识符,我们把它拆解开来说:

  • 使用了主键的字段的值,必须是唯一的,不能重复
  • 主键的列,不能包含NULL值
  • 每个表最多只能有一个主键

1.2.2 添加主键约束

创建表时,声明主键,示例代码如下:

CREATE TABLE People(
id int PRIMARY KEY,
name VARCHAR(30),
age INT
);

创建完成后,我们看一下People表的表结构,如下:

mysql> desc People;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int         | NO   | PRI | NULL    |       |
| name  | varchar(30) | YES  |     | NULL    |       |
| age   | int         | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> 

这里我们发现id字段在NULL列的值为NO,在KEY列有个PRI键,这个就表示该字段为主键,下面我们试一下,如果我们插入数据时,主键字段为空,报什么错,报错如下:

mysql> insert into People(id,name,age) values(NULL,"张三",'20');
ERROR 1048 (23000): Column 'id' cannot be null
mysql> 

从上面的报错我们可以看出主键不能为空,为空就会报上面的错,下面我们再来验证一下主键id字段不能重复,代码如下:

mysql> insert into People(id,name,age) values(1,"张三",'20');
Query OK, 1 row affected (0.01 sec)

mysql> insert into People(id,name,age) values(1,"张三",'20');
ERROR 1062 (23000): Duplicate entry '1' for key 'people.PRIMARY'
mysql> 

我们最开始插入了一条数据,然后我们又插入了一遍,发现报错了,提示id的值重复了,主键是不能重复的。

1.2.3 联合主键

我们上面的主键为id,即只需要一个字段就可以标识数据的唯一性,有的时候我们的表需要两个及以上的字段组合起来,才能确定一条记录的唯一性,举个例子,假如我们要设计一张统计一个地区学生信息的表,一个地区有多个学校,每个学校都有自己的编号,而每个学校的学生有自己的学校,当我们想要确定这个地区的某个学生时候,单单使用学号是无法确定的,因为有多个学校,学号肯定有重复的,此时我们就需要学校和学生学号两个字段才能准确确定一个学生,这个时候就需要将这两个字段设置成联合主键联合主键还是一个主键,只不过这个主键是由多个字段共同确定的

示例代码如下:

CREATE TABLE AreaStuInfo(
sch_no INT,
stu_no INT,
name VARCHAR(30),
CONSTRAINT pk_sch_stu_id PRIMARY KEY (sch_no,stu_no)
);

这个时候,我们再查询一下表结构,结果如下:

mysql> DESC AreaStuInfo;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sch_no | int         | NO   | PRI | NULL    |       |
| stu_no | int         | NO   | PRI | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

从上面的结果我们发现,sch_nostu_no两个字段的KEY列的值都有PRI,也就意味着sch_no和stu_no两者的值一样,就会触发约束,报错,但是如果仅仅是这两个列的某一个列的值一样,它是不会报错。

1.2.4 删除主键约束

当我们不需要主键约束的时候,我们可使用如下的代码,将某一张的主键删除,语法如下:

ALTER TABLE 表名 DROP PRIMARY KEY;

示例代码入下:

mysql> DESC AreaStuInfo;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sch_no | int         | NO   | PRI | NULL    |       |
| stu_no | int         | NO   | PRI | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

mysql> ALTER TABLE AreaStuInfo DROP PRIMARY KEY;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> DESC AreaStuInfo;
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| sch_no | int         | NO   |     | NULL    |       |
| stu_no | int         | NO   |     | NULL    |       |
| name   | varchar(30) | YES  |     | NULL    |       |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

mysql> 

1.2.5 自动增长列

我们有的时候,希望表的某一个字段的值是自动增长的,比如编号,从1开始,依次+1,在数据库中,我们可以使用auto_increment自动增长列关键字来实现,数据库会自动生成该字段的值默认开始的值是1,我们也可以修改起始值,语法如下:

ALTER TABLE 表名 AUTO_INCREMENT=值

此外值得注意的是,如果一个字段是自动增长的列,那么该字段的数据类型必须是整型且必须是主键,下面我们看一个示例:

CREATE TABLE `People` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `age` int DEFAULT NULL
);

我们看一下表结构:

mysql> desc People;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | YES  |     | NULL    |                |
| age   | int         | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

我们有自动增长列的表中插入数据的时候,可以不为id字段设置值,也可以为其设置成null,示例代码如下:

mysql> insert into People(name,age) values("王二",20);
Query OK, 1 row affected (0.01 sec)

mysql> insert into People(id,name,age) values(Null,"李四",20);
Query OK, 1 row affected (0.00 sec)

mysql> select * from People;
+----+--------+------+
| id | name   | age  |
+----+--------+------+
|  1 | 王二   |   20 |
|  2 | 李四   |   20 |
+----+--------+------+
2 rows in set (0.00 sec)

mysql> 

从上面的示例上我们可以看出,我们即使没有指定id字段的值,也是不会报错的,数据库会自动为其生成值

1.3 非空约束

所谓非空的约束,其实很简单,如果那个字段的值添加了非空的约束,那么这个字段的值就不能为NULL,如果是NULL,就会报错,示例代码如下:

mysql> desc People;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | YES  |     | NULL    |                |
| age   | int         | YES  |     | NULL    |                |
| sex   | char(30)    | NO   |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> insert into People(name,age,sex) values('张三',29,NULL);
ERROR 1048 (23000): Column 'sex' cannot be null
mysql> 

我们从通过查询People的表结构发现,sex字段不能为空,当我们在插入数据的时候,如果把该字段插入一个空值,那么就会报错。添加非空约束的语法如下,只需要在需要添加的字段后面,增加NOT NULL即可。示例代码如下:

CREATE TABLE `People` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `age` int DEFAULT NULL,
	`sex` CHAR(30) NOT NULL
);

1.4 唯一约束

唯一约束也很简单,就是字面意思,如果一个字段被添加了唯一约束,那么该字段的值就只能是唯一的,不可重复的,添加唯一约束方式也很简单,直接在数据类型的后面加上UNIQUE关键字即可,示例代码如下:

CREATE TABLE `Person` (
  `id` int PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(30) UNIQUE,
  `age` int 
);

以我们这里的Person表为例,所有数据的名字都不能重复,如果重复则会报错,示例如下:

mysql> desc person;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int         | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30) | YES  | UNI | NULL    |                |
| age   | int         | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> insert into person(name,age) values("张三",20);
Query OK, 1 row affected (0.00 sec)

mysql> insert into person(name,age) values("张三",20);
ERROR 1062 (23000): Duplicate entry '张三' for key 'person.name'
mysql> 

但是这个唯一约束对一个值例外,就是NULL,在MySQL中,NULL与任意一个值都不想等,连和它自己都不相等,多以如果名称这一列有多条记录,但是它的值是空的,也是不会报错的。

1.5 结尾

本期的内容就到这里了,如有不足之处还请大家多多指正,欢迎大家留言、关注、转发、收藏,谢谢。

<think>嗯,用户这次的问题很明确,是在确认MySQL主键的两个核心特性:唯一性。结合用户提供的引用材料历史对话,我需要给出权威且清晰的解释。 用户可能正在学习数据库约束相关的知识,或是遇到了实际设计表时的困惑。从ta反复确认主键特性的行为来看,ta对数据完整性原则常重视,这种严谨的态度值得赞赏。 让我梳理一下关键证据链: 引用[2]直接指出"主键的列不能包含NULL值""使用了主键的字段的值必须是唯一的"[^2],这是最核心的佐证。引用[3]的语法示例也印证了主键在定义时就天然包含这两个特性[^3]。有趣的是,用户似乎已经通过之前的讨论理解了主键的独立性(不需要来自其他表),现在更聚焦在属性层面。 考虑到用户连续提出技术细节问题,回答时需要特别注意: 1 必须用表格对比主键/外键/唯一约束的区别,帮助建立系统认知 2 要解释"为什么"需要这些特性(比如避免数据歧义) 3 警告常见错误场景(如误用NULL值) 最后的相关问题设计要延续知识链,比如下一步可以探讨主键选择策略或索引实现原理。 </think>关于MySQL主键唯一性,以下结论基于引用内容: ### ✅ 结论 **正确**。MySQL主键必须同时满足: 1. **性**(NOT NULL) 2. **唯一性**(UNIQUE) ### 📚 详细说明(附引用依据) | 特性 | 说明 | 引用依据 | |-------------|----------------------------------------------------------------------|--------------------------------------------------------------------------| | **性** | 主键列禁止存储`NULL`值,插入或更新时值会被拒绝 | 引用[2]:"主键的列,不能包含NULL值" [^2] | | **唯一性** | 主键列的值必须唯一,重复值会导致操作失败 | 引用[1]:"主键是数据表的唯一索引";引用[2]:"使用了主键的字段的值,必须是唯一的" [^1][^2] | | **其他特性**| 每张表只能有一个主键,可以是单列或多列组合(复合主键) | 引用[2]:"每个表最多只能有一个主键" [^2] | ### 🔍 关键引用解析 1. **定义本质** > 引用[2]明确说明: > _"主键约束(PRIMARY KEY)的作用是定义一个主键来唯一确定表中每一行数据的标识符"_ > 其中包含两条核心规则: > - 值必须唯一 > - 不能包含`NULL`值 [^2] 2. **创建表示例** 引用[3]的语法验证性与唯一性: ```sql CREATE TABLE emp2( eid INT PRIMARY KEY, -- 隐含 NOT NULL + UNIQUE ename VARCHAR(20), sex CHAR(1) ); ``` 若插入重复值或`NULL`,操作将被拒绝 [^3]。 3. **与其他约束对比** | 约束类型 | 唯一性 | 性 | 数量限制 | |------------|--------|--------|----------| | **主键** | ✅ | ✅ | 每表1个 | | **唯一约束**| ✅ | ❌(允许NULL)| 每表多个 | | **约束**| ❌ | ✅ | 无限制 | ### ️ 注意事项 - **复合主键**:多列组合必须整体唯一,但单列可重复(如`(order_id, product_id)`)。 - **自增主键**:使用`AUTO_INCREMENT`时仍需满足唯一性(如`id INT AUTO_INCREMENT PRIMARY KEY`)[^3]。 - **错误场景**: ```sql INSERT INTO emp2(eid) VALUES (NULL); -- 因性失败 INSERT INTO emp2(eid) VALUES (101), (101); -- 因唯一性失败 ``` ### 💎 总结 MySQL主键通过**强制唯一性**,确保了每行数据的可标识性。这是关系型数据库实现数据完整性的基石机制[^1][^2][^3]。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑大钱呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值