如果我在SQL中有两个表有很多关系的表,我是否需要创建一个额外的表?

时间:2010-01-24 02:10:18

标签: sql database

以这些表格为例。

Item
    id
    description
    category

Category
    id
    description 

一个项目可以属于许多类别,一个类别显然可以附加到许多项目。

在这种情况下如何创建数据库?我不确定。有人说创建了第三张桌子,但是我需要这样做吗?我真的要做一个

  

创建表bla bla

第三个表?

3 个答案:

答案 0 :(得分:4)

是的,您需要创建一个带有ids映射的第三个表,其中包含以下列:

 item_id     (Foreign Key)
 category_id (Foreign Key)

编辑:您可以将item_id和category_id视为主键,它们可以单独唯一地标识记录。在某些应用程序中,我发现为记录本身包含一个额外的数字标识符很有用,如果您愿意,可以选择包含一个

将此表视为项目和类别之间所有映射的列表。它简洁明了,很容易查询。

编辑:删除(不必要的)主键。

答案 1 :(得分:3)

是的,你不能只用这两个表在两个表之间形成第三范式的多对多关系。你可以形成一对多(在两个方向中的一个方向)但是为了获得真正的多对多,你需要这样的东西:

Item
    id primary key
    description

Category
    id primary key
    description

ItemCategory
    itemid     foreign key references Item(id)
    categoryid foreign key references Category(id)

您不需要在Item表中使用某个类别,除非您对某个项目具有某些特权类别(此处似乎不是这种情况)。当加入表中已经存在“真正的”唯一键时,我也不是引入不必要的主键的忠实粉丝。项目和类别ID已经是唯一的这一事实意味着ItemCategory表格的整个记录​​也将是唯一的。

只需使用标准工具监控ItemCategory表的性能即可。您可能需要以下一个或多个索引:

  • 的itemid
  • 类别ID
  • (商品ID,类别ID)
  • (类别ID,项ID)

取决于您用于加入数据的查询(其中一个复合索引将是主键)。

整个工作的实际语法如下:

create table Item (
    id            integer       not null primary key,
    description   varchar(50)
);
create table Category (
    id            integer       not null primary key,
    description   varchar(50)
);
create table ItemCategory (
    itemid        integer       references Item(id),
    categoryid    integer       references Category(id),
    primary key   (itemid,categoryid)
);

您应该考虑其他类型的事情,例如将您的ID列设置为身份/自动增量列,但这与手头的问题没有直接关系。

答案 2 :(得分:2)

是的,你需要一个“联接表”。在一对多关系中,“多”侧的对象可以对“一”侧的对象具有FK引用,这足以确定整个关系,因为每个“很多”对象只能有一个“一”对象。

在多对多关系中,这已不再足够,因为您无法在单个字段中填充多个FK引用。 (嗯,你可以,但是你会丢失数据的原子性和关系数据库带来的所有好东西。)

这是连接表的来源 - 对于ItemCategory之间的每个关系,该关系在连接表中表示为一对:Item.id x {{ 1}}。