[英]postgresql no unique constraint error
I get for this schema this error: 我为这个模式得到这个错误:
ERROR: there is no unique constraint matching given keys for referenced table "abteilung"
What I am doing wrong? 我做错了什么? EDIT: now I add a column krankenhaus to the table mitarbeiter and change the alter table command but I get the same error...
编辑:现在我将列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;
The primary key of the table Abteilung
is (abid, krankenhaus)
. 表
Abteilung
的主键是(abid, krankenhaus)
。 As a foreign references references exactly one row, you also need to use both columns in the foreign key constraint definition. 由于外部引用仅引用一行,因此您还需要在外键约束定义中同时使用两列。
But as you don't have a column krankenhaus
in your table Mitarbeiter
you can't reference Abteilung
. 但是当你没有列
krankenhaus
在你的表Mitarbeiter
你不能引用Abteilung
。
You either need to reduce the primary key of Abteilung
to (abid)
(which would be possible as it is a generated, artificial key anyway) or add a column Krankenhaus
to your Mitarbeiter
table. 您或者需要将
Abteilung
的主键减小为(abid)
(因为无论如何它都是生成的人工键,这都是可能的),或者在Mitarbeiter
表中添加一列Krankenhaus
。
This should work: 这应该工作:
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;
Use a serial
column for surrogate PKs: 将
serial
列用于替代PK:
Don't use varchar(n)
with arbitrary limitations for string length, unless you really need to enforce a maximum length and its not going to change. 请勿对字符串长度使用具有任意限制的
varchar(n)
,除非您确实需要强制执行最大长度且该长度不会改变。 Details: 细节:
Go with just abid
as primary key for abteilung
. 一起去的只是
abid
作为主键abteilung
。 There would be a related application for a redundant column included in a FK constraint, but that's not what your model does right now: 有将是包含在FK约束冗余列相关的应用程序,但是这是你的模型确实现在不是:
No need to use an explicit transaction ( BEGIN ... COMMIT
) for part of the code. 无需为部分代码使用显式事务(
BEGIN ... COMMIT
)。
The real difficulty with this kind of circular reference is entering and changing data. 这种循环引用的真正困难在于输入和更改数据。 You probably made your FK constraints
DEFERRABLE INITIALLY DEFERRED
- which is going to make some queries considerably slower . 您可能使FK约束
DEFERRABLE INITIALLY DEFERRED
-这将使某些查询变得相当慢 。
You could go with just plain default IMMEDIATE
FK constraints, if you wrap INSERT / UPDATE on related rows into data-modifying CTEs : 如果将相关行上的INSERT / UPDATE包装到可修改数据的CTE中 ,则可以使用普通的默认
IMMEDIATE
FK约束:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.