【问题标题】:How to deal with a 'self' relationship in SQL?如何处理 SQL 中的“自我”关系?
【发布时间】:2019-09-28 01:44:54
【问题描述】:

在我们的应用程序中,我们有clients,每个客户端都有一个customers的列表

client table:
id  |  name
-------------
1   |  happy
2   |  bashful


customer table:
id  | client_id  |  name
----------------------------------------
50  | 1          | happys first customer
51  | 1          | happys second customer
52  | 2          | bashfuls first customer

无需过多详细说明,每个客户都会有一份适用于他们的价格清单。为简单起见,我们会说我们还有一个产品表,产品 ID 为 1,2 和 3,每个客户对每个项目都有一个唯一的价格。所以客户 50 将有 3 行,客户 51 将有 3 行,客户 52 在此 price 表中将有 3 行。

price table:
id  | customer_id  |  product_id  |
----------------------------------------
50  | 50           | 1            |  4.99
51  | 50           | 2            |  6.20
52  | 50           | 3            |  8.00
...

现在最重要的是:每个客户应该在这个price 表上拥有自己的行。我们将此客户价目表称为“基本价目表”,因为在应用程序的上下文中,所有客户的价格都将与之进行比较。


对我来说,有三个显而易见的解决方案,但我不确定它们中的任何一个是否正确,或者哪一个是最佳的:

解决方案 1

在名称类似于“self”的客户表中添加一行,以便将“self”视为几乎像客户一样

.

解决方案 2

使价格表有两个外键列,一个带有customer_id,一个带有client_id,并允许customer_id为空——如果customer_id为空,我知道该行是客户行。

.

解决方案 3

有 2 个基本相同的价格表,一个外键输入客户,一个外键输入客户。

【问题讨论】:

  • 另一种选择是让价格表有一个通用 ID 字段,该字段可以引用 either 客户或客户。然后,您为客户/客户标志添加一个字段,以识别该 ID 是针对客户还是客户。我已经看到这很有效,但据我所知,它完全消除了拥有外键的能力。我的投票是使用“默认”或什至使用 null 来表示自我/默认的解决方案 1。但我认为您的意思是在 customer 表中添加一行。
  • @avery_larry 我的意思是客户表,谢谢。我不喜欢有一个标志来指定要加入哪个表的想法,因为这会使联接最终变得很奇怪。我在 Laravel 工作,hasMany 关系在这种情况下会有点失常。
  • 解决方案 1 但有一个单独的字段 customer_is_client 来标识客户基本价格。这样,您仍然可以将“Joe Self”作为客户!
  • 不错的主意@KenOn10

标签: sql foreign-keys relational-database


【解决方案1】:

声明外键关系是个好主意。据我所知,没有数据库支持有条件的外键关系,因此消除了为客户及其客户提供一列的情况。

您没有指定客户是否对客户是唯一的,所以让我假设他们不是。

这表明选项 2 和 3 是最合理的。实际上几乎没有什么可以将它们分开的。对于单个表,您需要一个检查约束,即设置了一个 id — 除非您有客户在客户端之间共享 并且,否则您允许特定于客户、特定于客户、 客户特定价格。

我认为,更重要的考虑因素是价格和关系会随着时间而变化。您应该考虑如何将有效日期和结束日期合并到数据模型中以捕获此信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2015-06-17
    • 2018-07-09
    • 2018-02-17
    • 1970-01-01
    • 2015-04-12
    • 2011-11-29
    相关资源
    最近更新 更多