Database design 每个桌子真的需要PK吗?

Database design 每个桌子真的需要PK吗?,database-design,Database Design,我正在创建一个数据结构,其中一个表没有任何定义的唯一性 它是一个用于保存付款条目的表(因此两个条目可以相同) 它将以一对多的方式进行链接。i、 e.返回账号=x的所有行 它将用于显示,无更新或删除,仅用于插入 我停下来考虑这张桌子是否需要一把主键,我的大学坚决要求每一张桌子都要有主键。所以他添加了一个递增的id(使用序列) 对我来说这意味着 有一个序列在使用资源,但实际上没有贡献任何东西。 在表上创建的索引永远不会使用,但会产生开销。 如果我需要在紧急情况下删除一行,我可以使用内置的rowid

我正在创建一个数据结构,其中一个表没有任何定义的唯一性

它是一个用于保存付款条目的表(因此两个条目可以相同)

它将以一对多的方式进行链接。i、 e.返回账号=x的所有行

它将用于显示,无更新或删除,仅用于插入

我停下来考虑这张桌子是否需要一把主键,我的大学坚决要求每一张桌子都要有主键。所以他添加了一个递增的id(使用序列)

对我来说这意味着 有一个序列在使用资源,但实际上没有贡献任何东西。 在表上创建的索引永远不会使用,但会产生开销。 如果我需要在紧急情况下删除一行,我可以使用内置的rowid

我知道桌子上应该有PK,但每个桌子真的需要PK吗?我错过什么了吗?
谢谢您的时间。

这是一种常见的做法,是的。是的,这是数据规范化的一部分

但有时为了正确地存储数据并让上层按原样读取数据,必须进行非规范化处理。所以答案是不,这不是一个银弹


只要试着使用索引来增强查询,并正确地设计数据库(如果可用,识别正确的PK/FK),以适当的方式进行规范化,以容纳应用程序的控件和需求。

几乎可以肯定,您的表需要一个主键。身份证号码不是答案

主键主键或其等价物。(例如,
非空唯一约束。)

如果没有id号你无法区分一件事物和另一件事物,那么你就无法用id号区分一件事物和另一件事物

如果没有一个键,一个付款条目表可能会变成这样

account_id  payment_type  payment_amount
--
10167       cash          $10.00
10167       cash          $10.00
10167       cash          $10.00
10167       cash          $10.00
关于付款的常见问题可能包括

  • 账户10167已经支付了多少款项
  • 账户10167已经支付了多少
你可能想回答“4”和40美元。但其中两个条目是重复的。(可能是编程错误。有时我会被“你好,世界”挑战。你不能指望我总是把这些复杂的东西做好。)

如果你把我原来的表格改成一个id号,你最终会得到这个

id    account_id  payment_type  payment_amount
--
1     10167       cash          $10.00
2     10167       cash          $10.00
3     10167       cash          $10.00
4     10167       cash          $10.00

你仍然看不出有两个重复的条目。

让我提供一个更哲学的观点

表只是关系的物理表示。任何给定的元组最多只能在一个关系中存在一次(关系是一个集合,一个元素可以属于集合,也可以不属于集合;它不能属于多个集合)

由于没有键,因此无法区分各行,因此可能会有多个物理行表示同一逻辑元组。您没有向系统添加任何有用的信息,只是在浪费空间


在您的特定情况下,无键表的逻辑含义

account   amount
123       $10.00
…与(例如)完全相同

如果你真的想知道,
$10.00
被支付到账户
123
4次,为什么不让

account   amount    count
123       $10.00    4
…并将
{account,amount}
作为一个键?理论上,通过将现有列放入键中并添加计数,始终可以将无键表转换为键控表


但在实践中,你可能不太关心某一特定金额的支付次数——你关心的是支付的顺序和/或时间(以及最终是否有一个正确的金额)。那么,为什么不把一个键建立在这个基础上呢?

这取决于你对坚持关系理论的要求有多严格。@PaulG-听说过吗?为什么你想在一个表中有重复的数据?数据库是命题(事实)的集合。两次陈述同一事实并不能使这一事实更加真实。重复只会导致歧义、不准确,并使数据操作更复杂,更容易出错。总之。。添加代理PK并不能修复糟糕的设计:p然而,这不是真的:“如果没有id号就无法区分一行和另一行,那么就无法用id号区分一行和另一行。”根据定义,所有PK都是候选键,因此可以“唯一标识记录”(与任何候选键一样)并且可以用作FK目标。但是,代理PKs可能仍然无法正确地覆盖问题/模型,如示例所示。@pst:Right。代孕本质上意味着“替代或代替”——代孕母亲代替自然母亲分娩。严格来说,代理密钥必须取代自然密钥。没有自然密钥,也没有代理密钥。再多一个无意义的整数。代理键仍然可以是候选键。在自动递增的情况下,它会向列添加一个“标识”(这是一个CK,因为每个RS的值都是唯一的),但不一定是适当的语义信息。。我同意代理自动PK不会修复糟糕的设计。@pst:识别行和识别行所代表的东西之间有区别。识别一行很简单(它是SQL,不是关系型的);识别行所代表的内容可能是一个问题。我同意这个结论。。只是没有具体的措辞。但是,如果可以的话,我会再加一个+1。我不同意这里的“逻辑意义”。。但我喜欢结尾的一段,它谈到了添加不同的(期望的)信息。@pst关系的数学概念和表的物理概念之间有区别。如果您将上述内容视为一种关系,则它们是相同的。如果你仅仅把它看作一个表,那么它们是不同的,但是我们不再处于关系模型的范围之内……啊,是的。不过,在帖子中(对我来说)似乎不太清楚:(
account   amount    count
123       $10.00    4