【问题标题】:mysql many to many relationshipmysql多对多关系
【发布时间】:2011-04-05 13:07:18
【问题描述】:

一直在看教程How to handle a Many-to-Many relationship with PHP and MySQL

在这个问题中,我参考了“数据库架构”部分,其中规定了以下规则:

这个新表必须被构造成 允许以下:

* It must have a column which links back to table 'A'.
* It must have a column which links back to table 'B'.
* It must allow no more than one row to exist for any combination of rows from table 'A' and table 'B'.
* It must have a primary key.

现在已经很清楚了。

我遇到的唯一问题是第三条规则(“它必须允许任何组合不得超过一行”)。
我也想应用它,但它似乎不能这样工作。

在我的 mysql (5.XX) 测试实例中,我可以添加反映相同关系的两行!

例如,如果我建立这种关系(通过添加一行):
A 到 B
它也允许我建立这种关系:
B 到 A

所以问题实际上是两个问题:

1) 我该如何执行不允许执行上述操作的第三条规则?无论组合如何,都只有一个唯一关系。

2) 当我想要搜索“A”的所有关系时,SQL 查询会是什么样子

注意#1:基本上我的最终目标是创建一个“友谊”系统,据我了解,解决方案是多对多表。如果可能,请提出其他建议。

注意 #2:用户表与关系位于不同的数据库中(称为友谊)。因此我不能使用外键。

【问题讨论】:

标签: mysql many-to-many database-relations


【解决方案1】:

听起来你想要一个复合主键。

CREATE TABLE relationship (
     A_id INTEGER UNSIGNED NOT NULL,
     B_id INTEGER UNSIGNED NOT NULL,
     PRIMARY KEY (A_id, B_id)
);

这就是您设置表的方式,以便只能有一行将表 AB 定义为相关的。它之所以有效,是因为主键在表中必须是唯一的,因此数据库将只允许一行具有任何特定的值对。您可以创建不是主键的复合键,它们不必是唯一的(但您可以创建一个唯一的非主键,复合与否),但您的规范要求一个主键,所以这就是我建议。

当然,您可以添加其他列来存储有关此特定关系的信息。

【讨论】:

  • 感谢您花时间回答 staticsan!好吧,您发布的代码没有实现它,但您的描述是我的目标。怎么行不通?这是我用来创建表的确切代码: CREATE TABLE IF NOT EXISTS db_relations.tbl_relations ( id_a INT UNSIGNED NOT NULL , id_b INT UNSIGNED NOT NULL , PRIMARY KEY (id_a, @987654329 @) ) 引擎 = InnoDB;
  • 我假设您有两种不同类型的对象,例如人员和邮寄地址,正如您对“表 A”和“表 B”的描述所暗示的那样。这意味着对“表 A”的引用将始终id_a 中,对“表 B”的引用将始终id_b 中,否则没有意义。或者有用。
【解决方案2】:

Ok WoLpH 更快,我基本上同意(请注意,您必须同时在两列上创建 single 约束!)。并且只是为了解释为什么您与您提到的规则发生冲突:通常,A 和 B 是不同的表。因此,n:m 关系的典型示例将允许条目 (1,0) 和 (0,1),因为它们将引用不同的对。让表 A=表 B 是另一种情况(您使用 A 和 B 作为用户,但在示例中它们是表)。

【讨论】:

  • nicolas 感谢您的支持 - 抱歉,如果我不理解您,或者 WoLpH。检查我们对他的回答的评论,我会应用更多信息丰富的话!
【解决方案3】:

第一个问题:

  1. 在两者上创建唯一约束 列
  2. 确保始终对列进行排序。所以如果你的桌子有 列ab 比确保 a 小于或等于 b

第二个问题:

SELECT
  *
FROM
  many_to_many_table
WHERE
  a = A or b = A

【讨论】:

  • "唯一约束" ?对不起,但我不会说 SQLish(:你能解释一下吗?我知道外键 - 如果这就是你的意思,那么不,我不能这样做,因为 ID 来自完全不同的数据库。有解决方案吗?关于第 2 条 - 我也没有理解这一点。仅理解第二个问题的答案。感谢您的耐心和善意,真的,谢谢。
  • @Poni:您可以在两列上创建唯一约束。或者两列上的主键(看看 staticsan 的例子)。这是有关如何创建唯一约束的文档:dev.mysql.com/doc/refman/5.1/en/…alter table many_to_many_table add unique index(a, b);
  • 两列上的主键会使一对确实是唯一的,但可以添加这对的其他组合,这是我不想要的。 12 & 21。不需要第二个。
  • @Poni:正如我在回答中已经解释的那样。如果您确保在插入/更新时a 始终是比约束更小的 ID,则可以完美地工作。
猜你喜欢
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
  • 2012-07-16
  • 2018-09-09
  • 2020-04-04
相关资源
最近更新 更多