从第二个表中的一个表链接两个不同的主键

时间:2010-02-10 07:21:37

标签: mysql database database-design normalization

我只是在学习规范化,所以如果这是一个愚蠢的问题,请原谅我。

我有一张表TBL_Users,主键为ID。跟踪我最近想过的朋友是谁做了一个带有两个外键的表,这两个外键都是另一个人的ID。然而,我越是想到这一点,我不禁想到必须有更好的方法。

+----+------+
| ID | Name |
+----+------+
| 1  | Al   |
| 2  | Bob  |
+----+------+

该模型意味着我必须复制所有信息或两次调用TBL_Friends。

如果表是

,则为IE
+----+--------+
| ID | Friend |
+----+--------+
| 1  | 2      |
| 2  | 1      |
+----+--------+

然后我有重复的信息,必须拨两个电话来添加/删除朋友。

另一方面,如果我只是做

+----+-----+
| ID | ID2 |
+----+-----+
| 1  | 2   |
| 3  | 1   |
| 4  | 1   |
+----+-----+

情况似乎更糟,因为我必须在任何时候查询数据库两次,无论是收集信息还是添加/删除朋友。

当然,我可以忽略一个更简单的解决方案吗?

2 个答案:

答案 0 :(得分:1)

您不需要使用两个查询,只需使用一个带有OR子句的查询。

SELECT
    (CASE WHEN
       WHEN id1 = XXX THEN id2
       ELSE id1
    END) AS friend_id
WHERE
   id1 = XXX OR id2 = XXX

XXX 是您正在查找的用户的ID。 这符合您提供的简单案例。

如果您的模型变得更加复杂,我们可以像您的第一个解决方案一样查看表格的其他解决方案和/或非规范化。

答案 1 :(得分:1)

您需要回答的问题是:以下两个陈述是否相同?

  1. Bob是Al
  2. 的朋友
  3. Al是Bob的朋友
  4. 这取决于背景。在社交网站中,Al和Bob只是图表上的节点,只要它们之间存在足够的链接即可。

    但如果Al跟踪Bob,那么Al可能会根据自己的喜好断言#1,Bob永远不会同意声明#2。或者考虑一个类似的政治家:

    1. Bob是Al
    2. 的经理
    3. Al是Bob的经理
    4. 这两种陈述同时是真实的,但这里有一些复杂的管理结构,这种情况并不常见。

      在这两种情况下,您的第一个表不包含重复数据,因为(1,2)与(2,1)不同。如果你确实选择第二个解决方案,你应该执行一个规则,如果(1,2)存在,(2,1)就不存在。

      在某些情况下,您的第一个解决方案是合适的解决方案,而第二个解决方案是正确的解决方案。换句话说,数据建模很难:)

      关键是,首先让你的逻辑模型正确。在编写查询之前忘掉SQL。如果您的表设计正确,SQL将会流动。或者换句话说,如果您发现难以编写查询,则可能是您的数据模型错误。