Table_1中的每一行都需要与一行或多行有关系,这些行可能来自数据库中的任意数量的其他表(Table_X)。所以我设置了一个中间表(Table_2),其中每一行包含Table_1中的id和Table_X中的id。它也有自己的自动增量ID,因为没有任何关系是独占的,因此其他ID在表中都不是唯一的。
我现在的问题是,当我从Table_1中检索行并希望查看Table_X中每个相关行的信息时,我不知道如何获取它。起初我以为我可以为Table_2中的每一行创建一个Table_X的确切名称列,并使用该信息创建第二个SELECT语句,但是我已经看到了关于外键和连接语句的内容。我想我需要进入。我只是在整理它时遇到了麻烦。我甚至需要Table_2吗?
这可能并不过分复杂,但我刚刚进入MySQL,这是我遇到的第一个真正的挑战。
编辑以包含所需信息:如果我理解正确,我认为我处理的是多对多的关系。 Table_3有游戏; Table_1有文章。一篇文章可以是关于多个游戏的,并且游戏也可以有多篇关于它的文章。我能看到的唯一其他可能相关的信息是,当一篇新文章被制作出来时,每一个与之相关的游戏都会立刻被决定。但随着更多文章的撰写,与特定游戏相关的文章列表会随着时间的推移而增长。然而,这可能并不是特别重要。
答案 0 :(得分:2)
如果我理解正确您正在谈论数据库中的一对多关系(例如:一个人可以有多个电话号码),您可以将数据存储在两个单独的表persons
和phones
中。
人:
|person_id|person_name |person_age |
| 1 | Bodan Kustan| 28 |
电话:
|phone_id |person_id |phone_number|
| 1 | 1 | 31337 |
| 2 | 1 | 370 |
然后您可以使用Join:
执行查询SELLECT * FROM `persons`
LEFT JOIN `phones` ON `persons`.`person_id` = `phones`.`person_id`
WHERE `persons`.`person_id` = 1;
它将返回您的电话号码列表:
|person_id|person_name |person_age |phone_id |person_id |phone_number|
| 1 | Bodan Kustan| 28 | 1 | 1 | 31337 |
| 1 | Bodan Kustan| 28 | 2 | 1 | 370 |
另一种可能性是多对多的关系(例如:任何人都可以喜欢披萨,而披萨对于那个人来说并不是唯一的),那么你需要第三张桌子来加入桌子person_food
人:
|person_id|person_name |person_age |
| 1 | Bodan Kustan| 28 |
食物:
|food_id |food_name |
| 1 | meat |
| 2 | pizza |
Person_Food
|person_id |food_id |
| 1 | 2 |
然后您可以使用Join:
执行查询SELLECT * FROM `persons`
LEFT JOIN `person_food` ON `person`.`person_id` = `person_food`.`person_id`
LEFT JOIN `food` ON `food`.`food_id` = `person_food`.`food_id`
WHERE `persons`.`person_id` = 1;
它将从所有表中返回数据:
|person_id|person_name |person_age |person_id |food_id |food_name |
| 1 | Bodan Kustan| 28 | 1 | 2 | pizza |
但是,有时您需要加入n
个表来加入,然后您可以使用单独的表来保存关于关系的信息。我的方法(我认为这不是最好的)是将表名存储在关系旁边(例如将手机和家庭电话分成两个独立的表):
人:
|person_id|person_name |person_age |
| 1 | Bodan Kustan| 28 |
MOBILE_PHONE:
|mobile_phone_id |mobile_phone_number |
| 1 | 31337 |
HOME_PHONE:
|home_phone_id |home_phone_number |
| 1 | 370 |
Person_Phone:
|person_id |related_id |related_column |related_table |
| 1 | 1 | mobile_phone_id | mobile_phone |
| 1 | 1 | home_phone_id | home_phone |
然后查询中间表以获得所有关系:
SELECT * FROM person_phone
WHERE person_id
= 1
然后构建动态查询(伪代码,未经测试 - 可能无效):
foreach (results as result)
append_to_final_sql = "LEFT JOIN {related_table}
ON {related_table}.{related_column} = `person_phone`.`related_id`
AND `person_phone`.`related_table` = {related_table}"
final_sql = "SELECT * FROM `persons` "
+ append_to_final_sql +
" WHERE `persons`.`person_id` = 1"
所以你的最终SQL将是:
SELECT * FROM `persons`
LEFT JOIN `person_phone` ON `person_phone`.`person_id` = `person`.`person_id`
LEFT JOIN `mobile_phone` ON `mobile_phone`.`mobile_phone_id` = `person_phone`.`related_id` AND `person_phone`.`related_table` = 'mobile_phone'
LEFT JOIN `home_phone` ON `home_phone`.`home_phone_id` = `person_phone`.`related_id` AND `person_phone`.`related_table` = 'home_phone'
答案 1 :(得分:0)
如果Table_x中的条目可以与Table1中的多行相关,则只需要Table2 - 否则Table1的简单键就足够了。
查看联接 - 非常强大,灵活和快速。
select * from Table1 left join Table2 on Table1_id = Table2_table_1_id
left join Table_X on Tablex_id = Table2_table_x_id
查看输出,您将看到它返回包含Table1和Table2字段副本的所有table_x行。