2010-08-29 105 views
3

一直在阅读教程How to handle a Many-to-Many relationship with PHP and MySQLmysql多对多关系

在这个问题上我指的是哪些规定如下规则“数据库架构”部分:

这个新表必须构建以 允许:

* 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:用户表是从关系不同的数据库(称之为友谊)。所以我不能使用外键。

+0

我已经发布了一个“澄清”的问题在这里:http://stackoverflow.com/questions/3597078 – Poni 2010-08-29 23:54:37

回答

2

对于第一个问题:

  1. 两个 列上创建一个唯一约束
  2. 确保你总是列进行排序。比确保 即a小于或等于 b

对于第二个问题,所以,如果你的表有 colummns ab

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

“独特的约束”?对不起,但我不会说SQLish(你能解释一下吗?我知道外键 - 如果这就是你的意思,那么不行,我不能这样做,因为这些ID来自一个完全不同的数据库,有没有解决方案?关于第2条 - 我也没有承认这一点,只有第二个问题的答案是可以理解的,我感谢你的耐心和善意,真的,谢谢 – Poni 2010-08-29 23:21:02

+0

@Poni:你可以创建一个唯一的约束或者两列的主键(查看staticsan的例子),下面是关于如何创建唯一约束的文档:http://dev.mysql.com/doc/refman/5.1/en/ innodb-foreign-key-constraints.html 'alter table many_to_many_table add unique index(a,b);' – Wolph 2010-08-30 00:35:02

+0

两列上的主键都会使得一对具有唯一性,但这对的另一个组合可能会添加,我不想要。1 <-> 2&2 <-> 1.第二个是不想要的。 – Poni 2010-08-30 00:52:10

0

好WoLpH增快,我基本上同意(请注意,您必须同时在两个列上创建一个单个约束!)。只是为了解释为什么你碰到你提到的规则:通常,A和B是不同的表。因此,n:m关系的典型示例将允许条目(1,0)和(0,1),因为它们会引用不同的对。有表A =表B是不同的情况(你使用A和B作为用户,但在这个例子中他们是表)。

+0

尼古拉斯感谢您的支持 - 对不起,如果我不理解你,或WoLpH。查看我对我的评论他的答案,我会appriciate更多信息的话! – Poni 2010-08-29 23:22:47

1

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

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

这是你如何建立一个表,以便有永远只能是一个一行AB定义表作为相关。它可以工作,因为主键必须在表中是唯一的,因此数据库将只允许一行使用任何特定的值对。你可以创建不是主键的复合键,它们不必是唯一的(但你可以创建一个唯一的非主键,复合或不),但是你的规范要求一个主键,所以这就是我建议。

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

+0

感谢您花时间回复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 ','id_b')) ENGINE = InnoDB; – Poni 2010-08-29 23:38:19

+0

我假设您有两种不同类型的对象,例如您对'表A'和'表B'的描述所建议的对象,如人员和邮寄地址。这意味着对'表A'的引用将总是*在'id_a'中,而对'表B'的引用将总是*在'id_b'中,否则将无意义。或者有用。 – staticsan 2010-08-30 03:12:55