代码之家  ›  专栏  ›  技术社区  ›  rich

数据库设计-是否应将日期用作主键的一部分

  •  13
  • rich  · 技术社区  · 16 年前

    将日期字段作为主键的一部分有哪些优点/缺点?

    10 回复  |  直到 16 年前
        1
  •  9
  •   Rosh_LK    8 年前

    考虑一个零件库存表——如果您想在每天结束时存储库存水平,那么可以在零件ID和日期上使用组合主键。您可以选择将其设为唯一键并添加合成主键,特别是如果有一个或多个表使用外键约束引用它,但除此之外,没有问题。

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

    编辑:这是另一条评论。

    我想起不久前写的一篇文章,主题是数据库中的日期值到底是自然值还是合成值。日期的可读表示形式“yyyy-mm-dd”当然是自然的,但在oracle内部,它存储为一个数字,只表示oracle的特定日期/时间。我们可以在任何时候选择和改变内部价值的表示(完全不同的可读格式,或完全不同的日历系统),而不丧失其内在价值。 那个 特定的日期和时间。我认为在此基础上,数据类型介于自然数据和合成数据之间。

        2
  •  4
  •   Patrick Harrington    16 年前

    我同意它是键的一部分,但我要补充的是,您还应该有一个自动递增的序列号作为主键的一部分,并强制将任何日期作为UTC写入数据库,下游系统不转换为本地时间。

    我工作的一个系统决定,一旦碰到另一个表,就有一个Oracle触发器写入数据库,并使SysDead成为没有序号的主键的一部分,这将是一个伟大的想法。唯一的问题是,如果您运行的更新查询每秒命中该行不止一次,则它会打断正在记录更改的表的主键。

        3
  •  4
  •   Steven A. Lowe    16 年前

    如果您已经决定使用“自然”主键,那么问题是:日期是主键的必要部分吗,还是不是-正反不相关!

        4
  •  3
  •   Thomas Jones-Low    16 年前

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

    日期包括时间部分吗?这使得事情变得棘手,因为时间包括时区和日光节约。这不会更改日期/时间值,但在基于查询排序或检索值时可能会产生意外结果。

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

        5
  •  2
  •   cagcowboy    16 年前

    一个小小的缺点是它不像其他标识符那样优雅

    (例如,对一个同事说,请你看一下记录475663比说“容易”好吗?

    在不同的地区,不同的日期格式也有混淆的风险。

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

    (我的偏好总是使用单独的键列)

        6
  •  2
  •   RobS    16 年前

    一如既往。这取决于。

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

    我可以预见的主要问题是显而易见的问题,即使用UTC日期还是本地日期?日期是否会被曲解(有人会认为它意味着当地时间,而它意味着UTC)?正如其他一些人建议的那样,这可能更好地用于代理项/组合键?在主键以外的键或索引中使用它可能对性能更好。

    [旁注]这让我想起了 (1) COMB (组合GUID)虽然这里的想法是为PK创建一个唯一的ID,但SQL Server更好地索引/要求更少的索引重建,而不是向行添加任何有意义的日期/时间值。

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

        7
  •  2
  •   Tony Andrews    16 年前

    日期是非常好的主键,只要它们是自然键的一部分。我会在表格中使用日期,比如:

    • 假日日期(hol_date)
    • 员工薪资(员工ID整数,薪资起始日期)

    (在上面添加代孕员工工资ID有什么意义?)

    对于某些表,可以使用日期,但作为主键的其他内容更有意义,例如:

    • 酒店房间预订(预订参考)

    我们可以使用(房间号,从预订日期开始)或(房间号,从预订日期开始)或(房间号,从预订日期到预订日期),但是参考对于与客户沟通等更有用。我们可能会将这些限制设置为唯一的限制,但事实上,我们需要对这些限制进行更复杂的“无重叠”检查。

        8
  •  0
  •   David Waters    16 年前

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

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

    在大多数情况下,我认为这是一种难闻的气味,并建议不要这样做。

        9
  •  0
  •   James Anderson    16 年前

    这没有什么特别的问题,但正如其他海报所指出的,你可能会陷入时区和当地人的问题。此外,您还可以使用许多date()函数来模糊您的sql。

    如果它类似于前面提到的当天结束时的库存,那么您可以考虑将8个字符的文本字段(如“20081202”)作为主键的第二部分。这样可以避免时区区域设置问题,并且如果需要,可以很容易地转换为实际日期。

    请记住,主键有两个函数来唯一标识记录和强制唯一性。代理主键做niether。

        10
  •  -2
  •   HLGEM    16 年前

    使用日期作为主键的一部分可能会使表上的联接明显变慢。如果需要的话,我更喜欢代理项密钥,然后是日期上的唯一索引。