我的系统中可能有X个不同的表,还有一个表存储这些表的所有关系数据。例如,数据库看起来像这样
-------------------------- -----------------------------------
| Table fruits | | Table drinks |
-------------------------- -----------------------------------
| id | name | | id | name |
-------------------------- -----------------------------------
| 1 | banana | | 1 | strawberry apple cocktail|
| 2 | apple | | 2 | banana juice |
| 3 | strawberry | | 3 | cola |
-------------------------- -----------------------------------
--------------------------
| table food |
--------------------------
| id | name |
--------------------------
| 1 | apple pie |
--------------------------
关系表包含两个条目的id和表名。
--------------------------------------------------
| table relations |
--------------------------------------------------
| id | table_1 | id_1 | table_2 | id_2 |
--------------------------------------------------
| 1 | fruits | 1 | drinks | 2 | banana + banana juice
| 2 | fruits | 2 | drinks | 1 | apple + s.a. cocktail
| 3 | fruits | 3 | drinks | 1 | strawberry + s.a cocktail
| 4 | food | 1 | fruits | 2 | apple pie + apple
| 5 | drinks | 3 | food | 1 | if someone wants to mix it
--------------------------------------------------
如果我喝了一杯(草莓苹果鸡尾酒),我想得到属于它的所有水果ids(草莓和苹果),当我有水果(草莓)时,我想查询所有相关的喝ids。
所以我需要一个查询结构来查找双方,因为它是动态的,我不知道水果是在table_1
还是table_2
(否则它会很简单)
我希望有这样的东西(注意伪代码)来查询包含香蕉的饮料中的所有ID(表:fruits,id:1)
SELECT id
FROM drinks
LEFT JOIN relations AS rel ON drinks.id = (rel.table_1 == drinks)? rel.id_1 : rel.id_2
WHERE
((rel.id_1 = '1' AND rel.table_1 = 'fruits') OR ( rel.id_2 = '1' AND rel.table_2 = 'fruits' ))
我的问题
当我这样做2次加入时
Select * from drinks
LEFT JOIN relations AS relation1 ON drinks.id = relation1.id_1
LEFT JOIN relations AS relation2 ON drinks.id = relation2.id_2
WHERE
( (relation1.id_1 = '1'
AND relation1.table_1 = 'fruits')
OR ( relation2.id_2 = '1'
AND relation2.table_2 = 'fruits' )
OR ( relation1.id_2 = '1'
AND relation1.table_2 = 'fruits')
OR ( relation2.id_1 = '1'
AND relation2.table_1 = 'fruits'))
我可以从两边搜索所有东西(有饮料 - >收到水果/有水果 - >收到饮料)但我也得到了与水果相同的饮料
select * from relations
,因为我使用php构建查询,其他条件如fruit name,dateCreated等等,如果它包含关系,我将不得不重构整个查询
谢谢你,我的英语不好
答案 0 :(得分:0)
您的问题出在您的设计中,drink
表与fruit
表有多对多的关系,因此您应该将fruit_drink_relation表分开。
fruit_drink_food_relation的表存在相同的多对多关系。
要查找食物,查询第二个关系表,否则,第一个关系表就足够了。
答案 1 :(得分:0)
那里的设计非常糟糕。
请参阅,关系数据库管理系统拥有强大的机制,可以保持和实施实体之间的一致(!)关系(表示为表中的记录)。
为什么不按原样使用它?
从示例中可以看出,你有n..n(多对多)关系,而不是更多关系。
它有一个比它更常见的模式,关系表基本上由两列组成,这两列都是你需要连接在一起的实体的外键:
CREATE TABLE fruits_juices (
fruit_id INT,
juice_id INT
FOREIGN KEY fruit_id
REFERENCES fruits(id),
FOREIGN KEY juice_id
REFERENCES juices(id)
)
为你需要的每个关系做到这一点 - 就这样。
创建一些关系并没有什么不好 - 这是RDBMS应该工作的方式(因此他们最擅长的)。
不要尝试不必要的多才多艺:你的用例并不要求这样做。
在他们想要涵盖的所有情况下,太过一对一的解决方案通常并不好,并且需要额外的维护成本以防止它们崩溃(数据一致性,在您的情况下)
答案 2 :(得分:0)
我想你想要一个snowflake schema。
看起来你现在正处于丑陋的一半。