基本上,我所做的是创建四个表,Program、Channel、Ident 和 CommunicationType 来存储有关每个表的信息,并且,
这是个好主意。
我没有为 (Program, Channel)、(Program, Identifier) 等创建联结表,这只会使设计复杂化,而是创建了一个由这四个表的主键组成的表,并对 (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)
);
根据需要添加其他列。在某些情况下,您可能会发现需要重叠的外键。我认为您在这里不需要它们,但我可能是错的。
我不确定“如果它违反规范化原则”是什么意思。具有四列主键的表不会仅仅因为这个原因而违反任何正常形式,尽管它可能是由于其他原因。未能实现所有已知的约束通常是,嗯,次优设计,但不是因为它违反了任何正常形式。