在像MySQL这样的RDBMS数据库中处理多对多关系的最佳方法是什么?
尝试使用数据透视表来跟踪关系,但它会导致以下任一情况:
规范化落后于
空列或空的列
您采取了哪些方法来支持多对多关系?
答案 0 :(得分:10)
跟踪表中专门针对该关系的多对多关系(有时称为联结表)。该表将关系建模为指向相反方向的两个一对多关系。
CREATE TABLE customer (
customer_id VARCHAR NOT NULL,
name VARCHAR NOT NULL,
PRIMARY KEY (customer_id));
CREATE TABLE publication (
issn VARCHAR NOT NULL,
name VARCHAR NOT NULL,
PRIMARY KEY (issn));
-- Many-to-many relationship for subscriptions.
CREATE TABLE subscription (
customer_id VARCHAR NOT NULL,
FOREIGN KEY customer_id REFERENCES customer (customer_id),
issn VARCHAR NOT NULL,
FOREIGN KEY issn REFERENCES publication (issn),
begin TIMESTAMP NOT NULL,
PRIMARY KEY (customer_id, issn));
然后使用联结表通过外键通过它加入其他表。
-- Which customers subscribe to publications named 'Your Garden Gnome'?
SELECT customer.*
FROM customer
JOIN subscription
ON subscription.customer_id = customer.customer_id
JOIN publication
ON subscription.issn = publication.issn
WHERE
publication.name = 'Your Garden Gnome';
-- Which publications do customers named 'Fred Nurk' subscribe to?
SELECT publication.*
FROM publication
JOIN subscription
ON subscription.issn = publication.issn
JOIN customer
ON subscription.customer_id = customer.customer_id
WHERE
customer.name = 'Fred Nurk';
答案 1 :(得分:4)
我会使用数据透视表,但我不知道您的问题来自哪里。使用简单的学生/班级示例:
Student
-------
Id (Primary Key)
FirstName
LastName
Course
------
Id (Primary Key)
Title
StudentCourse
-------------
StudentId (Foreign Key -> Student)
CourseId (Foreign Key -> Course)
或者,正如其他人在回答您的学生/教师/课程问题时提到的那样(会有一个额外的表格来存储课程中的人员类型):
PersonType
----------
Id (Primary Key)
Type
Person
------
Id (Primary Key)
FirstName
LastName
Type (Foreign Key -> PersonType)
Course
------
Id (Primary Key)
Title
PersonCourse
------------
PersonId (Foreign Key -> Person)
CourseId (Foreign Key -> Course)
学生表包含学生信息,课程表存储课程信息......数据透视表只包含相关学生和课程的ID。这不应该导致任何null / empty列或任何东西。
答案 2 :(得分:1)
除了Justin的回答:如果巧妙地使用外键约束,您可以控制数据更新或删除时会发生什么。这样,您就可以确保不会以非规范化数据结束。