【问题标题】:Link table(s) or redundant columns, SQL optimisation链接表或冗余列,SQL 优化
【发布时间】:2012-04-16 11:04:41
【问题描述】:

我有两个表,Users 和 People,它们共享一个共同的属性,即电子邮件地址,应该允许它们拥有多个电子邮件地址。

我自己可以看到三个选项:

  1. 一个带有冗余列的链接表:

    • 用户 [id,email_id] 和人员 [id,email_id]
    • 电子邮件地址 [id,user_id,person_id,email_id]
    • 电子邮件 [id、地址、类型]
  2. 两个没有冗余的链接表:

    • 用户 [id,email_id] 和人员 [id,email_id]
    • PersonEmail [id,person_id,email_id]
    • 用户邮箱 [id,user_id,email_id]
    • 电子邮件 [id、地址、类型]
  3. 没有冗余列的链接表:

    • 用户 [id] 和人员 [id]
    • 电子邮件 [id,address,type,user_id,person_id]

有没有人知道什么是最好的选择,或者是否有其他方法?另外,如果有人知道如何实现或觉得最好有没有生成的 id 列的链接表,请同时指定。

更新:一个用户有很多人,一个人属于一个用户

【问题讨论】:

  • 如果不对用户和人之间的关系进行更多解释,就无法提供此问题的答案。例如:“用户”是可以登录的特殊类型的人吗?如果有人员条目,是否总是有用户,反之亦然?多解释一下您要建模的内容,您将能够就如何建模得到更好的答案。
  • 它们在概念上是不同的——一个用户有很多人,一个人属于一个用户

标签: sql ruby-on-rails database optimization


【解决方案1】:

首先,用户和电子邮件之间的关系是1:N,而不是M:N,所以无论如何你都不需要“链接”表EmailAddress

您需要确定哪些可能性适合您的应用程序:

  1. 用户永远是人。
  2. 人永远是用户。
  3. 可能有人不是用户并且可能有人不是人。

选项 1:

假设选项 (1) 是正确的,逻辑模型应该如下所示:

Person 和 User 之间的符号是“类别”,在物理数据库级别可以实现:

  • 作为单独的表PersonUser 之间的“1 到0 或1”关系,
  • 或包含人员和用户字段的单个表,其中用户字段对于非用户的人员为 NULL。

如果你有...

  • 许多用户特定的字段,
  • 有用户特定的外键,
  • 未来可能会添加新类型的人
  • 而且您无需竭尽全力降低性能,

...选择两个表的实施策略。

如果有:

  • 用户特定字段相对较少,
  • 没有特定于用户的关系,
  • 低“可进化性”是可以接受的
  • 性能非常重要,

...选择单表的实现策略。

可以对剩余的每种可能性进行类似的分析...

选项 2:

选项 3:

【讨论】:

  • 一个用户是一个人,所以它会是选项(1)虽然它符合:一个用户有很多用户特定的字段,并且有个人特定的外键。您能否详细说明“使用两个表选择实施策略”的含义。(?)在这方面有很多想法!
  • @defaye 一个类别可以实现为两个相关的表或单个表,如答案中所述。
  • 您的回答非常有帮助。我意识到我可能应该考虑有一个额外的表,这样一个用户有很多联系人,一个联系人属于一个用户,用户和联系人都是特殊类型的人
  • 然后我可以将 Person_id 作为电子邮件中的 FK。
【解决方案2】:

User 不是 Person (People) 吗?

这将立即解决冗余字段问题。

----------
| Person |
----------
    |
 --------
 | User |
 --------

User 应该具有单个电子邮件字段,或者保持与电子邮件表的关系,因为Person 是一个与任何应用程序无关的抽象概念。

我会说开始考虑(重新)建模您的架构,这样您就不会遇到这样的问题。

阅读 Rails 指南中的Multiple Table Inheritance,这应该可以帮助您入门。

【讨论】:

  • 允许User登录,Person是属于User的人的记录。
  • 您可能在这里有所收获,但我还不确定如何在 Rails 中实现继承。调查一下
【解决方案3】:

如果这两个实体在概念上是相关的,那么拥有一张表可能是有意义的。但如果它们是两个不同的概念,那么根据我的经验,最好有单独的表以避免将来混淆。而且这样做不会对任何地方造成重大影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 2019-01-23
    • 2018-08-14
    • 1970-01-01
    • 2013-01-20
    相关资源
    最近更新 更多