多对多的数据库建模问题[重复]

Posted

技术标签:

【中文标题】多对多的数据库建模问题[重复]【英文标题】:issue with database modelling of many-tom-many [duplicate] 【发布时间】:2018-07-11 04:21:07 【问题描述】:

我想要两个模型 2 的简单表:Account & Manager。

帐户可以有多个经理,经理可以有多个帐户要管理。所以我们之间是多对多的关系。

这就是我在数据库中创建它们的方式:

CREATE TABLE Account (
    accountId int NOT NULL AUTO_INCREMENT,
    name varchar(255) NOT NULL,
    PRIMARY KEY (accountId)
);

CREATE TABLE Manager (
    managerId int NOT NULL AUTO_INCREMENT,
    name varchar(255) NOT NULL,
    accountId int NOT NULL,
    PRIMARY KEY (managerId),
    FOREIGN KEY (accountId) REFERENCES Account (accountId)
);

对您来说可能很明显的问题是,对于同一个经理,我将有重复的名称和不同的 ID,如下所示:

你会如何推荐一个 sql 新手来做呢? :)

我认为我建模它的方式是一对多...

【问题讨论】:

many-to-many 需要 3 个表:2 个主要表和一个特殊 link 表。 【参考方案1】:

创建一个映射表(例如 Account_Manager)来映射 Account 和 Manager,AccountID 和 ManagerID 应该是外键。

问候 阿卜杜勒

【讨论】:

【参考方案2】:

我会从经理中删除 accountid/外键并引入一个新表来交叉引用这两个表。像这样的:

CREATE TABLE ManagerAccount(
    id int not null auto_increment,
    managerId int not null,
    accountId int not null,
    primary key(id),
    foreign key(managerid) references Manager (ManagerID),
    foreign key(accountId) references Account (AccountID)
)

也许在两个外键上抛出一个唯一索引。

【讨论】:

【参考方案3】:

实现与第三个表的多对多关系,并使用两个相关表的外键。

举个例子:

person
  id
  person_name

club
  id
  club_name

一个俱乐部可以有零个、一个或多个成员;一个人可以是零个、一个或多个俱乐部的成员。这是一个多对多的关系。

关系表的最简单形式:

membership
   club_id       PK, FK ref club.id
   person_id     PK, FK ref person.id

可以定义...

CREATE TABLE membership
( club_id    INT NOT NULL COMMENT 'PK, FK ref club.id'
, person_id  INT NOT NULL COMMENT 'PK, FK ref person.id'
, PRIMARY KEY (club_id, person_id)
, KEY membership_IX1 (person_id)
, CONSTRAINT FK_membership_club   FOREIGN KEY (club_id)   REFERENCES club (id)
, CONSTRAINT FK_membership_person FOREIGN KEY (person_id) REFERENCES person (id)
)

我们注意到,这种关系本身可能具有属性,例如加入日期和离职日期。也可能有状态(临时、活跃、试用),我们可能想要跟踪俱乐部内的办公室或角色。

这种关系可能不仅仅是 junctionlink 表。它实际上可能是我们系统中的一个实体。而且我们可能希望像处理实体一样处理它,添加一个单独的 id 列,并且还考虑删除 (club_id,person_id) 是唯一的要求。


【讨论】:

【参考方案4】:

通常,建模多对多关系的最佳方法是创建一个单独的表来保存它。使用您的示例:

CREATE TABLE Account (
   accountId int NOT NULL AUTO_INCREMENT,
   name varchar(255) NOT NULL,
   PRIMARY KEY (accountId)
);

CREATE TABLE Manager (
    managerId int NOT NULL AUTO_INCREMENT,
    name varchar(255) NOT NULL,
    PRIMARY KEY (managerId),
);

CREATE TABLE Account_Manager (
        id int NOT NULL AUTO_INCREMENT,
        accountId int NOT NULL,
        managerId int NOT NULL,
        PRIMARY KEY (id),
        FOREIGN KEY (accountId) REFERENCES Account(accountId)
        FOREIGN KEY (managerId) REFERENCES Manager(managerId)
 );

这样,经理和帐户之间的任何关联都将显示在 Account_Manager 表中(例如,(5,1) 表示 patrick 与 accountId = 5 的帐户的关联)。但是,要完全理解为什么这是最常见的方法,我建议您阅读规范化。

【讨论】:

以上是关于多对多的数据库建模问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章

星型模式建模 - 多对多

在关系数据库中对相同实体之间的多个多对多关系进行建模

CoreData:如何建模循环多对多关系

《Entity Framework 6 Recipes》翻译系列 -----第二章 实体数据建模基础之有载荷和无载荷的多对多关系建模 (转)

建模数据仓库中的多对多关系

DW中尺寸之间的多对多关系-更好的建模?