多对多关系示例
Posted
技术标签:
【中文标题】多对多关系示例【英文标题】:Many-to-many relationships examples 【发布时间】:2011-02-24 19:30:34 【问题描述】:我在这里和谷歌中没有找到任何 mysql 。我正在寻找的是一个非常简单的例子,其中 php+mysql 显示了数据库的结果。谁能写一个非常简单的例子?
【问题讨论】:
看这个:tonymarston.net/php-mysql/many-to-many.html 【参考方案1】:示例场景:大学的学生和课程。一个给定的学生可能会学习几门课程,当然一个课程通常会有很多学生。
示例表,简单设计:
CREATE TABLE `Student` (
`StudentID` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`FirstName` VARCHAR(25),
`LastName` VARCHAR(25) NOT NULL,
PRIMARY KEY (`StudentID`)
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_general_ci
CREATE TABLE `Course` (
`CourseID` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
`Code` VARCHAR(10) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`Name` VARCHAR(100) NOT NULL,
PRIMARY KEY (`CourseID`)
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_general_ci
CREATE TABLE `CourseMembership` (
`Student` INT UNSIGNED NOT NULL,
`Course` SMALLINT UNSIGNED NOT NULL,
PRIMARY KEY (`Student`, `Course`),
CONSTRAINT `Constr_CourseMembership_Student_fk`
FOREIGN KEY `Student_fk` (`Student`) REFERENCES `Student` (`StudentID`)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `Constr_CourseMembership_Course_fk`
FOREIGN KEY `Course_fk` (`Course`) REFERENCES `Course` (`CourseID`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=INNODB CHARACTER SET ascii COLLATE ascii_general_ci
查找所有注册课程的学生:
SELECT
`Student`.*
FROM
`Student`
JOIN `CourseMembership` ON `Student`.`StudentID` = `CourseMembership`.`Student`
WHERE
`CourseMembership`.`Course` = 1234
查找给定学生参加的所有课程:
SELECT
`Course`.*
FROM
`Course`
JOIN `CourseMembership` ON `Course`.`CourseID` = `CourseMembership`.`Course`
WHERE
`CourseMembership`.`Student` = 5678
【讨论】:
为什么 CourseMembership 表有 ascii 字符集? 能否请您添加如何正确插入数据?按什么顺序等。 这种情况下有什么办法可以更新记录吗?我现在正在做的是删除现有记录并在更新案例中添加新记录?如何检查要更新的记录?【参考方案2】:下面是所涉及的 SQL 的一个快速而肮脏的示例。我认为没有必要用 php 混淆这个概念。只需像检索其他集合一样检索该集合。
在这个例子中,有很多名字和很多颜色。人们可以有不止一种喜欢的颜色,而且很多人可以有相同的喜欢的颜色。因此多对多。
***** Tables **********
person
--------
id - int
name - varchar
favColor
-------------
id - int
color - varchar
person_color
------------
person_id - int (matches an id from person)
color_id - int (matches an id from favColor)
****** Sample Query ******
SELECT name, color
FROM person
LEFT JOIN person_color ON (person.id=person_id)
LEFT JOIN favColor ON (favColor.id=color_id)
****** Results From Sample Query *******
Name - Color
---------------
John - Blue
John - Red
Mary - Yellow
Timmy - Yellow
Suzie - Green
Suzie - Blue
etc...
这有帮助吗?
【讨论】:
【参考方案3】:mysql> SELECT * FROm products;
+----+-----------+------------+
| id | name | company_id |
+----+-----------+------------+
| 1 | grechka | 1 |
| 2 | rus | 1 |
| 3 | makaronu | 2 |
| 4 | yachna | 3 |
| 5 | svuniacha | 3 |
| 6 | manka | 4 |
+----+-----------+------------+
6 rows in set (0.00 sec)
mysql> SELECT * FROm company;
+----+----------+
| id | name |
+----+----------+
| 1 | LVIV |
| 2 | KIEV |
| 3 | KHarkiv |
| 4 | MADRID |
| 5 | MILAN |
| 6 | KOR |
+----+----------+
6 rows in set (0.00 sec)
mysql> SELECT * FROm many_many;
+------------+---------+
| product_id | city_id |
+------------+---------+
| 1 | 1 |
| 1 | 3 |
| 2 | 3 |
| 1 | 2 |
| 1 | 4 |
| 2 | 4 |
| 2 | 1 |
| 3 | 1 |
+------------+---------+
8 rows in set (0.00 sec)
mysql> SELECT products.name,company.name FROM products JOIN many_many ON many_
ny.product_id =products.id JOIN company ON company.id= many_many.city_id;
+----------+---------+
| name | name |
+----------+---------+
| grechka | LVIV |
| grechka | KHarkiv |
| grechka | KIEV |
| grechka | MADRID |
| rus | KHarkiv |
| rus | MADRID |
| rus | LVIV |
| makaronu | LVIV |
+----------+---------+
8 rows in set (0.00 sec)
【讨论】:
喜欢 grechka,兄弟(棕褐色) 这就是我要找的,感谢您提供的图形示例【参考方案4】:SELECT a.a_id, b.b_id, b.b_desc,
CASE WHEN x.b_id IS NULL THEN 'F' ELSE 'T' END AS selected
FROM a
CROSS JOIN b
LEFT JOIN x ON (x.a_id = a.a_id AND x.b_id = b.b_id)
WHERE (a.a_id = 'whatever')
【讨论】:
请给出你的答案解释以上是关于多对多关系示例的主要内容,如果未能解决你的问题,请参考以下文章
如何使用PowerDesigner软件进行数据库设计(多对多关系)
MySQL 基础 -- 多表关系(一对一1对多(多对一)多对多)多表查询(内连接外连接自连接子查询(嵌套查询)联合查询 union)笛卡儿积