我正在尝试在 MSSQL 2005 中为我的公司设置电话列表。
我拥有的当前架构有效,但我想在名为“EmployeeCompany”的员工表中添加一个列,并让它从部门的“CompanyName”列中提取。
如果 Department 表中的 CompanyName 不是 PK,我将如何链接这两列?
任何帮助是极大的赞赏。
谢谢你,CJ
我正在尝试在 MSSQL 2005 中为我的公司设置电话列表。
我拥有的当前架构有效,但我想在名为“EmployeeCompany”的员工表中添加一个列,并让它从部门的“CompanyName”列中提取。
如果 Department 表中的 CompanyName 不是 PK,我将如何链接这两列?
任何帮助是极大的赞赏。
谢谢你,CJ
如果你知道员工的部门,你知道部门的公司,那么你也知道员工的公司。您可以将其表示为 SQL 中的简单 JOIN,如果您希望简化客户端代码,甚至可以将此 JOIN“隐藏”在 VIEW 后面。
作为一般规则:除非您试图解决特定的性能问题,否则不应存储可以推断的数据。
让我分解一下这个思路:
但是,有一种方法可以通过“滥用”引用完整性迁移属性这一事实来同时具有冗余和完整性。达米尔回答的“案例2”解释了一种方式,让我提供另一种方式:
如您所见,外键(FKx
在上图中)不必引用主键 - 它也可以引用备用键(Ux
)。这使您可以保留Company_id
和Department_id
作为各自表的主键,并避免干扰模型的其余部分3。
1如果有两条数据描述同一事物,其中一条已更新,那么您总是有可能忘记更新另一条(例如,由于应用程序错误)。除非您可以诱使 DBMS 自己为您做这件事,如答案中所述。
2例如过多的 JOIN 或昂贵的聚合。
3即可能引用公司或部门的其他表格。
案例 1——使用 ID
案例 2——自然的复合键
在部门表中,您存储的company_id
是键,而不是company name
.
当你想查询员工所在的公司时,你可以这样做:
SELECT
LastName,
FirstName,
CompanyName
FROM
Employee
INNER JOIN Department ON employee.department_id = department.department_id
INNER JOIN Company ON department.company_id = company.company_id
我将创建第三个名为 Company 的表,它有两列 - CompanyId(主键)和 CompanyName。然后我会使用 CompanyId 作为 Department 中的外键,然后使用 DepartmentId 作为 Employee 中的外键。