MySql - 使用联结和外键

时间:2017-02-19 01:54:09

标签: php mysql set foreign-keys junction

所以这就是问题所在:

我有一张桌子"会员"成员及其属性(姓名,生日,邮件等) 这些成员可能属于组(让我们说有3组),从无到有。这些组在表格中引用(" Groups"),因此我可以根据需要添加/删除/修改它们。

SET()似乎不是解决方案,它与外键/参考表不兼容。

首先,我考虑做一个TINYINT()列,我使用SET()111 (7)表示所有组,000 (0)表示无,{{1对于第一组,001 (1)用于第二组,等等。但由于这些名称非常复杂,令人困惑,与外键的兼容性也不高。

我读到我应该做第3张桌子"会员 - 团体"使用memberID和groupID连接我的两个表,但我不清楚它是如何工作的。

据我所知,我将拥有一张包含会员和群组ID的表格,如下所示:

010 (2)

并结合我可以检索我想要的东西。这样对吗 ?否则有人可以解释我应该怎么做?

我确切地说,我希望最终结果(在sql请求+ php脚本之后)成员,他的属性和他所属的组在一行中(与+----------+---------+ | memberID | groupID | +----------+---------+ | 1 | 1 | | 1 | 2 | | 2 | 1 | | 2 | 3 | | 3 | 2 | +----------+---------+ 一样),即使是不属于任何群体的成员。

2 个答案:

答案 0 :(得分:0)

我对这个问题感到有些困惑,但我会对它进行一次尝试。

如果您有一个Members表,那么将member_id作为唯一主键是有意义的。如果要存储每个成员所在的组,只需将新列添加到每个组的“成员”表中。

至于要为列Group1Group2Group3提供的值,您可以将它们设置为ENUM('0','1')或ENUM('否' ,'是')或其他任何方法,并将默认值设为负值(第一)值。

使用这种数据库结构,您无需在查询期间打乱字符串 - 只需编写指定相应组列值的SELECT或WHERE语句。

如果没有直接回答,请澄清您的问题。

答案 1 :(得分:0)

假设

drop table if exists mg;

drop table if exists m;
create table m (id int primary key, name varchar(3));
insert into m values
(1,'abc'),
(2,'def'),
(3,'ghi');

drop table if exists g;
create table g(id int primary key ,name varchar(3));
insert into g values
(1,'aaa'),
(2,'bbb'),
(3,'ccc');

create table mg
(memid int,grid int,
index fmid(memid,grid) ,
foreign key (memid) references m(id) on delete cascade,
foreign key (grid)  references g(id) on delete cascade
);
insert into mg values
(1,1),(1,2),(1,3),
(2,1),(2,3);

您可以加入3个表并使用group_concat或条件聚合生成结果。

MariaDB [sandbox]> select m.id,m.name, group_concat(g.name) groups
    -> from m
    -> join mg on mg.memid = m.id
    -> join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+-------------+
| id | name | groups      |
+----+------+-------------+
|  1 | abc  | aaa,bbb,ccc |
|  2 | def  | aaa,ccc     |
+----+------+-------------+
2 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select m.id,m.name,
    -> max(case when g.id = 1 then g.name else '' end) as group1,
    -> max(case when g.id = 2 then g.name else '' end) as group2,
    -> max(case when g.id = 3 then g.name else '' end) as group3
    -> from m
    -> join mg on mg.memid = m.id
    -> join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+--------+--------+--------+
| id | name | group1 | group2 | group3 |
+----+------+--------+--------+--------+
|  1 | abc  | aaa    | bbb    | ccc    |
|  2 | def  | aaa    |        | ccc    |
+----+------+--------+--------+--------+
2 rows in set (0.00 sec)

如果您希望不属于任何群组的成员将联接更改为左联接。

ariaDB [sandbox]> select m.id,m.name, group_concat(g.name) groups
    -> from m
    -> left join mg on mg.memid = m.id
    -> left join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+-------------+
| id | name | groups      |
+----+------+-------------+
|  1 | abc  | aaa,bbb,ccc |
|  2 | def  | aaa,ccc     |
|  3 | ghi  | NULL        |
+----+------+-------------+
3 rows in set (0.00 sec)

MariaDB [sandbox]>
MariaDB [sandbox]> select m.id,m.name,
    -> max(case when g.id = 1 then g.name else '' end) as group1,
    -> max(case when g.id = 2 then g.name else '' end) as group2,
    -> max(case when g.id = 3 then g.name else '' end) as group3
    -> from m
    -> left join mg on mg.memid = m.id
    -> left join g on mg.grid = g.id
    -> group by m.id,m.name;
+----+------+--------+--------+--------+
| id | name | group1 | group2 | group3 |
+----+------+--------+--------+--------+
|  1 | abc  | aaa    | bbb    | ccc    |
|  2 | def  | aaa    |        | ccc    |
|  3 | ghi  |        |        |        |
+----+------+--------+--------+--------+
3 rows in set (0.00 sec)