在关系数据库中,数据存储是通过表格形式进行的,每张表由多条记录组成,而每条记录由多个字段构成。正确设计表的主键和保证记录的唯一性是关系数据库设计中的关键部分。在本节中,我们将详细探讨如何选取和使用主键,以及如何确保数据表中的每条记录是唯一的。
1. 记录与字段的定义
1.1 记录(Record)
在关系数据库中,每一行数据都被称为一条 记录(Record)。例如,假设我们有一个学生表 students
,其包含以下两行记录:
id | class_id | name | gender | score |
---|---|---|---|---|
1 | 1 | 小明 | M | 90 |
2 | 1 | 小红 | F | 95 |
每一条记录都由若干字段组成。字段(Column)是表中数据的具体类型,例如学生表中的“姓名”字段或“成绩”字段。在关系数据库中,所有记录的字段定义是相同的。
2. 唯一性与主键设计
2.1 唯一性约束
在关系数据库中,所有记录必须具有唯一性。也就是说,表中不能有完全相同的两条记录。为了保证这一点,我们通常使用一个特殊的字段来唯一标识每一条记录,这个字段被称为 主键(Primary Key)。
主键 的作用是确保表中的每一条记录都能够通过某个字段或字段组合唯一地标识。例如,假设我们将学生表中的 name
字段作为主键,那么每个学生的名字将唯一地对应一条记录。然而,这样的设计并不完美,因为数据库不能存储同名的学生。因此,我们通常使用更加合适的字段来设计主键。
2.2 主键的选取原则
主键应该具有以下特性:
-
唯一性:每条记录必须能够通过主键字段唯一标识。
-
不可修改性:一旦记录插入到表中,主键字段的值最好不进行修改,因为主键用于定位记录,修改主键会导致一系列的复杂问题。
-
不含业务信息:主键不应包含任何与业务相关的字段。原因在于,业务字段(如身份证号、手机号等)可能会发生变化,而修改主键会影响到整个系统的稳定性。
例如,假设将 身份证号 或 手机号 作为主键来标识学生记录。这些字段虽然能够保证唯一性,但若有某些特殊情况需要变更(例如手机号或身份证号错误),将导致主键修改,从而影响数据库设计和相关联的表数据。
2.3 理想的主键设计
在设计主键时,最好选择一个 业务无关的字段。常见的主键字段通常为一个自动生成的唯一标识符,比如:
-
自增整数类型:数据库自动为每一条记录分配一个自增的整数值,避免手动生成主键,且能保证主键的唯一性。
-
全局唯一的GUID(或UUID):这种主键由计算机根据网卡MAC地址、时间戳、随机数等信息生成,确保其全局唯一。GUID的格式类似于
8f55d96b-8acc-4636-8cb8-76bf8abc2f57
。
对于大多数应用而言,自增整数类型的主键已经足够满足需求。例如,在 students
表中,我们通常将主键设置为 BIGINT NOT NULL AUTO_INCREMENT
类型。
2.4 主键数据类型选择
如果使用 INT
类型作为主键,表的记录数会有一个限制,即最多可存储约 21 亿条记录(2,147,483,647)。当表的记录数超过这个上限时,系统会报错。为了避免这种问题,通常会选择 BIGINT
类型作为主键,这样可以支持约 922 亿亿条记录。
3. 联合主键设计
3.1 什么是联合主键
在某些情况下,单一字段可能不足以唯一标识一条记录。此时,可以选择多个字段的组合来作为主键,这种主键称为 联合主键。联合主键的作用是通过多个字段的组合来确保记录的唯一性。
例如,我们有一个表,其中包含 id_num
(身份证号码)和 id_type
(证件类型)字段,如果将这两个字段组合起来作为联合主键,那么它们的组合将唯一标识一条记录:
id_num | id_type | other columns... |
---|---|---|
1 | A | ... |
2 | A | ... |
2 | B | ... |
在这种情况下,id_num
和 id_type
两列的组合才构成唯一主键,因此,表中的数据可以允许 id_num
字段重复,但只要 id_type
不同,就可以有不同的记录。
3.2 联合主键的使用考虑
尽管联合主键能够保证记录的唯一性,但通常情况下,我们应避免使用联合主键。原因是联合主键会增加数据库表设计的复杂度,特别是在关联查询和外键约束时,会带来额外的维护成本。因此,除非业务需求非常特殊,我们通常建议使用单一字段作为主键。
4. 小结
-
主键 是关系数据库中每条记录的唯一标识。
-
主键的选取应遵循两个原则:不使用业务字段作为主键,避免使用可能会变更的字段。
-
推荐使用 自增整数类型 或 GUID 作为主键类型。
-
联合主键 虽然可以使用,但应谨慎采用,因为它会使表设计更加复杂。
掌握了如何正确选择和使用主键之后,我们可以确保关系数据库的设计既符合业务需求,又具备良好的性能和可维护性。在接下来的课程中,我们将继续深入探讨SQL的其他重要功能,帮助你更好地理解和使用关系数据库。