mysql菜鸟教程
8.1 主键(PRIMARY KEY)唯一标识
在现实生活中,每个人都有一个唯一的身份证号,每个学生都有一个唯一的学号,每个订单都有一个唯一的订单号。在数据库的世界里,主键(PRIMARY KEY) 就是扮演这个角色的核心概念——它是表中用于唯一标识每一行数据的列或列的组合。
一、主键的核心作用
为什么需要主键?
唯一标识:确保表中每行记录都能被唯一地找到。就像身份证号能唯一确定一个人。
数据完整性:防止表中出现重复的记录,保证数据的准确性。
快速查找:主键会自动创建索引,基于主键的查询速度极快。
建立关系:主键是与其他表建立关联(外键)的基础。
主键必须具备的特性
二、主键的创建方式
在 MySQL 中,可以在创建表时定义主键,也可以在表创建后添加。我们来看看几种常见的方式。
1. 单列主键(列级约束)
直接在列定义后面添加 PRIMARY KEY 关键字:
CREATE TABLE students ( id INT PRIMARY KEY, -- 将 id 设为主键 name VARCHAR(50) NOT NULL, age TINYINT );
这种方式简洁明了,适合单列主键。
2. 单列主键(表级约束)
在列定义结束后,单独声明主键:
CREATE TABLE students ( id INT, name VARCHAR(50) NOT NULL, age TINYINT, PRIMARY KEY (id) -- 表级约束定义主键 );
表级约束可以为主键指定名称(可选):
CREATE TABLE students ( id INT, name VARCHAR(50) NOT NULL, PRIMARY KEY pk_student_id (id) -- 为主键起名 pk_student_id );
3. 复合主键(多列组合主键)
当单列不足以唯一标识一行时,可以用多列组合作为主键。例如,订单明细表中,同一订单号下可能有多个商品,但订单号+商品号的组合可以唯一确定一行:
CREATE TABLE order_details ( order_id INT, product_id INT, quantity INT, price DECIMAL(10,2), PRIMARY KEY (order_id, product_id) -- 复合主键 );
注意:复合主键的每一列都不能为 NULL,且组合值必须唯一。
4. 建表后添加主键
如果表已经创建,可以使用 ALTER TABLE 添加主键:
ALTER TABLE students ADD PRIMARY KEY (id);
但要注意,添加主键前必须保证该列没有重复值和 NULL 值,否则操作会失败。
5. 删除主键
ALTER TABLE students DROP PRIMARY KEY;
删除主键时要小心,如果该主键被其他表的外键引用,需要先处理外键。
三、自增主键(AUTO_INCREMENT)
实际开发中,最常用的主键类型是自增整数主键。使用 AUTO_INCREMENT 属性,数据库会自动为每行生成一个唯一的递增值,省去了手动赋值的麻烦。
语法示例
CREATE TABLE students ( id INT AUTO_INCREMENT PRIMARY KEY, -- 自增主键 name VARCHAR(50) NOT NULL );
插入数据时,可以不为 id 指定值,或指定为 NULL 或 0,数据库会自动填充:
INSERT INTO students (name) VALUES ('张三'); -- id 自动生成 1
INSERT INTO students VALUES (NULL, '李四'); -- id 自动生成 2
INSERT INTO students VALUES (0, '王五'); -- id 自动生成 3(0 也会触发自增)自增的细节
默认起始值为 1,步长为 1。
删除最大记录后,新记录不会复用被删除的值(除非手动重置)。
可以使用 LAST_INSERT_ID() 函数获取最后生成的 ID。
可以手动设置自增起始值:ALTER TABLE students AUTO_INCREMENT = 1000;
四、主键选择策略:用自然键还是代理键?
在设计主键时,有两种常见的选择:
推荐做法
首选代理键:绝大多数情况下,使用自增整数作为主键是最稳妥的选择,尤其适合 OLTP 系统。
慎用自然键:除非你能保证该业务属性绝对唯一、永不改变、且长度适中(如国家代码、某些唯一编码)。
复合主键:尽量少用,除非逻辑上确实需要(如多对多关系的中间表)。复合主键可能导致索引变大,查询复杂度增加。
五、主键使用注意事项
主键列不能为 NULL:这是基本要求,插入时必须提供值(自增列会自动生成)。
不要频繁更新主键:主键是其他表引用它的基础,更新主键会引发连锁反应(外键更新),应尽量避免。
主键不宜过长:主键会在索引中存储,过长的主键(如 UUID 字符串)会占用大量空间,影响性能。推荐使用整数类型。
每个表只能有一个主键,但可以有多个唯一索引(UNIQUE)。
主键会自动创建索引,所以基于主键的查询很快。
六、实战练习
创建一个 users 表,使用自增主键 id,包含 username(唯一)、email、created_at 字段。
创建一个 courses 表,使用课程编号 course_code(如 'CS101')作为自然主键。
创建一个 student_course 表(学生选课表),使用复合主键 (student_id, course_id),并插入一些示例数据。
尝试向 students 表插入两条相同 id 的数据,观察错误。
删除某个表的主键,然后再重新添加。
主键要点总结
主键是数据库设计的核心,一个设计良好的主键能让后续的数据操作和关系建立事半功倍。记住:每个表都应该有一个主键,这是数据完整性的第一条法则。

发表评论
所有评论