表上的唯一约束

时间:2017-08-24 17:01:52

标签: sql postgresql unique-constraint postgresql-9.6

我有以下表格定义:

CREATE TABLE modules(
    id  integer PRIMARY KEY)

CREATE TABLE submodules(
    id          integer PRIMARY KEY,
    identnum    integer)

CREATE TABLE usablesubmodules(
    moduleid    integer REFERENCES modules(id),
    submoduleid integer REFERENCES submodules(id))

基本上是一个模块表和一个子模块表。模块只能使用availablesubmodules表定义的某些子模块。如何定义约束,以便任何给定模块可用的子模块的identnum值是唯一的?也就是说,以下查询必须为任何给定的moduleid'x'返回一组唯一的identnum值:

SELECT identnum FROM submodules
INNER JOIN usablesubmodules ON submodules.id = usablesubmodules.submoduleid
WHERE usablesubmodules.moduleid = x

如果重要,我正在使用postgresql 9.6。

2 个答案:

答案 0 :(得分:1)

not null上设置唯一性和submodules.identnum约束。

CREATE TABLE submodules(
    id          integer PRIMARY KEY,
    identnum    integer UNIQUE NOT NULL);

usablesubmodules表格上创建复合PK。

CREATE TABLE usablesubmodules(
    moduleid    integer REFERENCES modules(id),
    submoduleid integer REFERENCES submodules(id)
    PRIMARY KEY (moduleid, submoduleid));

...或...

CREATE TABLE usablesubmodules(
    moduleid    integer REFERENCES modules(id),
    identnum    integer REFERENCES submodules(identnum)
    PRIMARY KEY (moduleid, identnum));

上述任何一种情况都可以保证您不会多次与模块关联identnum

identnum表格中submodules的唯一性约束可确保您只能为给定的submodules提供一条identnum条记录。

usablesubmodules上的复合主键可确保您永远不会有多个具有相同moduleididentnum的记录。

答案 1 :(得分:0)

您实际上有两个约束:

  • {module,submodule}必须是唯一的
  • 此对必须存在于allowed_pa​​irs中(它也必须是唯一的)

- \ t tmp.sql

CREATE TABLE modules(
        m_id integer PRIMARY KEY
        );

CREATE TABLE submodules(
        s_id integer PRIMARY KEY
        );

CREATE TABLE allowed_submodules(
        m_id integer NOT NULL REFERENCES modules(m_id)
        , s_id integer NOT NULL REFERENCES submodules(s_id)
        , PRIMARY KEY (m_id, s_id)
        );

CREATE TABLE used_submodules(
        m_id integer NOT NULL
        , s_id integer NOT NULL
        , PRIMARY KEY (m_id, s_id)
        ,  FOREIGN KEY (m_id,s_id) REFERENCES allowed_submodules(m_id,s_id)
        );

更新:如果你坚持保留(冗余的,恕我直言)附加密钥列identnum,这里可以将其添加到used_submodules表中。

CREATE TABLE used_submodules(
        m_id integer NOT NULL
        , s_id integer NOT NULL
        ,  PRIMARY KEY (m_id, s_id)
        ,  FOREIGN KEY (m_id, s_id) REFERENCES allowed_submodules(m_id, s_id)
        , identnum integer NOT NULL
        ,  UNIQUE (m_id, identnum)
        );