首页 > 解决方案 > 从 UML 到 SQL (PostgreSQL)

问题描述

我正在为即将到来的考试进行培训,并且刚刚完成了这个(简单的)练习。

我只是想确保我正确地实现了一切,尤其是具有多重性 1 和 0 的组合 ..*

我的运动

我的答案:

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));

标签: sqlpostgresqluml

解决方案


您的 SQL 代码非常好,但我看到以下问题:

  1. 在 UML 类图中,默认情况下属性是必需的。仅当使用多重性表达式 [0..1] 进行限定时,它们才是可选的。因此,所有属性都需要编码为 NOT-NULL 列。但是,您的讲师可能没有意识到这一点,或者正在对“UML 数据模型”使用非标准阅读。
  2. 字符串值属性 A::b 有一个 "{not empty}" 属性修饰符,它读作要求非空字符串的约束。请注意,具有非空字符串值与强制 (NOT NULL) 不同,因为空字符串 "" 满足 NOT NULL 约束。
  3. 您还需要在 RelationAandB 表中的 idB 上使用 CASCADE DELETE 规则,因为无论删除 A 还是 B,都必须删除 RelationAandB 中的关联元组。
  4. 我认为,为了可读性,如果键是非复合的(只有一列),最好将 PRIMARY KEY 声明添加到列定义中。单列 FOREIGN KEY 声明也是如此。
  5. 许多人认为组合意味着删除依赖,尽管这不是 UML 语义所保证的(参见Aggregation vs Composition),而且它也不是基于常识(参见我下面的评论)。在您的 SQL 代码中,您没有实现这样的依赖关系(“每当删除 A 时,所有依赖的 B 也必须删除”),根据类图的 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 vs Composition中,我建议对这种组合使用“不可分割”的刻板印象。


推荐阅读