子表的正确主键?

时间:2012-06-14 15:10:44

标签: sql-server-2008-r2 primary-key query-performance

主键在员工表中应该是什么?

Table Stores
(PK) StoreID
{other store columns}

Table Employee
StoreID
EmployeeID
{other employee columns...}

[编辑] 我们的设置是,员工将始终只属于一个商店。每个员工都应该拥有一个唯一的ID(即,即使员工属于不同的商店,他们也不应该拥有相同的ID)。

我认为PK应该只是EmployeeID,因为它应该始终是唯一的。我的同事认为PK应该与StoreID + EmployeeID复合,但是(理论上)可能会有重复的员工ID。我并不完全遵循他的推理,但他引用的一件事就是表现。我并不太担心查询性能,因为对于我们的数据库,Employee表从未超过5000条记录。我们确实有其他更大的子表引用StoreID,这是创建这样一个键的正当理由吗?

[编辑] 如果您还创建了仅在EmployeeID上强制实施唯一性的内部密钥,那么复合PK是否可以?也许有多种方法可以做到这一点,但我想选择最常用的做法。

2 个答案:

答案 0 :(得分:1)

  

我认为PK应该只是EmployeeID,因为它应该始终如此   独特。我的同事认为PK应该复杂化   StoreID + EmployeeID,但它(理论上)可能   有重复的员工ID。

你说的是两件略有不同的事情。

如果您只想 来识别员工,那么主键可能应该是employee_id,而商店的ID号根本不应该在该表中。 但是此外,如果您想知道员工通常在哪个商店工作,您可以在员工表中包含store_id(并将其设为NOT NULL),或者您可以创建一个单独的表。

在25年多的时间里,我一直在做这些事情,我经常让人们告诉我,员工只能在 一家商店工作。这几乎总是不真实的,甚至经常在经理们宣誓就职时 是真的。有一次,我们在一个有六个员工的房间里“讨论”了这个问题,他们都在一家商店工作过。其中一人每周在五家不同的商店工作。并且所有管理者都知道这一点。当我们指出所有在多家商店工作的人时,经理们仍然坚持认为每个人只在一家商店工作。 (耸肩)

我赞成使用单独的表来存储员工当前的付费工作地点。主要原因是管理始终除了只是之外还需要更多关于该关系的信息。总是。出勤,计时,总是别的。

那个表中,您需要一个至少为{store_id,employee_id}的复合主键。您可能需要更多列(有时还需要更多表),具体取决于您要存储的有关该位置关系的其他信息。您还需要某种管理程序(您可能或可能无法自动执行)以确保每个员工至少有一个当前的付费工作地点。 (如果dbms曾支持断言,则可以摆脱管理过程。)

答案 1 :(得分:1)

如果您的EmployeeID在所有商店中都是唯一的,那么它应该是该表的主键。就像你说的那样,否则你会有重复的EmployeeID。我可以看到具有StoreID + EmployeeID的唯一原因是,如果每个商店都有自己的员工编号。如果一个人在两个不同的商店工作,那么他将需要两个EmployeeID,每个商店一个。但是,从你的问题来看,我认为情况并非如此。

但是,应该使用外键关系设置StoreID,假设始终为员工分配StoreID。

此外,如果您的同事主要关注性能,您可以在表中添加EmployeeID,StoreID索引,这样可以清除任何慢速查询(如果遇到任何问题)。既然你说这个表很小,我会等到在添加索引之前出现性能问题。我认为主键始终是一个逻辑组织决策,我不会将性能视为该决定的一部分。