使用两个不同的外键创建表

时间:2017-03-05 06:09:09

标签: mysql sql sql-server

我必须创建一个与两个不同表关系的表。考虑下面的例子。

假设我有以下三个表:

1) Person -> person_id, residence_type (V or T)
2) Village -> village_id, village_name
3) Town -> town_id, town_name

现在我要做的是在人员表中为该人的村庄或城镇创建一个外键引用。我想到了两种方式。

一个是创建一个residence_name列,只输入来自村庄或城镇表的id,然后根据residence_type查询它是否为V或T.但是我肯定无法将其创建为两个不同表的外键引用时间。

另一种选择是在person表中创建两列--v_id和t_id,并根据residence_type填充一列。我可以再次相应地查询它,但肯定无法将其创建为外键引用,因为它不能为NULL,但在这种情况下,一列始终为NULL。

这两种方法中的哪一种更好,还是有更好的方法可以让我创建外键引用?

1 个答案:

答案 0 :(得分:1)

对我而言,设计看起来有些“不确定”。我的假设是,对于一个人,你想知道他的住所是什么,即最终是村庄或城镇的名字?

如果是这种情况,我会删除乡村和城镇的桌子,并将其替换为包含乡村和城镇的住宅查找表,其中包含一个到ResidenceType表的列。 ResidenceType表看起来像这样(这是SQL Server语法):

CREATE TABLE dbo.ResidenceType
(
  ResidenceTypeID smallint NOT NULL,
  ResidenceTypeDefinition nvarchar(25),
  CONSTRAINT [pk_ResidenceType] PRIMARY KEY (ResidenceTypeID),
);

然后你会像这样填充那个表:

INSERT INTO dbo.ResidenceType(ResidenceTypeID, ResidenceTypeDefinition)
VALUES (1, 'Village'), (2, 'Town');

现在你可以创建一个Residence表,这个表可以包含城镇和村庄的名字 - 而且它会有一个反对ResidenceType表的外键:

CREATE TABLE dbo.Residence
(
  ResidenceID int NOT NULL,
  ResidenceTypeID smallint NOT NULL,
  ResidenceName nvarchar(25),
  CONSTRAINT [pk_Residence] PRIMARY KEY (ResidenceID),
  CONSTRAINT [fk_ResidenceTypeID] FOREIGN KEY (ResidenceTypeID)
  REFERENCES dbo.ResidenceType(ResidenceTypeID),
);

添加一些数据:

INSERT INTO dbo.Residence(ResidenceID, ResidenceTypeID, ResidenceName)
VALUES (1, 1, 'Village 1'),
       (2, 1, 'Village 2'),
       (3, 2, 'Town 1'),
       etc...

最后你的Person表看起来像:

CREATE TABLE dbo.Person
(
  PersonID bigint NOT NULL,
  ResidenceID int NOT NULL,
  CONSTRAINT [pk_Person] PRIMARY KEY (PersonID),
  CONSTRAINT [fk_Person_ResidenceID] FOREIGN KEY (ResidenceID)
  REFERENCES dbo.Residence(ResidenceID),
);

这就是我建议你这样做的方式。您现在正在遵循规范化等方面的最佳实践。