2008-12-04 157 views

回答

4

我确定它是密钥的一部分,但会补充说你还应该有一个自动递增序列号作为PK的一部分,并强制任何日期以UTC写入数据库,下游系统比转换到当地时间。

我工作的一个系统决定,每当触摸另一个表时,让Oracle触发器写入数据库是一个好主意,并且使sysdate成为没有序列号的主键的一部分。唯一的问题是,如果您运行每秒超过一次命中行的更新查询,它会中断正在记录更改的表上的主键。

+1

UTC事物上的+1。我们的数据库不使用UTC,它会导致我们一个痛苦的世界。 – 2008-12-04 20:55:23

2

轻微CON将是它不是优雅的手柄一些其它标识符

(例如说一个同事请你可以看看记录475663是不是说请你可以看看2008-更容易一点12-04 19时34分02秒)

也有在不同的日期格式混乱的在不同的语言环境风险

(如2008年3月4日 - 2008年4月3日在欧洲,2008年3月4日在美国)

(我的首选总是使用单独的键列)

+1

ISO日期格式YYYY-MM-DD岩石! :)作为一名在美国工作的英国人,我一直把它作为妥协位置,因为即使在10年之后,MM/DD/YYYY在我的神经上像指甲一样在黑板上闪闪发光。 – 2008-12-04 19:21:33

+1

是的,我试图让每个人都使用ISO。说起来容易做起来难.... – cagcowboy 2008-12-04 19:25:12

3

有一些问题我会问有关使用日期作为主键的一部分。

日期是否包含时间部分?这使得事情变得棘手,因为时间包括时区和夏令时。这不会更改日期/时间值,但可能会在根据查询对数据进行排序或检索方面产生意想不到的结果。

我非常相信使用代理键(即使用序列列作为主键)而不是自然键(如使用日期)。

7

考虑部件库存表 - 如果要在每天结束时存储库存水平,那么part_id和date_of_day上的复合主键就可以。您可以选择创建一个唯一键并添加一个合成主键,特别是如果您有一个或多个表使用外键约束引用它时,但这一点没有问题。

所以没有什么必然的错误,但像其他任何方法一样,它可以像帕特里克的例子那样被错误地使用。

编辑:这是另一个要添加的评论。

我想起了一些我之前写过的关于数据库中的日期值是真的还是合成的主题。日期为“YYYY-MM-DD”的可读表示形式当然很自然,但在Oracle内部,这是作为一个数字来存储的,它只是表示Oracle的特定日期/时间。我们可以随时选择并更改该内部值的表示(以不同的可读格式或完全不同的日历系统),而内部值不会丢失其具体日期和时间的含义。我认为在此基础上,DATE数据类型介于自然和合成之间。

0

日期作为主键的唯一或第一个组件导致高插入表上的性能问题。 (表格需要经常重新平衡)。

如果每个日期插入多于一个,通常会导致问题。

在大多数情况下,我认为这是一种难闻的气味,并会提出反对意见。

2

一如既往..这取决于。

你在PK中包含日期/时间列的目标是什么?是否提供关于记录的附加信息而不必实际选择行?

我在这里可以预见的主要问题是显而易见的问题,即是否使用UTC日期或本地日期?日期是否会被误解(有人认为这意味着当地时间,意味着UTC)?正如其他一些人所说,这可能会更好地用于替代/复合键吗?您的性能可能会更好地用于除主键以外的密钥或索引。这个想法让我想起(1) COMB(组合的GUID)背后的理论,尽管这里的想法是为PK创建一个唯一的ID,这个ID更好地索引/索引较少索引重建,而不是将任何有意义的日期/时间值添加到行中。

(1)http://www.informit.com/articles/article.aspx?p=25862&seqNum=7]

4

,如果你已经决定使用“自然”主键,那么问题是:是日期的主键,或者不是一个必要组成部分 - 优点/缺点是不相关的!

+0

没错。任何其他的考虑都是关键的。要么区分唯一性在逻辑上是正确的,要么不是。如果是这样,无论是在自然PK中,还是应该在另一种唯一性约束中。 在FK中它几乎不会有用。 – dkretz 2008-12-04 18:48:45

+0

MMM ...永远不会在FK中有用吗?如果你PK包含它,它是IMPERATIVE它是在FK。没有选择的有用或不是,它是什么。随身携带复合键肯定更难,但它可能性更大,效果更好。 – 2008-12-04 18:59:57

0

没有什么特别的错误,但其他海报已经注意到你可能会遇到时区和当地人的问题。此外,您最终可能会有大量DATE()函数模糊您的SQL。

如前所述,如果它是一天结束时的库存,您可以考虑使用八字符文本字段,如“20081202”作为主键的第二部分。这样可以避免时区语言环境问题,并且如果需要的话,很容易转换为真实日期。

记住主键有两个功能来唯一标识记录并强制唯一性。代理主键不会。

2

日期制作完美的主键,只要它们作为自然键的一部分是有意义的。我会像表使用日期:

  • holiday_dates(hol_date日期)
  • employee_salary(EMPLOYEE_ID整数,sal_start_date日期)

(什么是添加上述替代employee_salary_id点? )

对于一些表,日期可以使用,但其他东西更有意义的主键,例如:

  • hotel_room_booking(booking_reference)

我们可以用(room_no,booking_from_date)或(room_no,booking_to_date),但一提的是与客户端等我们不妨让这些成为唯一约束通信更有用,但实际上我们需要更复杂的“不重叠”检查。

-2

将日期用作主键的一部分可能会使表上的连接速度明显变慢。如果需要的话,我宁愿选择一个代理键,然后选择一个唯一的索引。