RDBMS 数据库中的多对多关系

发布于 2024-08-26 02:10:03 字数 170 浏览 2 评论 0原文

在像 mySQL 这样的 RDBMS 数据库中处理多对多关系的最佳方法是什么?

已尝试使用数据透视表来跟踪关系,但它会导致以下任一情况:

  • 标准化被抛在后面

  • 列为空或为空

您采用了什么方法来支持多对多关系?

What is the best way of handling many-to-many relations in a RDBMS database like mySQL?

Have tried using a pivot table to keep track of the relationships, but it leads to either one of the following:

  • Normalization gets left behind

  • Columns that is empty or null

What approach have you taken in order to support many-to-many relationships?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不知所踪 2024-09-02 02:10:04

专门针对该关系的表(有时称为联结表)中跟踪多对多关系。该表将关系建模为两个指向相反方向的一对多关系。

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';

Keep track of a many-to-many relationship in a table specifically for that relationship (sometimes called a junction table). This table models the relationship as two one-to-many relationships pointing in opposite directions.

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));

You then use the junction table to join other tables through it via the foreign keys.

-- 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';
流星番茄 2024-09-02 02:10:04

我会使用数据透视表,但我不知道你的问题来自哪里。使用一个简单的学生/班级示例:

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。这不应该导致任何空/空列或任何内容。

I would use a pivot table, but I don't see where your issues are coming from. Using a simple student/class example:

Student
-------
Id (Primary Key)
FirstName
LastName

Course
------
Id (Primary Key)
Title

StudentCourse
-------------
StudentId (Foreign Key -> Student)
CourseId (Foreign Key -> Course)

Or, as somebody else mentioned in response to your Student/Teacher/Course question (which would have an additional table to store the type of person in the 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)

The Student table contains student information, the Course table stores course information...and the pivot table simply contains the Ids of the relevant students and courses. That shouldn't lead to any null/empty columns or anything.

桃扇骨 2024-09-02 02:10:04

除了贾斯汀的回答之外:如果巧妙地使用外键约束,您可以控制数据更新或删除时发生的情况。这样,您就可以确保最终不会得到非规范化的数据。

In addition to Justin's answer: if you make clever use of Foreign Key constraints, you can control what happens when data gets updated or deleted. That way, you can make sure that you do not end up with de-normalized data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文