我应该创建两个单独的表只是因为一个不同的列

时间:2015-07-25 17:12:07

标签: php mysql database-design

我的网站有两种类型的用户:companyindividual。它们都具有几乎相同的形式值。 Company还有company_nameindividual还有gender列。

它们之间共有10个字段。现在,我应该创建两个不同的表,还是应该为它们创建单个表?

4 个答案:

答案 0 :(得分:2)

公司和个人似乎是完全不同的实体,所以除非你对它们的处理完全相同,否则最好将它们放在不同的表格上。

但是,如果您期望将公司视为人,并且他们将始终被视为独立单位(没有子单位),您只需在表中添加两个键,一个用于性别(这不是必填字段) ),还有像“公司指标”这样的东西,它是二进制值(是或否)。

然而,真正的问题是可扩展性。如果您预计在任何时候,公司将受到与个人不同的待遇(例如,与公司的联系可能会发生变化,或者如果公司分拆),您真的应该将它们视为单独的实体。您可以在公司表上有一个 person 指标,该指标链接到个人;这样你就可以存储公司内个人的信息。

答案 1 :(得分:2)

有一个原则,有人应该把它们的名字命名为 - 它与墨菲定律或重力定律一样 - 就像这样:在关系数据库的设计阶段采取的任何捷径都会回来咬一口你在后方...通常在它上线后的第二天。

称之为“每日一蹴而就”的原则。

您有一个实体,即用户,由两个子实体组成,即公司和个人。对公司特定属性和特定于个人的属性的正确规范化调用将被移除到单独的表中。但每个这样的属性只有一个。这似乎需要付出很多努力和/或浪费少许结果。

完全没有。

您是否绝对确定以后不会添加其他特定于子实体的属性?

没想到。

这种正常化有许多好处,并且阻止了许多弱点,这使得这一点非常值得付出一点努力。如果,即它已正确完成。

考虑:

create table Users(
    ID      integer   not null auto increment,
    UType   char( 1 ) not null check( UType in( 'C', 'I' )),
    ...     ..., -- common user data
    constraint PK_Users primary key( ID )
);
create unique index IX_UserType on Users( ID, UType );

UType字段只是一个标志,用于指定用户,公司或个人的类型。每个用户必须是一个或另一个。

ID字段是表的PK,因此根据定义,它必须是唯一的。因此,您可能会认为将此字段与UType包含在唯一索引中有点奇怪。如果ID本身是唯一的,则ID和UType的任何组合也必须是唯一的。

真。但该指数使以下成为可能。

create table CompanyUsers(
    ID      integer   not null,
    UType   char( 1 ) not null check( UType = 'C' ),
    Name    varchar( 50 ) not null,
    constraint PK_CompanyUsers primary key ( ID ),
    constraint FK_CompanyUser_User foreign key( ID, UType )
        references Users( ID, UType )
);

create table IndividualUsers(
    ID      integer   not null,
    UType   char( 1 ) not null check( UType = 'I' ),
    Gender  char( 1 ) not null check( Gender in( 'F', 'M' )),
    constraint PK_IndividualUsers primary key ( ID ),
    constraint FK_IndividualUser_User foreign key( ID, UType )
        references Users( ID, UType )
);

具体来说,它使FK参考成为可能。因此,如果用户1001创建为公司用户,则用户指示符“C”包含在UType字段中。因此,ID值为1001的行只能 插入到CompanyUsers表中。该值不能存在于IndividualUsers表中。

因此,不能为个人定义公司数据,反之亦然。此外,可以根据需要在以后添加其他公司特定属性和个人特定属性。仅与公司用户(例如联系人)相关的其他实体可以使其外键引用CompanyUsers表,从而消除可能错误的另一个来源。

大多数用户数据检查可能只需要公共属性,因此大多数时候只会使用一个表。因此,绝对最低限度,我会建议两种观点,一种是仅显示公司用户的加入以获取公司名称,另一种只显示具有联接的个人用户以获得性别。这些将满足您的应用程序的那些必须只考虑一种用户类型或另一种用户类型的部分。

这样的设计不仅比使用快捷方式更安全(不太容易出现异常数据),而且更加强大,并且更容易使用。

答案 2 :(得分:0)

这取决于,如果你有其他表的外键只引用两个表中的一个,你应该将它们都留下,否则你可以将它们合并到一个表中并添加一个字段type

请注意,如果你有外键引用其中一个或两个表,你有第三种可能性:

create table entity(k1 primary key..., other common attributes...);
create table individual (k1, gender..., foreign key(k1) references(entity));
create table company (k1, foreign key(k1) references(entity));

答案 3 :(得分:0)

取决于您使用它们的内容以及其他十个字段。听起来公司和个人只是不同的用户,但可以在您的应用程序中使用大多数可互换的用户。然后将它们放在user表中,如

,这是有意义的
user_id, ..., user_type_id, gender, company_name

其中gendercompany_name可以是NULL,并引入user_type

user_type_id, user_type

持有类型"公司"和"个人"。

要给出一般性答案,如果companyindividual是具有完全不同逻辑的实体,恰好有许多共同属性,我会将它们分开并同时提取共同点数据到其他有意义的表。例如,如果他们中的大多数代表个人或公司的地址,您可以将它们提取到address表。