【问题标题】:How to select primary keys for transaction and master tables?如何为事务表和主表选择主键?
【发布时间】:2014-06-03 18:39:25
【问题描述】:

在设计数据库时,例如假设我有名为SalaryTransEmployeeMasterAttendanceTrans 的表。假设它的规范化到第 3 范式,表字段将如下......(仅显示相关的 3 个表)

SalaryTrans (salary_id[pk], employee_id[fk], month, ..., net_salary )

EmployeeMaster (employee_id[pk], name, ...)

AttendanceTrans (attendance_id[pk], employee_id[fk], in_time, out_time, date)

注意:

salary_idattendance_id 是整数自动递增字段。

employee_id 是一个类似“OA123”的字符串。

[pk] - 主键

[fk] - 外键

问题:

  1. 我是否正确选择了主键?
  2. 我是否也应该为EmployeeMaster 使用integer 自动递增ID 字段(使employee_id 成为唯一但非主键)?
  3. 例如,在表 SalaryTrans 中,如果我将主键更改为 [employee_id + month](因为此复合键是唯一的,因为没有员工会每月获得两次薪水)
  4. 对最佳做法和标准有何建议?

【问题讨论】:

    标签: sql-server database foreign-keys primary-key entity-relationship


    【解决方案1】:

    这取决于表格的用途。 SalaryTrans 可以有一个包含employee_ID 和月份和年份的复合键。除非是为了减轻开发人员的负担,否则有一个 Salary_ID 字段似乎很愚蠢。即使两个人的薪水相同,employeeID 在表上的事实也否定了两个不同的员工可以链接到同一记录的事实,因此salary_ID 实际上不会是其他表的 FK。所以复合键似乎很好。假设我在 X 公司工作了 10 年。我每 10 年 3 月的工资都一样吗?希望不会……

    EmployeeMaster 有一个名为 employee_Id 的 PK 似乎是合理的。在这种情况下,字符串与数字一样有效,只要它是唯一的且不为空即可。我不认为添加自动号码会增加任何特别之处。 轻微性能提升,因为整数处理速度比字符串快,但除非您是亚马逊、谷歌或重载网站,否则我怀疑它现在是否足够重要。

    您会遇到与出席_Trans 相关的问题,因为当晚上 10 点到早上 6 点轮班发生时,会存储什么“日期”?此外,当人们不输入或输出时会发生什么……相当长或短的时间。或者如果有人认真投入 25 小时会发生什么?记录日期/时间和日期/时间会更好吗?

    除此之外,这行得通吗……它可以。我没有看到任何无法在这里扩展的东西。从这个设计中我可以看出,没有什么根本性的错误是无法扩展的。只是一些我可能会做出不同的选择。

    关于提出的问题:

    好的,如果我将月/年的employee_id 作为SalaryTrans 表的主键,您是否建议删除自动编号字段salary_id 或将其保留为唯一键?

    我个人会删除它;但是,如果您计划在多个事务中频繁使用这样的表而没有要引用的公共对象,那么添加使用自动编号保留主键将使这些事务的开发变得不那么困难。就我个人而言,我更喜欢使用现有字段;但我了解一些现有工具更喜欢 1 个关键列。如果您正在使用此类工具,请保留它。

    一般来说,在每个表上都有这样的字段会比较有利吗? 仅当用于开发的工具要求键为 1 个字段时。随着继任计划和其他人继承设计,这将使理解表格更容易一些。但是,请确保该字段不是由用户以任何方式维护或呈现或呈现的。自然键对用户来说是最有意义的,所以这就是我们应该呈现给他们的东西。代理键更容易让系统开发/维护,因此开发人员应该/使用它。但是,为了减少技术发言并简化与客户的沟通,我发现在开发中坚持使用自然键可以更轻松地管理需求。尽管它使开发有些复杂。我个人宁愿让我的工作更难,以简化与客户群的沟通。

    还请告诉我如何为 AttendanceTrans 表选择复合主键? employee_id + in_time_date 是否会像同一员工不能同时登录两次一样工作?还是一个 ID 字段(自动编号)会更好?

    Employee_ID + In_Time_date 可以工作,因为它不会/永远不会被复制。

    【讨论】:

    • 好的,如果我将employee_idmonth/year 作为SalaryTrans 表的主键,您是否建议删除自动编号字段salary_id 或将其保留为唯一键?一般来说,在每个表上都有这样一个字段会比较有利吗?
    • 还请告诉我如何为AttendanceTrans 表选​​择composite primary keyemployee_id + in_time_date 会以同一员工不能同时登录两次的方式工作吗?或ID 字段(自动编号)会更好吗?
    • 因为这是一个古老的问题:我想我会引导您获得更完整的回复:stackoverflow.com/questions/63090/…
    猜你喜欢
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多