数据库设计 - 连接表和规范化问题



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

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

2) 每个应用程序都可以通过不同的渠道进行通信,如Internet(电子邮件、Twitter、Facebook)、Phone(短信、MMS等),因此程序和渠道之间存在多对多的关系。

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

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

基本上,我所做的是创建四个表,ProgramChannelIdentCommunicationType,以存储关于每一个表的信息,而不是为(Program, Channel)(Program, Identifier)等创建连接表,这只会使设计复杂化,我创建了一个由这四个表的主键组成的表,并对(Program, Channel, Ident, CommunicationType)进行了唯一约束。现在,这个表的每个记录都链接到一个给定的通信。

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

基本上,我所做的就是四个表,节目,频道,标识和要存储的CommunicationType关于每一个和的信息

这是个好主意。

而不是创建连接表对于(节目,频道),(节目,标识符),等等只是使设计复杂化,我创建由这四个表的主键对(Program,通道、标识、通信类型)。

当你设计这样的表时,你需要注意一件事。您的结构具有键{Program,Channel,Ident,CommunicationType},它允许Program和Channel、Channel和Ident、Program和CommunicationType等各种可能的组合。有时这是个坏主意。

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

这就是为什么它是一个坏主意。您似乎是在说,并非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)
);

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

我不知道你所说的"如果它违背了正常化的原则"是什么意思。一个有四列主键的表不会因为这个原因而违反任何正常形式,尽管它可能是因为其他原因。不能实现所有已知的约束通常是次优设计,但不是因为它违反了任何正常形式。

我不会这么做。

我会在每对(或n对)表之间创建一个连接表。这最终将允许更简单的查询,也将允许您在每种情况下以适当的方式独立于其他情况约束行。

你可能还会发现,在这些连接点上需要额外的归因,比如从一个软件到另一个软件,方向性、有效负载、使用的语言、访问的查询点等。

很抱歉为您提供了一个询问更多信息的答案。在这一点上,我的声誉不容任何评论。。。

根据解释,我看不出选择的设计有什么错。

然而,要想真正回答你的问题,了解你为什么选择这个设计是很有用的。

毕竟,如果没有包含所有键和复合唯一索引的单个表,它也可以工作。以这种方式锁定所有组合是相当严格的。

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

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

最新更新