【问题标题】:Do I need a Primary Key If I'm using 1 to Many Relationship?如果我使用一对多关系,我需要主键吗?
【发布时间】:2014-04-05 21:05:18
【问题描述】:

我有一张桌子叫branch

看起来有点像。

+----------------+--------------+
|     branch_id  |  branch_name |
+----------------+--------------+
|         1      |  TestBranch1 |
|         2      |  TestBranch2 |
+----------------+--------------+

我已将branch_id 设置为主键。

现在我的问题与名为item 的下一张表有关

看起来像这样。

+----------------+-----------+---------------------------+
|     branch_id  |  item_id  |         item_name         |
+----------------+-----------+---------------------------+
|         1      |     1     |  Apple                    |
|         1      |     2     |  Ball                     |
|         2      |     1     |  Totally Difference Apple |
|         2      |     2     |  Apple Apple 2            |
+----------------+-----------+---------------------------+

我想知道是否需要为item 表创建主键?

更新 他们不共享相同的项目。很抱歉造成混乱。一个分支可以创建另一个分支中不存在的产品。它们就像两个商店共享同一个数据库。

更新 抱歉信息不完整。 这些表实际上来自两个本地数据库...... 我正在尝试创建一个可以单独存在但与另一个数据库混合时仍然没有问题的数据库。所以系统只会附加来自另一个分支的所有项目数据,而不会将它们混合在一起。在为他们的项目生成unique_id 时,这些分支不会考虑其他分支的item_id。但是,所有数据库可能共享相同的 branch 表作为参考。

提前谢谢你们。

【问题讨论】:

  • 主键是 RDBMS 中表的先决条件。没有 PRIMARY KEY,它就不是一个真正的表!
  • @Strawberry 嗯,它仍然是一个表,但它不是一个关系!

标签: mysql sql database database-design primary-key


【解决方案1】:

我想知道是否需要为我的项目表创建主键?

您总是1需要一个键2,无论表是否涉及关系3。唯一的问题是 kind 的 key 是什么?

以下是您在这种情况下的选择:

  1. 单独将{item_id} 设为密钥。这使得关系“非识别”和item 成为“强”实体......
    • 这会产生更苗条的键(与第二个选项相比),因此任何可能引用它的子表都会更苗条。
    • 任何 ON UPDATE CASCADE 操作都在item 级别被切断,并且不会传播给子级。
    • 可以更好地使用 ORM。
  2. {branch_id, item_no} 上创建一个复合4 键。这使得关系“识别”和item 成为“弱”实体......
    • 这使得item 本身更苗条(少一个索引)。
    • 这对于clustering 可能非常有用。
    • 在某些情况下可能会帮助您避免 JOIN(如果有子表,branch_id 会传播给它们)。
    • 可能需要正确建模"diamond-shaped" dependencies

所以选择你的毒药;)

当然,branch_id 在这两种情况下都是外键(但不是键)。

与所有这些正交,如果 item_name 必须在每个分支(而不是整个表)上是唯一的,那么您还需要在 {branch_id, item_name} 上使用复合键。


1逻辑的角度来看,你总是需要一个键,否则你的表将是一个多重集,因此不是一个关系(它是一个集合) ,因此您的数据库将不再是“关系型”。从物理的角度来看,可能有一些特殊情况可以打破这条规则,但很少见。

2 从逻辑的角度来看,它的主要与否是immaterial,尽管如果 DBMS 赋予它特殊含义可能很重要,例如 InnoDB 的情况uses primary key as clustering key.

3请区分“关系”和“关系”。

4 又名。 “复合”。

【讨论】:

  • 哇。这真的很有意义。好吧,实际上我的数据库设置非常独特。我正在尝试建立一个可以为单个分支提供服务的数据库,但合并之前单独存在的两个分支没有问题。所以他们的项目可以有相同的 item_ids,但我可以保证他们有不同的 branch_ids,因为它们在安装之前是唯一的。有了这个设置。我可以创建本地服务器并将其数据整合到 1 台公司服务器上而无需麻烦。只是上传和更新数据。
【解决方案2】:

根据您的示例数据,您使用的是 n 到 m 关系,而不是 1 到 m。应该是这样的

item table
----------
item_id  | item_name
    1    | Apple
    2    | Ball


branch_item table
-----------------
item_id  | branch_id
    1    | 1
    1    | 2
    2    | 1
    2    | 2

您的brach_item 表应该有一个包含branch_iditem_id 的复合唯一键,以确保不能添加重复条目。

【讨论】:

  • 如果您还解释了原因,而不仅仅是提出解决方案,那就太好了。这一次他成功了,但情况可能相同的下一张牌桌没有。
  • @juergen d,我有一个疑问,如果我应该创建没有 pk 的表看起来像表,a4academics.com/interview-questions/53-database-and-sql/…
【解决方案3】:

是的,你知道。主键是允许多对一关系存在的原因。

branch_id 列已满足此要求。

您的示例中的一对多关系不需要 item_id 列。

【讨论】:

  • 正如我在更新中已经解释的那样。他们不共享相同的项目。所以这不是多对多的关系。它只是许多项目的一个分支。每个分支维护一个单独的项目列表。没有分支共享一个项目。
  • 明白。我已经修改了我的答案。只是让您知道,在您的示例中 item_id 没有意义。从表面上看,它看起来像一个主键,只是每个项目没有唯一的编号。如果您将 item_id 列从 1,2,1 和 2 更改为 1,2,3 和 4,那么这将是有意义的。
  • 事情是这样的。这些数据实际上存在于不同的分支中,合并后的数据看起来像这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
  • 2012-10-06
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多