我得到这个架构这个错误:
ERROR: there is no unique constraint matching given keys for referenced table "abteilung"
我做错了什么? 编辑:现在我添加一个列krankenhaus到表mitarbeiter并更改alter table命令,但我得到相同的错误...
SCHEMA:
CREATE TABLE Person (
svnr VARCHAR(40) PRIMARY KEY,
anschrift VARCHAR(40) NOT NULL,
name VARCHAR(20) NOT NULL
);
BEGIN;
CREATE TABLE Mitarbeiter (
svnr VARCHAR(40) PRIMARY KEY REFERENCES Person(svnr),
beschaeftigt_seit DATE NOT NULL,
gehalt NUMERIC(5,2),
CHECK(gehalt > 0),
abteilung INTEGER NOT NULL,
krankenhaus INTEGER NOT NULL
);
CREATE TABLE Krankenhaus (
kid INTEGER PRIMARY KEY DEFAULT nextval('seq_krankenhaus'),
anschrift VARCHAR(40) NOT NULL,
name VARCHAR(20) NOT NULL,
geleitet_von VARCHAR(40) REFERENCES Mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
);
CREATE TABLE Abteilung (
abid INTEGER DEFAULT nextval('seq_abteilung'),
name VARCHAR(40) NOT NULL,
anschrift VARCHAR(40) NOT NULL,
koordiniert VARCHAR(40) REFERENCES Mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED,
krankenhaus INTEGER REFERENCES Krankenhaus(kid),
PRIMARY KEY (abid, krankenhaus)
);
ALTER TABLE Mitarbeiter ADD CONSTRAINT fk_abteilung FOREIGN KEY (abteilung, krankenhaus) REFERENCES Abteilung(abid, krankenhaus) DEFERRABLE INITIALLY DEFERRED;
COMMIT;
答案 0 :(得分:3)
表Abteilung
的主键是(abid, krankenhaus)
。由于外部引用只引用了一行,因此还需要在外键约束定义中使用两个列。
但由于您的表krankenhaus
中没有列Mitarbeiter
,因此无法引用Abteilung
。
您需要将Abteilung
的主键缩减为(abid)
(这可能是因为它是生成的人工密钥)或向Krankenhaus
添加Mitarbeiter
{1}}表。
答案 1 :(得分:0)
这应该有效:
CREATE TABLE person (
svnr text PRIMARY KEY
, anschrift text NOT NULL
, name text NOT NULL
);
CREATE TABLE mitarbeiter (
svnr text PRIMARY KEY REFERENCES person
, beschaeftigt_seit date NOT NULL
, gehalt numeric(5,2)
, abid int NOT NULL
, CHECK(gehalt > 0)
);
CREATE TABLE krankenhaus (
kid serial PRIMARY KEY
, anschrift text NOT NULL
, name text NOT NULL
, geleitet_von text REFERENCES mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
);
CREATE TABLE abteilung (
abid serial PRIMARY KEY
, kid INTEGER REFERENCES krankenhaus(kid)
, koordiniert text REFERENCES mitarbeiter(svnr) DEFERRABLE INITIALLY DEFERRED
, name text NOT NULL
, anschrift text NOT NULL
);
ALTER TABLE mitarbeiter
ADD CONSTRAINT fk_abteilung FOREIGN KEY (abid)
REFERENCES abteilung(abid) DEFERRABLE INITIALLY DEFERRED;
使用serial
列替代代理PK:
不要对字符串长度使用varchar(n)
任意限制,除非您确实需要强制执行最大长度且不会更改。详细说明:
仅使用abid
作为abteilung
的主键。 将作为FK约束中包含的冗余列的相关应用程序,但这不是您的模型现在所做的:
不需要为部分代码使用显式事务( BEGIN ... COMMIT
)。
这种循环引用的真正困难在于输入和更改数据。您可能已经制定了FK约束DEFERRABLE INITIALLY DEFERRED
- 这会使某些查询显着更慢。
如果将相关行的INSERT / UPDATE包装到数据修改CTE 中,可以只使用普通的默认IMMEDIATE
FK约束: