在数据库的世界里,主键就如同每个人的身份证号码,是表中每一行数据的唯一标识,它确保了数据的完整性和可追溯性,是构建稳定、高效数据库系统的基石,理解并正确创建主键,是每一位数据库设计者和开发者的必备技能。

主键的核心原则
在深入探讨如何创建主键之前,我们必须先理解它所必须遵循的几个核心原则:
- 唯一性:主键值在整个表中必须是唯一的,不能有任何两行数据拥有相同的主键值。
- 非空性:主键列不能包含NULL值,每一行都必须有一个明确的主键值。
- 稳定性:主键值一旦确定,就不应该被随意更改,频繁更改主键会导致数据关系混乱和性能下降。
创建主键的常用方法
在不同的场景下,我们可以采用不同的SQL语句来创建主键,主要分为两大类:在创建新表时定义,以及在已有表上添加。
在创建表时直接定义
这是最直接、最常见的方式,具体实现上,又可以分为列级定义和表级定义。
列级定义
将主键约束直接写在列的定义之后,这种方式简单明了,适用于单列作为主键的情况。
-- 创建一张用户表,并在创建时将UserID列定义为主键
CREATE TABLE Users (
UserID INT PRIMARY KEY,
UserName VARCHAR(50) NOT NULL,
Email VARCHAR(100) UNIQUE
);
表级定义

将主键约束作为独立的子句,放在所有列定义之后,这种方式更具灵活性,尤其适用于定义由多个列共同组成的复合主键。
-- 创建一张订单明细表,使用OrderID和ProductID作为复合主键
CREATE TABLE OrderDetails (
OrderID INT,
ProductID INT,
Quantity INT,
Price DECIMAL(10, 2),
PRIMARY KEY (OrderID, ProductID) -- 在表级定义复合主键
);
为已存在的表添加主键
在实际开发中,我们可能会遇到需要为一张已经创建但尚未设置主键的表添加主键的情况,这时,可以使用ALTER TABLE语句。
-- 假设已有一张Products表,现在为其添加主键 ALTER TABLE Products ADD PRIMARY KEY (ProductID);
在执行此操作前,必须确保ProductID列中的所有数据都是唯一且非空的,否则数据库会报错。
如何选择合适的主键:自然键 vs. 代理键
选择哪一列或哪些列作为主键,是一个重要的设计决策,通常有两种选择:自然键和代理键。
| 类型 | 描述 | 优点 | 缺点 |
|---|---|---|---|
| 自然键 | 具有业务含义的、真实存在的属性,如身份证号、邮箱地址、商品编号。 | 具有可读性,与业务逻辑直接关联。 | 可能发生变化(如用户更换手机号);可能很长,影响索引性能;可能存在业务规则导致的唯一性问题。 |
| 代理键 | 与业务无关、由系统生成的唯一标识,如自增整数、UUID。 | 稳定,永远不会变化;小巧,通常为整数,性能高;简单,无业务含义,避免了业务逻辑变更的影响。 | 无可读性;需要额外的机制来生成(如AUTO_INCREMENT)。 |
在现代数据库设计中,强烈推荐使用代理键作为主键,我们会使用一个自增的整数ID列,并通过AUTO_INCREMENT(MySQL)或IDENTITY(SQL Server)等属性让它自动生成唯一值,这样可以完美地避开自然键的种种弊端,让数据库结构更加稳定和高效。
相关问答FAQs
一个数据库表可以有多个主键吗?

解答: 从严格意义上讲,一个表只能有一个主键约束,这个主键约束可以由多个列(字段)共同组成,这种情况我们称之为“复合主键”,在一个选课表中,学号和课程号的组合可以唯一确定一条选课记录,此时(学号, 课程号)就是这个表的复合主键,它虽然涉及两列,但在逻辑上仍然是一个主键约束。
主键和唯一索引有什么区别?
解答: 主键和唯一索引都保证了数据的唯一性,但存在几个关键区别:
- 数量限制:一个表只能有一个主键,但可以有多个唯一索引。
- 非空约束:主键列绝对不允许为NULL值,而唯一索引在某些数据库系统(如MySQL)中,可以允许多个NULL值的存在(因为NULL被认为不等于任何值,包括另一个NULL)。
- 功能定位:主键是表的逻辑标识,它不仅保证了唯一性,还常常作为外键的参照,是表关系模型的核心,而唯一索引更多是出于性能优化和保证数据某一列唯一性的目的。
- 创建方式:主键是一种约束,而唯一索引既是一种约束,也是一种索引对象,在创建主键时,数据库会自动为其创建一个唯一索引。