多对多 - 概念

Dea*_*an7 -1 schema database-design many-to-many

我知道有很多关于多对多关系的问题,但似乎没有一个对我有用,因为它更多地是关于概念而不是代码的问题。所以我需要澄清一下如何实现我的想法。

我正在尝试制作乐高数据库。我有可以有很多小人仔的套装。某些 MINIFIGURES 也可以出现在许多 SETS 中。我是这样做的,在 Excel(csv) 文件中。它是 SETS “表”。

Id  Set_Name                        Set_Id   Minifigures_List
1   Spider-Man's Doc Ock Ambush     6873     Doc Ock, Spider-Man, Iron Fist
2   Spider-Man: Spider-Cycle Chase  76004    Spider-Man, Venom, Nick Fury
3   Electro                         5002125  Electro
.....
Run Code Online (Sandbox Code Playgroud)

我的数据库实现的第一步是创建一个SETS表。

CREATE TABLE Sets (
ID int NOT NULL AUTO_INCREMENT,
Set_Name varchar(255),
Set_Id varchar(255),
);
Run Code Online (Sandbox Code Playgroud)

然后插入数据:

Insert into Sets (Set_Name, Set_Id)
VALUES ('Spidermans Doc Ock Ambush' , '6837'), 
('Spider-Man: Spider-Cycle Chase' , '76004')
('Electro', '5002125')
;
...
Run Code Online (Sandbox Code Playgroud)

下一步是创建一个MINIFIGS表,并赋予它们属性。

CREATE TABLE Sets (
ID int NOT NULL AUTO_INCREMENT,
Set_Name varchar(255),
Set_Id varchar(255),
);
Run Code Online (Sandbox Code Playgroud)

像这样:

CREATE TABLE MINIFIGS (
ID int NOT NULL AUTO_INCREMENT,
Minifig_Name varchar(255),
Minifig_Id varchar(255),
);
Run Code Online (Sandbox Code Playgroud)

然后插入数据:

Insert into Minifigs (Minifig_Name, Minifig_Id)
VALUES ('Doc Ock' , 'SH040'), 
('Spider-Man', 'SH038'),
('Venom', 'SH055')
;
...
Run Code Online (Sandbox Code Playgroud)

如何从这里开始?我错过了一步吗?我应该在哪里以及如何做?关联表格的步骤在哪里?我是否必须这样做,首先拆分 Minifigures_Sets 单元格,然后从中创建表格?如果我像这样创建表,就会有重复项。创建连接表的步骤在哪里?

Insert into Sets (Set_Name, Set_Id)
VALUES ('Spidermans Doc Ock Ambush' , '6837'), 
('Spider-Man: Spider-Cycle Chase' , '76004')
('Electro', '5002125')
;
...
Run Code Online (Sandbox Code Playgroud)

然后,我在哪里以及如何插入新数据?进入 Junction 表?主表可以从连接表中提取数据吗?

Min_Id  Minifig_Name    Minifig_Id
1       Doc Ock         SH040
2       Spider-Man      SH038
3       Venom           SH055
4       Nick Fury       SH056
5       Iron Fist       SH041
6       Electro         SH141
Run Code Online (Sandbox Code Playgroud)

谢谢你。


这是我在阅读可能的答案和评论后创建的连接表:

CREATE TABLE Minifigures_Sets ( 
  Minifig_Id INT NOT NULL,
  Minifig_Name varchar(255),
  Set_Id INT NOT NULL,
  Set_Name varchar(255)
);
Run Code Online (Sandbox Code Playgroud)

现在,当我得到它时,我在哪里以及如何插入这些新数据?我只是把它放在一个接线台上吗?或者我首先必须拆分 Minifigure_List 单元格,然后先插入 Minifigs 和 Sets 表?我是否需要一些命令,如 REFERENCES,也许插入和定义外键,但我不确定在哪里做?

CREATE TABLE MINIFIGS (
ID int NOT NULL AUTO_INCREMENT,
Minifig_Name varchar(255),
Minifig_Id varchar(255),
);
Run Code Online (Sandbox Code Playgroud)

J.D*_*.D. 5

正如您所提到的,您将需要第三个链接表(连接表),但它应该只包含被链接的两个表之间的键,以减少冗余并提高规范化

所以,你应该创建一个名称的表像MINIFIGURESETS,包含列ID从您的SETS表(应该给它一个更好的名字,但你已经有了所谓的另一列SET_ID,这样可以得到混淆),并MIN_ID从你的MINIFIGS。如果需要,它还可以有自己的标识列。

该表将始终管理您SETSMINIFIGS表之间的多对多关系。添加新集合、创建新小人仔或从集合中删除小人仔时MINIFIGURESETS,您将在表格中管理这些操作。

正如我在评论中提到的,您需要先插入到您的MINIFIGS和/或SETS表中以生成您需要的每条记录的键,一旦创建了这些键,您就可以使用每个表中的键插入到您的链接/连接表中。在不知道您使用的确切数据库系统、实现和版本的情况下,实际上不可能提供您可以利用的确切代码(如果您使用此信息更新您的帖子,那么我也会更新我的答案)。但是给您一个想法,例如在 Microsoft SQL Server 中,您可以在调用后INSERT调用某个函数SCOPE_IDENTITY()。这是一个示例查询批处理,它利用SCOPE_IDENTITY()这样您就可以将新插入的记录的键获取到MINIFIGS表中,然后将该键插入到您的表中特定的链接/连接表SET如下所示:

-- Creates a new Minifigure
INSERT INTO Minifigs (Minifig_Name, Minifig_Id)
VALUES ('Doc Ock' , 'SH040');

-- Created a new link between the new Minifigure and the Set with SET_ID 76057 (for the Set called Web Warriors Bridge Battle)
INSERT INTO Minifigures_Sets (Minifig_Id, Set_Id)
SELECT SCOPE_IDENTITY() AS Minifig_Id, 76057 AS Set_Id
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用相同的函数将新创建的映射MINIFIG到所有SETS类似的函数:

-- Creates a new Minifigure
INSERT INTO Minifigs (Minifig_Name, Minifig_Id)
VALUES ('Spider-Man' , 'SH038');

-- Created a new link between the new Minifigure and ALL Sets
INSERT INTO Minifigures_Sets (Minifig_Id, Set_Id)
SELECT SCOPE_IDENTITY() AS Minifig_Id, Set_Id
FROM Sets
Run Code Online (Sandbox Code Playgroud)

再次请注意,根据您使用的特定数据库系统如何将新插入记录的键获取到表中,您的里程会有所不同,上面的示例只是提供一个总体思路(基于 Microsoft SQL 中可用的内容)服务器)。

我注意到您使用链接/连接表更新了您的帖子,但您已将Minifig_NameSet_Name作为列包含在其中。这两列是不需要的,会导致不必要的数据冗余。您应该将它们从Minifigures_Sets表中删除并仅存储您添加的 ID 列。每当您需要其中一...Name列时,您都可以JOIN通过 ID 关联表以获取它们,如下所示:

SELECT MS.Minifig_Id, MS.Set_Id, M.Minifig_Name, S.Set_Name
FROM Minifigures_Sets MS
INNER JOIN Minifigs M
    ON MS.Minifig_Id = M.Minifig_Id
INNER JOIN Sets S
    ON MS.Set_Id = S.Set_Id
Run Code Online (Sandbox Code Playgroud)

我要说的最后一件事是(我之前的建议意味着)您的链接/连接表应该存储您的和表的,这些将是每个表的列。您只需要适当地命名它们,因为您已经在使用名称和它们各自的表中来表示不同的字段。(我个人会将它们重命名为其他名称,因此您可以使用这些名称来表示,这在您在表中使用它们时会更加清晰。)MinifigsSetsIDMinifig_IdSet_IdMinifigure_Sets