将日期字段作为主键的一部分包含哪些优缺点?
答案 0 :(得分:9)
考虑零件库存表 - 如果您想在每天结束时存储库存水平,那么part_id和date_of_day上的复合主键就可以了。您可以选择使其成为唯一键并添加合成主键,特别是如果您有一个或多个表使用外键约束引用它,但除此之外没有问题。
所以没有什么不一定是错的,但是像任何其他方法一样,它可以像帕特里克的例子那样被错误地使用。
编辑:这是另一个要添加的评论。
我想起了我刚才写过的关于数据库中的日期值是真的是自然的还是合成的。日期为“YYYY-MM-DD”的可读表示当然是自然的,但在Oracle内部,它存储为一个数字,只表示Oracle的特定日期/时间。我们可以随时选择和更改该内部值的表示(对于不同的可读格式,或完全不同的日历系统),而内部值不会失去其作为 特定日期和时间的含义。我认为在此基础上,DATE数据类型介于自然和合成之间。
答案 1 :(得分:4)
我很好,它是密钥的一部分,但是会补充说你还应该有一个自动递增序列号作为PK的一部分,并强制将任何日期作为UTC写入数据库,下游系统比转换到当地时间。
我工作的系统决定,每当触摸另一个表时,让Oracle触发器写入数据库是个大主意,并使sysdate成为没有序列号的主键的一部分。唯一的问题是,如果您运行的更新查询每秒多次击中该行,则会破坏记录更改的表上的主键。
答案 2 :(得分:4)
如果你已经决定使用'自然'主键,那么问题是:日期是主键的必要部分,或者不是 - 优点/缺点是不相关的!
答案 3 :(得分:3)
关于使用日期作为主键的一部分,我会问一些问题。
日期是否包含时间部分?这使事情变得棘手,因为时间包括时区和夏令时。这不会改变日期/时间值,但在根据查询排序或检索值方面可能会产生意外结果。
我非常相信使用代理键(即使用序列列作为主键)而不是自然键(比如使用日期)。
答案 4 :(得分:2)
稍微认为它不像其他标识符那样优雅。
(例如,对同事说,请你看看记录475663比说话请容易,请你看看2008-12-04 19:34:02)
在不同的语言环境中,还存在因不同日期格式混淆的风险
(例如,2008年3月4日 - 2008年4月3日在欧洲,2008年3月4日在美国)
(我的首选是使用单独的键列)
答案 5 :(得分:2)
一如既往..这取决于。
您在PK中包含日期/时间列的目的是什么?它是否提供有关记录的其他信息而无需实际选择行?
我可以预见的主要问题是显而易见的问题,即您使用UTC日期还是本地日期?日期是否会被误解(有人认为这意味着它意味着UTC的当地时间)?正如其他一些人所说,这可能更好地用在代理/复合键中?在主键之外的键或索引中使用它可能会更好。
[旁注]这让我想起了(1) COMB(组合GUID)背后的理论,虽然这里的想法是为PK创建一个唯一的ID,SQL Server更好地索引/需要更少的索引重建,而不是在一行中添加任何有意义的日期/时间值。
(1)[http://www.informit.com/articles/article.aspx?p=25862&seqNum=7]
答案 6 :(得分:2)
日期是完美的主键,只要它们作为自然键的一部分有意义。我会在表格中使用日期:
(在上面添加代理员employee_salary_id会有什么意义?)
对于某些表格,可以使用日期,但其他东西作为主键更有意义,例如:
我们可以使用(room_no,booking_from_date)或(room_no,booking_to_date),但是参考对于与客户端等进行通信更有用。我们可能会将这些变为UNIQUE约束,但实际上我们需要更复杂的“否”重叠“检查这些。
答案 7 :(得分:0)
作为主键的唯一或第一个组件的日期会导致具有高插入的表的性能问题。 (表格需要经常重新平衡)。
如果每个日期插入多个插件,通常会导致问题。
在大多数情况下,我认为这是一种难闻的气味,并建议反对它。
答案 8 :(得分:0)
这没有什么特别的错误,但正如其他海报所指出的那样,你可能会遇到时区和当地人的问题。此外,您最终可能会使用大量的DATE()函数来表示您的SQL。
如果它像前面提到的那样是库存,那么您可以考虑使用像“20081202”这样的八字符文本字段作为主键的第二部分。这样可以避免出现时区区域设置问题,并且如果需要,可以很容易地转换为实际日期。
请记住,主键有两个功能,可以单独识别记录并强制执行唯一性。代理主键不需要。
答案 9 :(得分:0)
可能很难引用。我遇到了_ID + _Date作为复合PK。此组合键也是另一个表中的引用/ FK。
首先,这纯粹是令人困惑,因为存在_ID暗示了一个非复合密钥。
第二次使用SYSDATE插入主表,并且需要找出该SYSDATE中的准确时间。 在引用它时,您需要精确了解其中的时间。否则,它将无法正常工作...
答案 10 :(得分:-2)
使用日期作为主键的一部分可能会使表上的连接速度明显变慢。如果需要,我更喜欢代理密钥,然后是日期的唯一索引。