我正在设计一个数据库表结构。假设我们需要记录来自不同公司的员工档案。我们有以下字段:
+---------+--------------+-----+--------+-----+
| 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'
为了实现这个要求,我的策略是将所有数据存储在一个表中,这个表易于阅读和理解。但是我注意到搜索可能需要很长时间,因为查询可能需要迭代所有行。我想尽快检索这些信息。会有更好的策略吗?
答案 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上会出现问题。我也不会说“全部”而是“几乎所有”,因为有时候违反这条规则是好的。
无论如何,拥有一个标识行简化了一些事情,它提供了一个围绕键的抽象,以防你出错。复合键提供了一些问题,这些问题最终会占用时间(并可能导致停机时间)。其中包括:
因此,根据您的数据库,您应该指定一个唯一的辅助密钥,或者将您的自然主键分开(您应该这样做取决于存储和实现细节)。