外键表中其他列的唯一性约束



我有一些事物在任意数量的语言中都有 0-* 名称:

CREATE TABLE Things(
thing_id INT PRIMARY_KEY,
thing_proprty INT);
CREATE TABLE ThingNames(
thing_name_id INT PRIMARY_KEY,
thing_id INT,
language CHAR[2],
name VARCHAR[64] UNIQUE,
FOREIGN KEY (thing_id) REFERENCES Things(thing_id));

这些东西在许多字段中是相关的,并且在每个字段中,每种语言都有 0-1 个规范名称。直接的方法是

CREATE TABLE Fields(
field_id INT PRIMARY_KEY,
name VARCHAR[64])
CREATE TABLE CanonicalNames(
thing_id INT
field_id INT
canonical_name_id INT
FOREIGN KEY (thing_id) REFERENCES Things(thing_id),
FOREIGN KEY (field_id) REFERENCES Fields(field_id),
FOREIGN KEY (canonical_name_id) REFERENCES ThingNames(thing_name_id));

但这错过了 0-1 约束,该约束将是field_id的唯一性约束以及canonical_name_id引用的 ThingNames 的thing_id语言列。在CanonicalNames中将所有列作为外键当然是多余的并且容易出错,那么有没有办法跨表施加唯一性约束呢?还是这里有我没有看到的更好的解决方案?

我不确定你设计中的几件事。将 ThingNames.name 声明为键意味着同一事物在两种不同的语言中不能具有相同的名称,但相关语言(例如挪威语和丹麦语(或技术术语未翻译时似乎可能会发生这种情况。

相关性的概念不会在架构中显式表示。仅当事物至少有一个规范名称(对于某些语言(时才与字段相关?

但是,做出一些假设,我建议使用这个模型(基于Dataphor的伪代码,省略数据类型(:

create table Thing {
ThingId,
ThingProperty,
key { ThingID }
};
create table Field {
FieldId,
FieldName,
key { FieldId },
key { FieldName } // Assumption - or can several Fields have the same name?
};
create table Relevance { // Standard many-to-many association table
ThingId,
FieldId,
key { ThingId, FieldId },
reference Relevance_Thing { ThingId } references Thing { ThingId },
reference Relevance_Field { FieldId } references Field { FieldId }
};
create table ThingName {
ThingName,
Language,
ThingId,
key { ThingName, Language }, // Assuming the same thing may have the same name in different languages
reference ThingName_Thing { ThingId } references Thing { ThingId }
};
create table CanonicalName {
ThingId,
FieldId,
Language,
CanonicalName,
key { ThingId, FieldId, Language },
reference CanonicalName_Relevance { ThingId, FieldId } references Relevance { ThingId, FieldId },
reference CanonicalName_ThingName { ThingId, Language, CanonicalName } references ThingName { ThingId, Language, ThingName }
};

由于 FD{ Canonicalname, Language } -> { ThingId },CanonicalName 不在 BCNF 中,但冗余由引用CanonicalName_ThingName控制。(你可以称之为外键,但它实际上是一个外超键。这不是错误,而是您如何确保规范名称是事物名称之一。(我假设这是一个规则。在此设计中,在 CanonicalName 中使用"语言"列不是多余的,它会启用您缺少的 0-1 约束。

此设计允许多个事物在不同的语言中具有相同的名称,但也允许不同的事物在不同的语言中具有相同的名称。例如,"kjole"在挪威语和丹麦语中的意思是"衣服",但挪威语中的"dress"在英语中的意思是"西装"。让我知道这是否应该被禁止,我会更新设计。

如果存在一条规则,即当且仅当该字段至少有一个规范名称时,则可能(或可能应该(省略相关性表。当然,CanonicalName 必须引用 Field 而不是 Relegance。

最新更新