从 UML 到 SQL (PostgreSQL)
From UML to SQL (PostgreSQL)
我正在为即将到来的考试进行训练,刚刚完成这个(简单的)练习。
我只是想确保我正确地实现了所有内容,尤其是具有多重性 1 和 0 的 Composition..*
我的回答:
CREATE TABLE exam.A(
idA integer,
b text NOT NULL,
c float DEFAULT -1.0 CONSTRAINT negative_c CHECK (c < 0.0),
PRIMARY KEY(idA));
CREATE TABLE exam.B(
idB integer,
c integer,
PRIMARY KEY(idB));
CREATE TABLE exam.RelationAandB(
idA integer NOT NULL ON DELETE CASCADE,
idB integer,
b integer,
c text,
FOREIGN KEY (idA) REFERENCES exam.A(idA),
FOREIGN KEY (idB) REFERENCES exam.B(idB),
PRIMARY KEY (idA, idB));
您的 SQL 代码非常好,但我发现了以下问题:
- 在 UML class 图中,默认情况下属性是必需的。只有在用多重表达式 [0..1] 限定时,它们才是可选的。因此,所有属性都需要编码为 NOT-NULL 列。但是,您的讲师可能没有意识到这一点,或者正在使用非标准阅读 "UML data models"。
- 字符串值属性 A::b 有一个“{not empty}” 属性 修饰符,读作需要非空字符串的约束。请注意,具有非空字符串值与强制性 (NOT NULL) 不同,因为空字符串 "" 满足 NOT NULL 约束。
- 您还需要在 RelationAandB 中的 idB 上使用 CASCADE DELETE 规则 table,因为无论删除 A 还是 B,RelationAandB 中关联的元组也必须删除。
- 我认为,为了可读性,如果键是非复合键(只有一列),最好将 PRIMARY KEY 声明添加到列定义中。这同样适用于单列 FOREIGN KEY 声明。
- 许多人认为组合意味着删除依赖,尽管这不是 UML 语义所保证的(参见 Aggregation versus Composition),而且它也不基于常识(参见下面我的评论)。在您的 SQL 代码中,您没有实现这样的依赖关系 ("whenever an A is deleted, all dependent Bs have to be deleted as well"),根据 class 图的 UML 语义,这是正确的,但这可能是您的意图讲师,特别是因为他强制要求 B 组件必须具有 A 复合材料(通过复合材料一侧的多重性 1)。这样的 强制组合 约束意味着,当它们的组合被删除时,组件要么也必须被删除,要么必须重新分配给另一个 (A) 组合。如果你的导师的意图是应该有一个删除依赖,那么你最好在 exam.B 中添加一个相应的外键声明从 idB 到 RelationAandB 与 CASCADE DELETE 规则:
idB integer FOREIGN KEY REFERENCES exam.RelationAandB CASCADE DELETE,
关于组合是否意味着组合与其组件之间的生命周期依赖关系的问题,我们必须区分三个抽象级别:1)纯概念(哲学)级别,这应该是常识数据建模器,2) 通常没有精确定义的 UML 语义,以及 3) 代码级别(例如,SQL)。在概念层面上,应该清楚存在具有和不具有这种生命周期依赖性的组合,因此存在组合这一事实本身并不意味着存在生命周期依赖性。
不幸的是,UML 没有定义任何方法来声明组合具有存在依赖的组件。在我的 SO 回答 Aggregation versus Composition 中,我建议对这样的组合使用刻板印象 "inseparable"。
我正在为即将到来的考试进行训练,刚刚完成这个(简单的)练习。
我只是想确保我正确地实现了所有内容,尤其是具有多重性 1 和 0 的 Composition..*
我的回答:
CREATE TABLE exam.A(
idA integer,
b text NOT NULL,
c float DEFAULT -1.0 CONSTRAINT negative_c CHECK (c < 0.0),
PRIMARY KEY(idA));
CREATE TABLE exam.B(
idB integer,
c integer,
PRIMARY KEY(idB));
CREATE TABLE exam.RelationAandB(
idA integer NOT NULL ON DELETE CASCADE,
idB integer,
b integer,
c text,
FOREIGN KEY (idA) REFERENCES exam.A(idA),
FOREIGN KEY (idB) REFERENCES exam.B(idB),
PRIMARY KEY (idA, idB));
您的 SQL 代码非常好,但我发现了以下问题:
- 在 UML class 图中,默认情况下属性是必需的。只有在用多重表达式 [0..1] 限定时,它们才是可选的。因此,所有属性都需要编码为 NOT-NULL 列。但是,您的讲师可能没有意识到这一点,或者正在使用非标准阅读 "UML data models"。
- 字符串值属性 A::b 有一个“{not empty}” 属性 修饰符,读作需要非空字符串的约束。请注意,具有非空字符串值与强制性 (NOT NULL) 不同,因为空字符串 "" 满足 NOT NULL 约束。
- 您还需要在 RelationAandB 中的 idB 上使用 CASCADE DELETE 规则 table,因为无论删除 A 还是 B,RelationAandB 中关联的元组也必须删除。
- 我认为,为了可读性,如果键是非复合键(只有一列),最好将 PRIMARY KEY 声明添加到列定义中。这同样适用于单列 FOREIGN KEY 声明。
- 许多人认为组合意味着删除依赖,尽管这不是 UML 语义所保证的(参见 Aggregation versus Composition),而且它也不基于常识(参见下面我的评论)。在您的 SQL 代码中,您没有实现这样的依赖关系 ("whenever an A is deleted, all dependent Bs have to be deleted as well"),根据 class 图的 UML 语义,这是正确的,但这可能是您的意图讲师,特别是因为他强制要求 B 组件必须具有 A 复合材料(通过复合材料一侧的多重性 1)。这样的 强制组合 约束意味着,当它们的组合被删除时,组件要么也必须被删除,要么必须重新分配给另一个 (A) 组合。如果你的导师的意图是应该有一个删除依赖,那么你最好在 exam.B 中添加一个相应的外键声明从 idB 到 RelationAandB 与 CASCADE DELETE 规则:
idB integer FOREIGN KEY REFERENCES exam.RelationAandB CASCADE DELETE,
关于组合是否意味着组合与其组件之间的生命周期依赖关系的问题,我们必须区分三个抽象级别:1)纯概念(哲学)级别,这应该是常识数据建模器,2) 通常没有精确定义的 UML 语义,以及 3) 代码级别(例如,SQL)。在概念层面上,应该清楚存在具有和不具有这种生命周期依赖性的组合,因此存在组合这一事实本身并不意味着存在生命周期依赖性。
不幸的是,UML 没有定义任何方法来声明组合具有存在依赖的组件。在我的 SO 回答 Aggregation versus Composition 中,我建议对这样的组合使用刻板印象 "inseparable"。