Has*_*ena 15 postgresql foreign-key
我是 postgreSQL 的新手。我有 3 个表,一个表引用其他 2 个表的主键。但是我无法将数据插入到Table3. 请参阅下面的代码:
DROP TABLE Table1 CASCADE;
CREATE TABLE Table1(
"DataID" bigint NOT NULL DEFAULT '0',
"AdData" integer DEFAULT NULL,
PRIMARY KEY ("DataID")
);
DROP TABLE IF EXISTS Table2 CASCADE;
CREATE TABLE Table2 (
"Address" numeric(20) NOT NULL DEFAULT '0',
"Value" numeric(20) DEFAULT NULL,
PRIMARY KEY ("Address")
);
DROP TABLE IF EXISTS Table3 CASCADE;
CREATE TABLE table3 (
"ID" bigint NOT NULL DEFAULT '0',
"DataID" bigint DEFAULT NULL,
"Address" numeric(20) DEFAULT NULL,
"Data" bigint DEFAULT NULL,
PRIMARY KEY ("ID"),
FOREIGN KEY ("DataID") REFERENCES Table1("DataID") on delete cascade on update cascade,
FOREIGN KEY ("Address") REFERENCES Table2("Address") on delete cascade on update cascade
);
Run Code Online (Sandbox Code Playgroud)
错误:插入或更新表“Table3”违反外键约束“Table3_DataID_fkey”详细信息:表“Table1”中不存在键 (DataID)=(27856)。
当我尝试将数据插入到 3 个表中时,发生了错误。我参考了postgreSQL 文档并按如下方式更改了我的代码:(不幸的是它显示了另一个错误)
DROP TABLE Table1 CASCADE;
CREATE TABLE Table1(
"DataID" bigint NOT NULL DEFAULT '0',
"AdData" integer DEFAULT NULL,
PRIMARY KEY ("DataID")
);
DROP TABLE IF EXISTS Table2 CASCADE;
CREATE TABLE Table2 (
"Address" numeric(20) NOT NULL DEFAULT '0',
"Value" numeric(20) DEFAULT NULL,
PRIMARY KEY ("Address")
);
DROP TABLE IF EXISTS Table3 CASCADE;
CREATE TABLE table3 (
"ID" bigint NOT NULL DEFAULT '0',
"DataID" bigint DEFAULT NULL REFERENCES Table1 ON DELETE RESTRICT,
"Address" numeric(20) DEFAULT NULL REFERENCES Table2 ON DELETE CASCADE,
"Data" bigint DEFAULT NULL,
PRIMARY KEY ("ID"),
PRIMARY KEY("DataID", "Address")
);
Run Code Online (Sandbox Code Playgroud)
错误:不允许表“Table3”的多个主键第 65 行:PRIMARY KEY("DataID", "Address")
请帮助我...我如何创建参考?
我更改了IDasUNIQUE并删除了该行PRIMARY KEY ("ID")。当时它显示了另一个错误,例如:
错误:重复键值违反唯一约束“Table3_pkey”
dez*_*zso 20
您的表存在一些问题。我会先尝试解决外键,因为您询问了它们:)
但在此之前,我们应该意识到这两组表(您创建的前三组和您删除第一组后创建的第二组)是相同的。当然,Table3你第二次尝试中的定义有语法和逻辑错误,但基本思想是:
CREATE TABLE table3 (
"ID" bigint NOT NULL DEFAULT '0',
"DataID" bigint DEFAULT NULL,
"Address" numeric(20) DEFAULT NULL,
"Data" bigint DEFAULT NULL,
PRIMARY KEY ("ID"),
FOREIGN KEY ("DataID") REFERENCES Table1("DataID") on delete cascade on update cascade,
FOREIGN KEY ("Address") REFERENCES Table2("Address") on delete cascade on update cascade
);
Run Code Online (Sandbox Code Playgroud)
这个定义告诉 PostgreSQL 大致如下:“创建一个有四列的表,一个是主键(PK),其他可以是NULL。如果插入新行,检查DataID和Address:如果它们包含非 NULL 值(说27856),然后检查Table1了DataID?和Table2了Address。如果有这些表中没有这样的值,然后返回一个错误。” 您首先看到的最后一点:
ERROR: insert or update on table "Table3" violates foreign key constraint
"Table3_DataID_fkey" DETAIL: Key (DataID)=(27856) is not present in table "Table1".
Run Code Online (Sandbox Code Playgroud)
很简单:如果Table1where 中没有行DataID = 27856,则不能将该行插入到Table3.
如果您需要该行,您应该首先在Table1with 中插入一行DataID = 27856,然后再尝试插入到 中Table3。 如果这在您看来不是您想要的,请用几句话描述您想要实现的目标,我们可以帮助您进行良好的设计。
现在关于其他问题。
您将 PK 定义为
CREATE all_your_tables (
first_column NOT NULL DEFAULT '0',
[...]
PRIMARY KEY ("ID"),
Run Code Online (Sandbox Code Playgroud)
主键意味着其中的所有项都互不相同,即值为UNIQUE。如果你给一个列一个静态DEFAULT(如'0')UNIQUE,你会一直遇到糟糕的惊喜。这就是您在第三条错误消息中得到的信息。
此外,'0'表示文本字符串,而不是数字(bigint或numeric在您的情况下)。简单地使用0(或者根本不使用它,正如我上面写的那样)。
最后一点(我可能在这里错了):在 中Table2,您的Address字段设置为numeric(20). 同时,又是表的PK。列名和数据类型表明此地址将来可能会更改。如果这是真的,那么这对于 PK 来说是一个非常糟糕的选择。想想以下情形:您有一个地址“1234567890454”,其中有一个孩子Table3喜欢
ID DataID Address Data
123 3216547 1234567890454 654897564134569
Run Code Online (Sandbox Code Playgroud)
现在该地址碰巧更改为其他地址。你如何让你的孩子Table3跟随它的父母到新地址?(对此有一些解决方案,但可能会引起很多混乱。)如果是这种情况,请在表中添加一个 ID 列,该列将不包含来自现实世界的任何信息,它将仅用作标识值(即, ID) 为地址。
| 归档时间: |
|
| 查看次数: |
152140 次 |
| 最近记录: |