复合主键:使用另一个

时间:2016-12-08 02:33:30

标签: sql database

数据字段

我正在设计一个数据库表结构。假设我们需要记录来自不同公司的员工档案。我们有以下字段:

+---------+--------------+-----+--------+-----+
| Company | EmployeeName | Age | Gender | Tel |
+---------+--------------+-----+--------+-----+

来自不同公司的两名员工可能具有相同的名称(并假设在同一家公司中没有2名员工具有相同的名称)。在这种情况下,我认为复合主键(Company, EmployeeName)是必要的。

搜索

现在我需要通过仅使用主键中的2个属性中的一个来获取所有信息。例如, 我想搜索A公司所有员工的个人资料:

SELECT EmployeeName, Age, Gender, Tel FROM table WHERE Company = 'Company A'

我还可以搜索来自不同公司Donald的所有员工:

SELECT Company, Age, Gender, Tel FROM table WHERE EmployeeName = 'Donald'

策略

为了实现这个要求,我的策略是将所有数据存储在一个表中,这个表易于阅读和理解。但是我注意到搜索可能需要很长时间,因为查询可能需要迭代所有行。我想尽快检索这些信息。会有更好的策略吗?

2 个答案:

答案 0 :(得分:1)

首先,您的行应该具有每行的唯一标识符 - identity / auto-increment / serial,具体取决于数据库。其次,您可能会重新考虑名称的独特性。为什么同一家公司的两个人不能有相同的名字?

在任何情况下,您都有一个主键,比如(company, name)。对于相反的搜索,您只需要(name, company)上的另一个索引:

create index idx_profiles_name_company on profiles(name, company);

答案 1 :(得分:0)

解释戈登关于每一行身份的建议的说明。这是对上述答案的补充。

理论上,跨越列的主键和像PostgreSQL这样的数据库中没有任何问题我喜欢将标识值作为辅助键(即非null唯一)并指定自然主键。当然在MS SQL Server或MySQL / InnoDB上会出现问题。我也不会说“全部”而是“几乎所有”,因为有时候违反这条规则是好的。

无论如何,拥有一个标识行简化了一些事情,它提供了一个围绕键的抽象,以防你出错。复合键提供了一些问题,这些问题最终会占用时间(并可能导致停机时间)。其中包括:

  1. 复合键的连接通常比简单值上的连接更贵,
  2. 添加或更改跨列的自然主键在涉及联接时要困难得多
  3. 因此,根据您的数据库,您应该指定一个唯一的辅助密钥,或者将您的自然主键分开(您应该这样做取决于存储和实现细节)。