3

我看到的许多表设计都有一个 id 列作为主键。例如一些 Logging 表中的 log_id,一些事件表中的 event_id 等等。该列将不依赖于任何其他表中的任何其他列,并且唯一标识该记录。从查找的角度来看,用于查找信息的列通常是表中也可以被索引的其他列(status/event_type/etc 等)。那么,有什么必要有这样一个 id 列来表示表中的记录呢?如果我要从日志表中删除这样的 id 列,并且可能改为使用复合键,我犯了什么罪?为什么在表中拥有如此独特的 id 列而在应用程序中不使用该列的情况如此普遍?希望听听专家的意见。:o

更新:谢谢大家的快速回复!首先,我想了解为什么在诸如审计表之类的表中使用代理键而不是复合键是如此普遍的做法(还有其他示例,但试图保持对话的重点)。在这样的表中,我可以通过事件、用户 ID 和时间戳的组合轻松识别唯一记录。我在网上研究的大多数设计仍然使用诸如 event_id 之类的键。如果有任何真正的原因,我试图理解为什么会这样?事实上,这是否意味着消耗不必要的数据库存储空间?

4

4 回答 4

3

我区分了在我的数据模型中实现真实关系的表,以及只是用于临时、日志记录、审计跟踪等的数据转储的表。

这些是没有自然键的表 - 即没有可以保证唯一的列组合,但重复项有意义;甚至没有可以应用的理论上的、合乎逻辑的自然键。换句话说,根据数据的关系模型,它不是真正的关系。我们只是为了方便使用一张桌子。

在极少数情况下,表根本不需要键——一个简单的例子是日志表,它只记录发生的事件。它只会被插入,并且清除是基于时间戳完成的(顺便说一下,不能保证它是唯一的)。如果不需要键或代理键,没有引用约束,那么我将省略它。

但是一旦应用程序需要引用一个表——例如,如果我们需要在其他地方引用一个特定的记录——它现在是数据模型的一部分,我们需要将它视为一个关系——即它是什么自然键。一旦确定了,我们就可以决定是否需要代理键。

通常,我的模式中唯一没有 ID 的表是完全没有约束的表 - 即调试日志和审计跟踪(即记录表上的每个插入/更新/删除)。其他一切都至少有一个独特的约束,如果不是更多的话。

于 2013-05-23T02:41:31.433 回答
2

如果它只是一个审计表,我个人对复合键没有问题。您需要某种密钥,因为大概您会不时清除日志,并且您可以使用密钥进行选择。

组合键的邪恶代表主要是因为有些人使用真实的业务值(SSN、出生日期等)来组成键,然后将它们扩散到与父级具有外键关系的相关表中。

这种扩散使表格非规范化,而且这些值可能会发生变化。如何?最常见的是因为他们一开始就输入错误,但我有一个客户不得不更改 SSN,原因如下:

  • 由于身份被盗,客户获得了新的 SSN。
  • “无证”并使用假 SSN 的客户,然后成为“有证”并获得真正的 SSN。
  • 最重要的是:所有 SSN 都必须加密存储的行政命令。

幸运的是,根据我的建议(以及其他人的建议),他们没有使用 SSN 作为主键的一部分,因此这些更改很容易。

避免使用复合键的另一个原因是:它们增加了JOIN. 但同样,对于审计日志,您可能不在乎。

最后,我想强调一下,我几乎 100% 的时间都使用 ID 类型的值,并且已经这样做了十多年,所以这并不是我对复合键感到矛盾的情况。我倾向于避免它们,但在你的情况下,我认为这不是一件坏事。

于 2013-05-22T20:42:08.250 回答
0

除了其他回答之外,我认为要记住的另一个问题是您需要考虑什么独特性。如果您需要复合键保持唯一,则有两种选择:1)将复合键创建为 PK 或 2)使用代理键(系统生成的数字)并在复合键(自然键)上添加另一个约束备用键。有时我使用的驱动器。黛安

于 2013-05-22T21:32:27.163 回答
0

复合键的用途与 ID 相同。如果这满足您的需求,那么您就没有犯罪。

但是,如果您发现您选择的复合键引入了冲突(当您期望一个或没有记录时您返回了多个记录),那么您需要重新评估您的复合键。

拥有一个保证唯一且不会重复使用的 ID 将避免此问题(以表中的额外字段为代价)。

于 2013-05-22T20:40:18.640 回答