【问题标题】:Relational Database design foreign keys关系数据库设计外键
【发布时间】:2015-05-16 06:12:38
【问题描述】:

我有表 types,其中有许多 grades 和许多 colors。 我在gradestype_idcolors 中都放了一个外键。 我有一个名为item 的第三个表,其中有一个grade 和一个color

我的问题是,如何确保从item 回到types 的数据的完整性。

例如:

Type:
     0 sometype1
     1 sometype2

grades:
     0 somegrade 0 (points to sometype1)

color:
     0 red 0 (points to sometype1)

item:
     0 item1 0 0 (points to somegrade, red - which points to   sometype1)

如何确保不会出现colorgrade 正确但type 不正确的情况?

如果其中一个外键引用了正确的类型,而另一个没有,等等,该怎么办?

在我看来,必须有更好的方法来对此进行建模,有人可以帮忙吗?

【问题讨论】:

  • 请提供更多关于类型、等级和颜色之间关系的信息以及更多示例数据(每张表格多做 2 行),以便我们了解您的要求。

标签: mysql database-design foreign-keys modeling


【解决方案1】:

由于colorgrade 都引用types,您可以让item 包含所有三个id 值,并使用它们自己的id 和type_id 引用这两个表。由于外键约束将共享相同的 type_id,因此无法引用不同类型的等级和颜色。

表上的最少列是:

types: type_id 
       [no foreign key constraints]
grades: grade_id, type_id 
       [type_id references types.type_id]
colors: color_id, type_id 
       [type_id references types.type_id]
items: item_id, type_id, grade_id, color_id
       [ (type_id, grade_id) should reference grades as one key
        ,(type_id, color_id) should reference colors as one key
        , type_id would reference types but that should not need enforced with a constraint.
       ] 

【讨论】:

  • 所以 gradecolortypes 会有一个指向 item 的外键?如果grade 的外键是类型 0 而颜色的类型是 1,item 可以是任何东西......我不确定这个问题
  • 不,现在更新清楚。
  • 你将如何实现items 外键约束?似乎外键只能引用一个表(这是有道理的)。
  • 类似CONSTRAINT fk`外键(type_idgrade_id)参考gradetype_idid)`??
  • @avrono 是的,就像那样,您将有一个类似的第二个外键约束引用颜色。由于两个约束将共享相同的 type_id,它会阻止您引用不同类型的颜色和等级。
【解决方案2】:

如果 Item 可以是某个 Type 并且 Type 可以有一个或多个 Colors 和一个或多个 Grades,那么 Items 表的 FK 引用可能不一定直接转到 Types 表。如果 Item 仅获取其特定类型的颜色和等级,则它不直接引用颜色或等级。

create table Colors(
    ID     int primary key,
    <ColorInfo>
);
create table Grades(
    ID     int primary key,
    <GradeInfo>
);

如果每个类型可以有多种颜色和等级组合,则必须将参考移动到交叉表中。

create table TypeColorGrade(
    TypeID    int,
    ColorID   int,
    GradeID   int,
    constraint PK_TypeColorGrade primary key( TypeID, ColorID, GradeID ),
    constraint FK_TypeColorGrade_Type foreign key( TypeID )
        references Types( ID ),
    constraint FK_TypeColorGrade_Color foreign key( ColorID )
        references Colors( ID ),
    constraint FK_TypeColorGrade_Grade foreign key( GradeID )
        references Grades( ID )
);

一个类型可以具有的每种颜色和等级的有效组合都在此处表示。因此,Items 表只能引用具有定义等级和颜色的 Type。

create table Items(
    ID       int,
    TypeID   int,
    ColorID   int,
    GradeID   int,
    constraint PK_Items primary key( ID ),
    constraint FK_Item_Type foreign key( TypeID, ColorID, GradeID )
        references TypeColorGrade( TypeID, ColorID, GradeID )
);

外键不指向类型表,而是指向类型/颜色/等级组合。任何插入具有未为该类型定义的颜色或等级的特定类型的项目的任何尝试都将失败。

【讨论】:

  • 谢谢@TommCatt,我已经用第一个解决方案测试了我的模型,这似乎暂时成立。但是,创建intersection 表似乎也是一个可行的选择。
  • 在 MySQL 中,约束 FK_Item_Type 外键(TypeID,ColorID,GradeID)引用 TypeColorGrade(TypeID,ColorID,GradeID)失败,引用不匹配,有什么想法吗?那是因为您不能将子项中的单个列映射到父项中的多个列吗?
  • 我在示例中默认使用整数数据类型。你的可能不一样。检查数据类型是否匹配。
  • 我想我试图将一个 id 映射到多个 fk(id) ref Table(x,y,z) 这显然是不允许的
猜你喜欢
  • 2014-07-09
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 2011-06-24
  • 1970-01-01
相关资源
最近更新 更多