SQL表是否有益或需要具有唯一的ID列?

时间:2014-12-03 17:14:03

标签: mysql sql-server

根据我的经验,几乎所有表都有一个名为Id的字段,该字段是唯一的主键并已编制索引。我的问题是,如果我没有在任何地方使用这个值,并且永远不需要这个值,那么获得它的好处是什么。

这是我的问题:

数据库有这么多的关系表(通常称为映射表),它们通过唯一的ID将两个其他表连接在一起。

前行:

Id = 1 MachineId = 1 UserId = 2

Id = 2 MachineId = 1 UserId = 3

代码在今天更新此表时的方式将删除计算机的所有用户,然后继续添加所有当前用户。这就是他们选择删除旧条目的方式。问题是这会不必要地膨胀Id列,因为即使nothings已更改,您也会为每个用户删除/添加。这种情况默认情况下每90分钟发生一次。

解决此问题的一个方法是修复代码以正确的方式执行操作。另一种解决方案是完全删除Id字段。因为我们没有在其他地方链接到这个表,我们不在任何地方使用代码中的Id值(我们甚至不从数据库中提取它)为什么我们需要它?

回到我原来的问题。其他东西需要Id字段吗?或者它是否会提供一些我可能想要的失去的好处?

3 个答案:

答案 0 :(得分:3)

不,这不是必需的,特别是对于那些多对多的关系,只有不拥有它们才是完全可以接受的。

如果你对该表有外键关系,那些id特别有用,但即使这样,你也可以拥有由多个列的唯一组合组成的外键,所以即使对于外键你也不一定需要它们,虽然非常建议使用单值键来实现此目的。

拥有一个您不需要的密钥的额外好处是,一旦您需要它,您就不需要添加它。几乎没有借口。 :)

如果您想谷歌更多信息:

  • 那些多对多的表通常称为“junction table”或“交叉引用表”。
  • “无意义”的唯一ID(通常是自动编号的)也称为“surrogate key
  • 由多个字段组成的密钥(包括主键和外键)称为“compound key”。 “Composite key”通常用作同义词,但维基百科的定义略有不同。

答案 1 :(得分:1)

从技术上讲,你不需要拥有一个独特的id,但是有太多的情况没有一个会真的搞砸了你。例如考虑一下地址簿。您可以假设"名字,姓氏,地址"足以识别某人,但请考虑约翰史密斯,123 Main Street"和#34; John Smith,123 Main Street" (约翰少年)。明显的解决方案:添加" Jr。"字段,或添加更多的密钥,并希望你不会得到重复....或者你只需​​添加一个auto_increment ID字段并完成它。并不重要的是其他字段在记录中是重复的,你知道id字段是唯一的。

如果您愿意,可以轻松制作一个独特的复合键,但如果您需要设置外键关系,则必须复制所有这些键'外表中的字段。

e.g。

table A (
   p, q, r, s t -> char
   primary key (p, q, r, s, t)
)

table B (
   h, i, j, k -> whatever
   p, q, r, s, t -> char
   foreign key (p, q, r, s, t) -> A (p, q, r, s, t)
)

现在你已经在两个表中得到了你的pqrst字段,并且必须为每个连接操作写出来,IN FULL。然而,如果你有一个简单的单一ID字段:

table A (
    id -> primary key int
    p, q, r, s ,t
)

table B (
    h, i, j, k -> hwatever
    a_id -> int
    foreign key (a_id) -> A (id)
)

在两个表之间携带一个简单的int字段,v。复合键中每个字段的n个字段。

答案 2 :(得分:1)

简答:在这种情况下,您在问题中描述了ID列不是必需的,如果您愿意,可以将其删除并在构建的表中添加PK / Unique使用链接表中的ID。

长答案(以我的个人观点):ID列用于加速使用大量连接的查询(比较整数比比较长字符串更快),并且适度链接表和外键列的大小。另一种用法是为这些表添加一个唯一标识符,这些标识符包含简单的现实生活标识符(如日志表)。

在某些情况下,只会添加ID列,因为所有表都包含ID列。

您始终必须考虑ID列具有任何含义或是否真的有必要:如果您的字符代码(仅使用ASCII字符)长度少于4个字符,则代码将小于INT ID列( INT存储在4个字节上,bigint存储在8个字节上。

另一件事:始终将实体的名称添加到ID列(例如PersonIDInvoiceID)以使查询和架构更具可读性。在我看来,列的名称始终应该代表它存储的内容,名称ID只是没有描述存储在列中的值,PersonID的时间。此外,您可以(并且应该)在外键中使用相同的名称。

在我们使用当前硬件的大多数情况下,ID列主要使数据库复杂化(您始终必须连接多个表才能获得业务/自然键)。此外,该ID对业务没有任何意义。您始终可以考虑保留ID列并使用自然键作为主键。 (当您将ID作为PK并且另一列定义为unique not null时,您可以保留ID列:例如:一个表包含发票:PK可以是InvoiceNumber,它是打开的基于纸张的发票,而不是ID,但如果数据库负责生成该数字,则必须使用基于序列的列。)

如果您没有使用简单的自然键(或者您拥有自然键,但它们太宽或者必须使用其他几个列进行构建),ID(或任何计算机生成的标识符)非常有用,或者自然钥匙我们可变,你必须有一些uniq标识符之王(车牌号码是一个例子)。