连接表&规范化问题

时间:2011-07-02 23:42:47

标签: database-design normalization junction-table

我很难弄清楚以下设计模式是否可以接受。对于关系模型,我有以下要求(以及其他一些要求):

1)它必须能够代表应用程序(例如AppAAppBAppC),每个应用程序都有自己的属性集。

2)每个应用程序都可以通过Internet(电子邮件,Twitter,Facebook),Phone(短信,彩信等)等不同渠道进行通信,以便有多对多的通道节目与频道之间的关系。

3)有一组预定义的标识符(地址,电话号码,登录帐户)可以被许多程序共享,因此,程序和标识符之间也存在多对多的关系。

4)相同的标识符可以发送多种类型的消息,程序也可以发送(多次),但我需要能够在每个应用程序的基础上限制通信类型标识符的使用

基本上,我所做的是创建四个表ProgramChannelIdentCommunicationType来存储有关每个表的信息,而不是创建联结(Program, Channel)(Program, Identifier)等表格会使设计复杂化,我创建了一个单独的表,其中包含这四个表的主键以及(Program, Channel, Ident, CommunicationType)上的唯一约束。现在,该表的每条记录都与给定的通信相关联。

当然,这以一种非常简单的方式解决了我的问题,但现在我在质疑自己这是否可以接受,如果它违背了规范化的原则。有人可以给我一个意见吗?

3 个答案:

答案 0 :(得分:1)

很抱歉为您提供了一个要求提供更多信息的答案。我此时的声誉不允许发表评论......

根据解释,我认为所选设计没有任何问题。

但是,要真正回答您的问题,了解您选择此设计的原因将非常有用。

毕竟它也可以在没有单个表的情况下使用所有键和复合唯一索引。以这种方式锁定所有组合是相当有限的。

当您找到通信后,您仍然必须加入一个或多个其他表来访问构成通信的信息。

为什么要以这种方式存储每个唯一的通信路径?

答案 1 :(得分:1)

我不会这样做。

我会在表的每对(或n元组)之间创建一个联结表。这样可以在最后进行更简单的查询,并且还允许您根据需要以适当的方式约束行,而不管其他情况如何。

您可能还会发现这些联结需要额外的归属,例如从一个软件到另一个软件,方向性,有效负载,使用的语言,正在访问的查询点等等。

答案 2 :(得分:1)

  

基本上,我所做的就是创造   四个表,Program,Channel,Ident   和CommunicationType存储   关于其中每一项的信息,

这是一个好主意。

  

而不是创建联结表   for(Program,Channel),(P​​rogram,   标识符),等等   我创建的只是使设计复杂化   由...组成的单个表   这四个表的主键有   一个独特的约束(程序,   Channel,Ident,CommunicationType)。

当你设计这样的表时,你需要小心一件事。您的结构具有密钥{Program,Channel,Ident,CommunicationType},允许Program和CommunicationType的Program和Channel,Channel和Ident的所有可能组合,等等。有时这是个坏主意。

  

相同的标识符可以发送多个   消息的类型,以及   程序(再次,多对多),但我   需要能够限制使用   通信类型的标识符   每个应用程序。

这就是让它成为一个坏主意的原因。您似乎在说,并非Ident,Program和CommunicationsType的每个组合都有效。

将有效组合存储在自己的表中。使用外键引用来维护数据完整性。

构建一个具有密钥{Program,Ident,CommunicationsType}的表。具有密钥{Program,Channel,Ident,CommunicationType}的表可以设置对它的外键引用。

构建尽可能多的表来实现您所知道的所有约束。更多表意味着数据完整性检查更简单。 (您可能需要比我提到的表更多的表。不要假设它们需要有两列;它们可能需要更多。)

根本不清楚你需要一个键入的表{Program,Channel}。但是如果你这样做,那么你需要在这些方面构建表格。 (航空代码。)

create table pc (
    program_name varchar(10) not null references programs (program_name),
    channel_name varchar(10) not null references channels (channel_name),
    primary key (program_name, channel_name)
);

create table pict (
    program_name varchar(10) not null,
    channel_name varchar(10) not null,
    comm_type varchar(10) not null references communication_type (comm_type),
    primary key (program_name, channel_name, comm_type),
    foreign key (program_name, channel_name) 
        references pc (program_name, channel_name) 
);

create table your-table-name (
    program_name varchar(10) not null,
    channel_name varchar(10) not null,
    comm_type varchar(10) not null,
    ident varchar(10) not null,
    primary key (program_name, channel_name, comm_type, ident),
    foreign key (program_name, channel_name, comm_type) 
        references pict (program_name, channel_name, comm_type),
    foreign key (ident) references ident (ident)
);

根据需要添加其他列。在某些情况下,您可能会发现需要重叠外键。我不认为你在这里需要它们,但我可能错了。

我不确定你的意思是“如果它违背了规范化的原则”。由于其他原因,具有四列主键的表不会仅因为该原因而违反任何常规表单。未能实现所有已知约束通常是次优设计,但不是因为它违反了任何正常形式。