2017-03-05 57 views
0

我必须创建一个有两个不同表的关系的表。考虑下面的例子。使用两个不同的外键创建一个表

可以说我有以下三个表:

现在我要做的是创建人表人的村庄或城镇的外键引用
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.但是当然,我无法将其创建为两个不同表的外键引用同时。

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

这两种方法哪个更好或者是否有更好的方法可以创建外键引用?

+0

是MySql还是Sql-Server?这是两种不同的产品,每种答案都不相同。 –

+0

其MySQL主要我需要一个建议。但是,如果我经历过更严格的SQL服务器,并且如果我需要迁移,我可能不得不记住它。 – Parry

+0

对于sql服务器来说,一种可能的解决方案是创建v_id和t_Id,使用一个检查约束,只允许其中一个为空。 MySql不强制检查约束,因此它不会在那里工作。这只是一个例子,也可能有其他例子。 –

回答

1

对我来说,它看起来像设计有点“如果”。我的假设是,对于一个人,你想知道他的住所是什么,即最终名称是村庄还是城镇?

如果是这样的话,我会删除乡村和城镇表格,并将其替换为包含乡村和城镇的居住查找表格,并且其中有一列到居住类型表格。该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'); 

现在你可以创建一个住宅表,whoch将举行这两个城镇和村庄的名字 - 它必须对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... 

最后你的人表看起来是这样的:

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), 
); 

那我会建议你做的方式。您现在正在遵循规范化等最佳做法。

+0

谢谢,这实际上对我很有意义,我想我倾向于使用它。但我有一个疑问。我需要单独的表的原因是,一个列表是固定的,而另一个是可变的 - 使用简单的例子来解释它,因为这个--- **可以说城镇列表是固定的,不能改变为用户只能从一个具体的城镇,但村名单是可变的,所以用户可以在文本框中添加村名。因此,如果用户居住在城镇,用户从城镇的表格下拉列表中选择,并且村庄用户输入名称(为此我创建了村庄表格)** – Parry

+0

您是否认为您的方法也可以在这种情况下运行还是有更好的办法分开城镇和乡村的桌子。 – Parry

+0

嗨帕里,这是一个前端问题。即前端决定可以做什么。所以我想说我给出的例子可以用于上面的场景。 –

相关问题