【问题标题】:Should I give a row ID to each row in a table of unique names?我应该给唯一名称表中的每一行一个行 ID 吗?
【发布时间】:2012-12-02 13:26:02
【问题描述】:

我需要一些最佳实践和性能建议。

假设我有三个表:Employees、Jobs 和 Ranks。 每个员工都有工作和等级,所以显然我应该在员工表中引用这些表。

我的问题是,以下哪个选项最好:

1) 每个工作和排名都存储有一个唯一的 ID,并与描述性名称配对。 Employees 表应该引用另一个表中的唯一 ID,从而节省内存(描述性名称仅在 Jobs/Ranks 表中保存一次),但要查看描述性名称,我需要执行 JOINs:

SELECT Employees.EMPL_ID, Ranks.R_NAME, Jobs.J_NAME
FROM Jobs
JOIN Ranks ON Ranks.R_ID=Employees.RANK
JOIN Jobs ON Jobs.J_ID=Employees.JOB

2) 只是唯一的描述性名称。这可能会浪费内存,因为我反复保存每个职级/工作的描述性名称,但我在 SELECT 语句上节省了时间

编辑:>

澄清一下,我主要关心的是,如果我需要使用多个 JOINs 而不是一个 SELECT 语句来执行 SELECTs,我必须处理的性能。

我希望能够处理大量流量 - 具体来说,员工请求查看他们的工作和排名。

编辑>

例子:

选项 1(ID 和名称):

Employees:
 __________________________
/ EMPL_ID  |  RANK  | JOB  \
|    1     |    2   |  3   |
|    1     |    1   |  3   |
|    1     |    1   |  1   |
\__________|________|______/

Ranks:
 __________________
/  R_ID  |  R_NAME \
|    1   |   GRUNT |
|    2   |   BOSS  |
\________|_________/

Jobs:
 ____________________
/  J_ID  |  J_NAME   \
|   1    | JANITOR   |
|   3    | PRESIDENT |
\________|___________/

选项 2(唯一名称):

Employees:
 _______________________________
/ EMPL_ID  |  RANK  | JOB       \
|    1     |  BOSS  | PRESIDENT |
|    1     |  GRUNT | PRESIDENT |
|    1     |  GRUNT | JANITOR   |
\__________|________|___________/

Ranks:
 __________
/   R_NAME \
|    GRUNT |
|    BOSS  |
\__________/

Jobs:
 ___________
/  J_NAME   \
| JANITOR   |
| PRESIDENT |
\___________/

【问题讨论】:

  • 你总是可以的,它永远不会伤害,而且有时会有所帮助。如果不确定,请添加数字 ID。
  • @JanDvorak:说“它永远不会痛”是不正确的,因为从另一个表中加入/查找值显然是有成本的。在大多数情况下,此类成本可能无关紧要 - 但它始终非零。

标签: mysql database


【解决方案1】:

是的,总是给每一行一个唯一的 id。

最佳实践是始终为每个表提供此信息。 通常称为 'id' 或 the-table-name_id'

它应该没有商业价值。

许多“保证唯一”记录后来发现需要或存在或重复记录,并且始终拥有唯一的主键在满足/发现这一点时有很大帮助。

“唯一”的一个例子......不是......如果一个系统有人们的社会安全号码,它们应该是唯一的。但是,有可能打错了。然后,当具有“错误输入”值的人出现并且他们的号码被输入时...除了识别行之外。

唯一记录是一个众所周知的问题。为所有记录提供唯一 ID 是解决该问题的解决方案的一部分。

上述所有情况的例外是性能。我不太关心几千条记录的连接速度,因为 SQL 数据库设计得很好,可以加快速度。我发现唯一标识的优势大于劣势。在某些情况下,您可能会因性能要求而更改上述做法。例如,如果有数百万条记录必须加载到内存中,则唯一 ID 空间的开销可能会成为一个问题。通常情况下,如果人们开始关注 Redis、MongoDB 等无 SQL 解决方案。

以下是 SO 和其他网站上的一些附加参考:

What's the best practice for primary keys in tables?

in general, should every table in a database have an identity field to use as a PK?

http://www.sql-server-performance.com/forum/threads/do-i-need-a-unique-identifier-or-identity-column.16910/

is an ID column really needed in SQL?

正如在一个答案中评论“在社区中的宗教辩论中使用自然键与代理键”。还有一个关于回答者如何获得他们的“规则”的评论...... tee-hee......

【讨论】:

  • 您能否引用任何关于您的“最佳实践”断言的参考资料?特别是对于命名列id,我觉得这是不好的做法(它会导致连接之间的歧义)。字段值本身肯定符合您作为主键的条件?
  • 并非如此。正是我在 15 年的应用程序构建和 7 年的数据仓库工作中在该领域和各种课程中学到的东西。
  • 我认为 SO 是更少的“引用参考”(维基百科)和更多的“个人推荐”,但其他人可能能够提供帮助。
  • 当然,在我的回答中添加了更多的 cmets
  • 在我的阅读中,您引用的所有链接都与您的陈述相矛盾“最佳实践它始终为每个表格提供此内容”。大多数链接表明自然键和代理都有其位置。 OP 想知道哪个最适合他的需求,我担心您的回答只是遵循“总是有一个代理键”的教条(尽管我确实喜欢 SSN 的自然键何时会出错的示例)。
【解决方案2】:

我强烈建议您添加一个 EMPL_ID (EmployeeID)。目前,您的应用程序可能工作得非常好,但是当您扩展它时,即使您认为自己不会这样做,EMPL_ID 也会派上用场。

不仅如此,如果您在代码中拥有可用的 EMPL_ID,并且需要访问您现在或将来构建的其他表,您所要做的就是将 EMPL_ID 添加到该表中,而不必复制新表中的 R_ID 和 J_ID。

例如,如果您添加了一个 tblNotes 表。 (我不知道您的应用程序的范围,所以我将仅参考注释表进行讨论)

在本例中,您只需要以下列:noteID、EMPL_ID、note、noteDateTime....

如果不添加 EMPL_ID,您将拥有多余的列,这些列是不必要的,并且很可能在多个表中!

此外,添加索引只能在一列上。

我总是为每个表添加一个 ID,因为它让生活变得如此轻松,尤其是当您的应用程序增长时。另外,我什至在某些情况下看到公司有两个同名的员工!当然,他们不太可能拥有相同的级别和工作,但这只是值得深思的!

希望我正确理解了您的问题,并为您提供了一些有用的信息。

约翰

【讨论】:

  • 我认为问题不在于如何在 Employees 表上定义 PK,而是在 RanksJobs 表上。
  • 是的。 @eggysl 是对的,我只是想了解 R_ID 和 J_ID
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
相关资源
最近更新 更多