# DBMS 中的主键

> 原文： [https://beginnersbook.com/2015/04/primary-key-in-dbms/](https://beginnersbook.com/2015/04/primary-key-in-dbms/)

**定义**：**主键**是表中唯一标识该表中元组（行）的一组最小属性（列）。

## DBMS 中的主键示例

让我们举一个例子来理解主键的概念。在下表中，有三个属性：`Stu_ID`，`Stu_Name`和`Stu_Age`。在这三个属性中，一个属性或一组多个属性可以是主键。

单个属性`Stu_Name`不能是主键，因为多个学生可以拥有相同的名称。

单个属性`Stu_Age`不能成为主键，因为不止一个学生可以拥有相同的年龄。

单个属性`Stu_Id`是主键，因为每个学生都有一个唯一的 ID，可以识别表中的学生记录。

**注意：**在某些情况下，单个属性不能唯一地标识表中的记录，在这种情况下，我们尝试查找可以唯一标识表中的行的一组属性。在这个例子之后我们将看到它的例子。

**表名：`Student`**

| `Stu_Id` | `Stu_Name` | `Stu_Age` |
| --- | --- | --- |
| 101 | Steve | 23 |
| 102 | John | 24 |
| 103 | Robert | 28 |
| 104 | Steve | 29 |
| 105 | Carl | 29 |

## 有关主键的注意事项

*   我们通常用下划线表示属性名称（列名）。
*   对于表的每一行，主键的值应该是唯一的。生成键的列不能包含重复值。
*   标记为主键的属性不允许具有空值。
*   主键不一定是单个属性（列）。它可以是一组多个属性（列）。例如`{Stu_Id, Stu_Name}`可以共同识别上表中的元组，但是我们不选择它作为主键，因为单独`Stu_Id`就足以唯一地标识表中的行而我们总是去最小的集合。话虽如此，只有当没有可以唯一标识表中的元组的单个列时，我们才应该选择多个列作为主键。

## 主键的另一个示例 - 多个属性

考虑这个表`ORDER`，该表保存了客户购买的每日记录。该表有三个属性：`Customer_ID`，`Product_ID`和`Order_Quantity`。

`Customer_ID`单独不能成为主键，因为单个客户可以下多个订单，因此多于一行拥有相同的`Customer_ID`值。正如我们在以下示例中看到的那样，客户 ID 1011 已经为产品（如果是 9023 和 9111）下了两个订单。

单独`Product_ID`不能成为主键，因为不止一个客户可以为同一产品下订单，因此多个行具有相同的产品 ID。在下表中，客户 ID 1011 和 1122 为同一产品（产品编号 9023）下订单。

单独使用`Order_Quantity`不能成为主键，因为不止一个客户可以让订单具有相同的数量。

由于没有一个属性能够成为主键，因此我们尝试创建一组属性作为主键。

`{Customer_ID, Product_ID}`一起可以在表中唯一地标识行，因此该集合是该表的主键。

**表名：`ORDER`**

| `Customer_ID` | `Product_ID` | `Order_Quantity` |
| --- | --- | --- |
| 1011 | 9023 | 10 |
| 1122 | 9023 | 15 |
| 1099 | 9031 | 20 |
| 1177 | 9031 | 18 |
| 1011 | 9111 | 50 |

**注意：**在为主键选择一组属性时，我们总是选择具有最小属性数的最小集合。例如，如果有两个集合可以标识表中的行，则应选择具有最小属性数的集合作为主键。

## 如何在 RDBMS 中定义主键？

在上面的示例中，我们已经有了一个包含数据的表，我们试图了解主键的用途和含义，但是您应该知道通常我们在创建表时定义主键。我们也可以稍后定义主键，但在现实场景中很少发生。

假设我们要创建上面讨论过的表，其中客户 ID 和产品 ID 设置为主键。我们可以在 SQL 中这样做：

```
Create table ORDER
(
    Customer_ID int not null,
    Product_ID int not null,
    Order_Quantity int not null,
    Primary key (Customer_ID, Product_ID)
)
```

假设我们在创建表时没有定义主键，那么我们可以在以后定义它：

```
ALTER TABLE ORDER
ADD CONSTRAINT PK_Order PRIMARY KEY (Customer_ID, Product_ID);
```

**另一种方式：**

当我们只有一个属性作为主键时，就像我们在`STUDENT`表的第一个例子中看到的那样。我们也可以像这样定义键：

```
Create table STUDENT
(
    Stu_Id int primary key,
    Stu_Name varchar(255) not null,
    Stu_Age int not null
)
```