【问题标题】:Relational schema and integrity constraints关系模式和完整性约束
【发布时间】:2021-08-03 00:54:11
【问题描述】:

请问是否可以使用创建脚本在此架构上创建这些完整性约束?

  1. 俱乐部 (klub) 只能有一名教练 (trener)
  2. 俱乐部只能有一位所有者 (majitel)
  3. 每个成员 (člen) 只能加入一个俱乐部
  4. 教练只能为他的俱乐部设置战术 (taktika)?

是否可以通过创建脚本中的完整性约束来解决这个问题,或者是否使用触发器来解决这个问题?我是我的创建脚本的一部分。

架构

创建脚本

CREATE TABLE club (
id_club SERIAL NOT NULL,
nazev VARCHAR(256) NOT NULL,
datum_zalozeni VARCHAR(256) NOT NULL
);
ALTER TABLE club ADD CONSTRAINT pk_club PRIMARY KEY (id_club);
ALTER TABLE club ADD CONSTRAINT uc_club_nazev UNIQUE (nazev);

CREATE TABLE coach (
    id_member INTEGER NOT NULL
);
ALTER TABLE coach ADD CONSTRAINT pk_coach PRIMARY KEY (id_member);

CREATE TABLE member (
    id_member SERIAL NOT NULL,
    id_club INTEGER NOT NULL,
    jmeno VARCHAR(256) NOT NULL,
    prijmeni VARCHAR(256) NOT NULL,
    narodnost VARCHAR(256) NOT NULL,
    datum_narozeni VARCHAR(256) NOT NULL
);
ALTER TABLE member ADD CONSTRAINT pk_member PRIMARY KEY (id_member);

CREATE TABLE owner (
    id_member INTEGER NOT NULL
);
ALTER TABLE owner ADD CONSTRAINT pk_owner PRIMARY KEY (id_member);

CREATE TABLE player (
    id_member INTEGER NOT NULL,
    cislo VARCHAR(256) NOT NULL,
    post VARCHAR(256) NOT NULL
);
ALTER TABLE player ADD CONSTRAINT pk_player PRIMARY KEY (id_member);

ALTER TABLE coach ADD CONSTRAINT fk_coach_member FOREIGN KEY (id_member) REFERENCES member (id_member) ON DELETE CASCADE;

ALTER TABLE member ADD CONSTRAINT fk_member_club FOREIGN KEY (id_club) REFERENCES club (id_club) ON DELETE CASCADE;

ALTER TABLE owner ADD CONSTRAINT fk_owner_member FOREIGN KEY (id_member) REFERENCES member (id_member) ON DELETE CASCADE;

ALTER TABLE player ADD CONSTRAINT fk_player_member FOREIGN KEY (id_member) REFERENCES member (id_member) ON DELETE CASCADE;
enter code here
enter code here

【问题讨论】:

  • 您写道,俱乐部应该只有一个trener,但在您的架构中,您只有一个与clen 关联的教练。 clen 还分配了一个俱乐部。问题是您是否希望对clen 表进行约束以限制进入具有相同俱乐部但不同培训师的 2 名成员,或者您是否允许在您的表中添加新列(特别是klub)。
  • 但是如果我在俱乐部里加了一个专栏,我还是得看看它,这样我就不会再加教练了。
  • 我再次查看了架构 - 我看到 trener 有字段 id_clen。这应该解释为“教练是会员”?
  • 成员可以是球员、教练或老板...... r 任何功能组合,同时所有三个......但不能有更多的团队......同时每支球队必须只有一名教练和一名老板

标签: sql postgresql database-design foreign-keys


【解决方案1】:

无法对当前架构强制实施所需的约束。您需要的是唯一约束,但唯一约束适用于单表数据,并且您没有包含成员角色和俱乐部信息的表。

为了实现它们,您必须将带有角色信息的新列添加到 clen 表(成员),或将俱乐部信息添加到 trener 和 majitel 表。因为一个成员可以有多个角色,所以第一个解决方案不是一个选项。

仅添加一个俱乐部可能会导致数据一致性问题(有人更改了会员的俱乐部 ID,但没有更改教练的 ID)。为了保证完整性,我在一对(member_id、club_id)上添加了外键。

结果是:

CREATE TABLE club (
id_club SERIAL NOT NULL,
nazev VARCHAR(256) NOT NULL,
datum_zalozeni VARCHAR(256) NOT NULL
);
ALTER TABLE club ADD CONSTRAINT pk_club PRIMARY KEY (id_club);
ALTER TABLE club ADD CONSTRAINT uc_club_nazev UNIQUE (nazev);

CREATE TABLE coach (
    id_member INTEGER NOT NULL
);
ALTER TABLE coach ADD CONSTRAINT pk_coach PRIMARY KEY (id_member);

CREATE TABLE member (
    id_member SERIAL NOT NULL,
    id_club INTEGER NOT NULL,
    jmeno VARCHAR(256) NOT NULL,
    prijmeni VARCHAR(256) NOT NULL,
    narodnost VARCHAR(256) NOT NULL,
    datum_narozeni VARCHAR(256) NOT NULL
);
ALTER TABLE member ADD CONSTRAINT pk_member PRIMARY KEY (id_member);

CREATE TABLE owner (
    id_member INTEGER NOT NULL
);
ALTER TABLE owner ADD CONSTRAINT pk_owner PRIMARY KEY (id_member);

CREATE TABLE player (
    id_member INTEGER NOT NULL,
    cislo VARCHAR(256) NOT NULL,
    post VARCHAR(256) NOT NULL
);
ALTER TABLE player ADD CONSTRAINT pk_player PRIMARY KEY (id_member);

ALTER TABLE coach ADD CONSTRAINT fk_coach_member FOREIGN KEY (id_member) REFERENCES member (id_member) ON DELETE CASCADE;

ALTER TABLE member ADD CONSTRAINT fk_member_club FOREIGN KEY (id_club) REFERENCES club (id_club) ON DELETE CASCADE;

ALTER TABLE owner ADD CONSTRAINT fk_owner_member FOREIGN KEY (id_member) REFERENCES member (id_member) ON DELETE CASCADE;

ALTER TABLE player ADD CONSTRAINT fk_player_member FOREIGN KEY (id_member) REFERENCES member (id_member) ON DELETE CASCADE;

--We need a unique constraint on (id_member, id_club), to be able to use the pair in a foreign key.
ALTER TABLE member ADD CONSTRAINT unq_member_and_club UNIQUE(id_member, id_club);

--Req. 1: club (klub) can have exactly one coach (trener)
ALTER TABLE coach ADD COLUMN id_club integer;
ALTER TABLE coach ADD CONSTRAINT fk_coach_club FOREIGN KEY (id_club) REFERENCES club (id_club);
ALTER TABLE coach ADD CONSTRAINT fk_coach_member_and_club FOREIGN KEY (id_member, id_club) REFERENCES member (id_member, id_club);
ALTER TABLE coach ADD CONSTRAINT fk_single_coach_per_club UNIQUE(id_club);

--Req. 2: club can have just one owner (majitel)
ALTER TABLE owner ADD COLUMN id_club integer;
ALTER TABLE owner ADD CONSTRAINT fk_owner_club FOREIGN KEY (id_club) REFERENCES club (id_club);
ALTER TABLE owner ADD CONSTRAINT fk_owner_member_and_club FOREIGN KEY (id_member, id_club) REFERENCES member (id_member, id_club);
ALTER TABLE owner ADD CONSTRAINT fk_single_owner_per_club UNIQUE(id_club);

您可以在db<>fiddle中测试脚本。

请注意,我添加了fk_coach_club 和fk_owner_club 外键约束,尽管它们不是强制性的。 fk_member_club、fk_owner_member_and_club 和 fk_coach_member_and_club 一起确保 club_id 值在 owner 和 coach 表中始终有效,但如果我觉得拥有这些 FK 是自然的。

要求。 3 每个成员 (člen) 只能在一个俱乐部中 在您的架构中无需更改任何内容,成员具有俱乐部属性,无法将另一个俱乐部分配给单个成员。

对于Req.4没有特殊限制,教练只能为他的俱乐部设置战术(taktika),因为战术是由分配给单个俱乐部的教练设置的,所以没有需要约束。

【讨论】:

  • 请问究竟如何 ALTER TABLE member ADD CONSTRAINT unq_member_and_club UNIQUE(id_member, id_club);作品?这真的会阻止一名成员加入多个团队吗?例如,这是否会阻止 id = 2 的成员在团队 1 中同时在团队 2 中?
  • 例如,它会阻止我这样做吗? id_clen = 2 id_klub = 1; id_clen = 2 id_klub = 2; ?
  • unq_member_and_club 不保证会员不属于多个俱乐部 - 会员表的结构确保了这一点。该表有 club_id 字段,因此无法为单个成员输入 2 个不同的值。 unq_member_and_club 需要在外键中使用密钥对(member_id, club_id)。外键不允许在表owner 和coach 中输入不同于member.id_club 的值。我已根据您的 cmets 更改了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
相关资源
最近更新 更多