2012-07-18 63 views
3

我正在创建一个数据结构,其中一个表没有任何明确的唯一性。每桌真的需要PK吗?

这是一个表来保存付款项(这样两个条目可能是相同的)

将被链接但在一个一对多的基础。即返回其中帐号= X

将用于显示时,不更新或删除只插入所有行。

我停下来考虑,如果该表需要一个主键,我的大学是坚定的,每个表都应有一个主键,不管是什么。所以他添加了一个递增的ID(使用序列)。

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

我知道表应该有PK,但是每个表真的需要一个吗?我错过了什么吗? 谢谢你的时间。

+1

这取决于你想坚持关系理论有多严格。 – Oded 2012-07-18 20:50:34

+1

@PaulG - 听说过[Cargo cult programming](http://en.wikipedia.org/wiki/Cargo_cult_programming)? – Oded 2012-07-18 20:53:33

+2

为什么你想要在表中有重复的数据?数据库是命题(事实)的集合。两次陈述相同的事实并不会使事实更加真实。复制只会导致不明确,不准确,并且会使数据操作更加复杂并容易出错。 – sqlvogel 2012-07-18 21:17:05

回答

0

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

但有时你必须以正确存储数据,让上层读它,因为它是反规范化。所以答案是否定的,这不是一个银弹。

刚刚尝试使用索引来提高查询和设计你的DB(确定适当的PK/FK如果可用),在保持控制和您的应用程序的需要作出适当的方式正常化。

2

你的表几乎肯定需要一个主键。而身份证号码不是答案。

的主键它的等效。 (A NOT NULL UNIQUE约束,例如)。

如果无法区分不同的东西没有一个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.00。但其中两个条目是重复的。 (编程错误,可能有些日子我受到“你好,世界”的挑战,你不能指望我一直得到这个复杂的东西)

如果你改变了我的原始表格以取得一个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 

而你仍然不能说有两个重复的条目。

+0

总之..添加一个代理PK并不能修复一个不好的设计:但是,这不是真的:“如果你不能区分一行与另一个没有id号的行,那么你不能区分一行和另一行与一个身份证号码。“根据定义,* all * PKs是候选键,因此可以“唯一标识一个记录”(与任何候选键一样多),并且可以用作FK目标。但是,代理PK仍然可能无法正确覆盖问题/模型,如示例中所示。 – 2012-07-18 21:08:40

+0

@pst:对。 *代孕*本质上是指“代替或代替” - 代孕母亲代替自然母亲分娩。严格来说,代理键必须取代自然键。没有自然钥匙,没有代理钥匙。再多一个毫无意义的整数。 – 2012-07-18 21:13:04

+0

代理键仍然可以是候选键。在自动递增网络的情况下,它为列添加“身份”(这是一个CK,因为每个RS的值是唯一的),但不一定是适当的语义信息。我同意代理自动PK赢得' t修复了一个糟糕的设计。 – 2012-07-18 21:16:33

1

让我提供的观点更哲学的角度...

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

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


在你的特殊情况,一无钥匙表的逻辑含义...

account amount 
123  $10.00 

...是完全一样(例如)...

account amount 
123  $10.00 
123  $10.00 
123  $10.00 
123  $10.00 

如果你真的想知道$10.00支付占123 4倍,为什么不只是有...

account amount count 
123  $10.00 4 

...并使{account, amount}一个关键?理论上,通过将现有列放入一个键并添加一个计数,您始终可以将无键表转换为键控表。

但实际上,您可能并不太在乎多少次付款 - 您关心付款的顺序和/或付款时间(以及最后有正确的金额)。那么为什么不在这个基础上设置密钥呢?

+0

我不同意这里的“逻辑含义”,但我喜欢最后谈到添加不同(所需)信息的那一点。 – 2012-07-18 22:15:07

+1

@pst关系的数学概念和表格的物理概念是有区别的。如果您将上述视为关系,则它们是相同的。如果你把它看作一张表,那么它们就不一样了,但那么我们就不再处于关系模型的范围之内了...... – 2012-07-18 22:21:58

+0

啊是的。在帖子中虽然对我来说似乎不是很清楚 – 2012-07-19 00:14:07