【问题标题】:PostgreSQL: Foreign Key to a table with 3 Primary Keys on PgAdminPostgreSQL:PgAdmin 上具有 3 个主键的表的外键
【发布时间】:2020-03-09 05:23:50
【问题描述】:

我有一个名为 table2 的表,它有 3 个 PK、categoryid、languageid 和 unitid。我正在尝试从 table1 到 table2 进行 FK。但由于下一个错误,我无法添加 FK 约束:

关于英文:“错误没有唯一的限制与 units 表中的列重合”

表 2:

表 1:

约束:

在 PSQL 上

表 2(单位)

                              Tabla ½public.units╗
       Columna       |       Tipo       | Ordenamiento | Nulable  | Por omisi¾n
---------------------+------------------+--------------+----------+-------------
 unitdisplayname     | text             |              |          |
 unitdescription     | text             |              |          |
 unitid              | integer          |              | not null |
 conversionfactor    | double precision |              |          |
 typesystem          | text             |              |          |
 prefixfactor        | integer          |              |          |
 categorydisplayname | text             |              |          |
 categoryid          | integer          |              | not null |
 languageid          | text             |              | not null |
═ndices:
    "units_pkey" PRIMARY KEY, btree (unitid, categoryid, languageid)

我正在尝试的 SQL 语句:

CREATE TABLE public.units_sensores
(
    id_rel integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 ),
    obra integer NOT NULL,
    edificio_serverguid integer NOT NULL,
    categoryid integer NOT NULL,
    unitid integer NOT NULL,
    PRIMARY KEY (id_rel),
    CONSTRAINT obras FOREIGN KEY (obra)
        REFERENCES public.obras (id_obra) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT edificios_serverguid FOREIGN KEY (edificio_serverguid)
        REFERENCES public.edificios_trend_meta (id_edificio) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT categoryid FOREIGN KEY (categoryid)
        REFERENCES public.units (categoryid) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT unitid FOREIGN KEY (unitid)
        REFERENCES public.units (unitid) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
);

ALTER TABLE public.units_sensores
    OWNER to postgres;

总结:

我想知道如何将其写入 postgreSQL:

reate Table A (
    A_ID char(3) primary key,
    A_name char(10) primary key,
    A_desc desc char(50)
)

create Table B (
    B_ID char(3) primary key,
    B_A_ID char(3),
    B_A_Name char(10),
    constraint [Fk_B_01] foreign key (B_A_ID,B_A_Name) references A(A_ID,A_Name)
)

【问题讨论】:

  • 我不明白您的客户端 GUI 生成的时髦图像。你能与psql 连接并显示\d tablename 的两个表的结果吗(文本,请不要图像)?另外,导致错误的 SQL 语句是什么?
  • 我更新了问题。我正在使用 pgAdmin,当我尝试使用 FK 到单位表创建一个新表时会弹出错误。 @LaurenzAlbe
  • 外键必须在 3 列上定义。没有 SQL 语句,我无法查明错误。
  • PSQL 上的答案也将不胜感激 :) @LaurenzAlbe
  • 我用 SQL 命令@LaurenzAlbe 更新了问题

标签: database postgresql pgadmin postgresql-11


【解决方案1】:

您无法创建该外键约束,因为units(category_id) 上没有唯一约束。

对于外键,您需要在目标列上精确定义的 PRIMARY KEYUNIQUE 约束。此约束标识目标行。

包含其他列的唯一约束还不够好,因为目标表中仍然可能有不止一行具有相同的category_id

由于一个表只能有一个主键约束,你必须使用UNIQUE 约束。要获得与使用主键相同的效果,列也应该是 NOT NULL(您的表中已经是这种情况)。

例子:

ALTER TABLE units
   ADD UNIQUE (category_id);

添加这些约束可能会使主键变得多余。在这种情况下,您可以删除它并将新约束之一设为主键。

【讨论】:

  • 但是caregoryid并不是桌上唯一的PK,有3个:unitid、categoryid、languageid。问题是我不知道如何使用多列的 FK。你回答我:)
  • 我觉得我们不理解,我在问题的底部添加了一个总结。
  • Thatnk 进行澄清。我希望我编辑的答案更有用。
猜你喜欢
  • 2019-12-25
  • 2014-11-16
  • 1970-01-01
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多