You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PG Admin 4中定义关系强度适配QGIS组合关系需求

问题描述

我正在处理一个包含1:M和M:N表关系的数据库,已在PG Admin 4中通过外键定义了表间关系。但在QGIS中打开该模型时,仅显示关联类型关系,而我需要将M:N关系对应的中间表(红框标注部分)设置为组合强度关系。请问如何在PG Admin 4中定义这种关系强度?


示例SQL代码

创建Arret表

DROP TABLE IF EXISTS sdt_transports.arret;

CREATE TABLE IF NOT EXISTS sdt_transports.arret
(
    objectid_arret integer NOT NULL DEFAULT nextval('sdt_transports.arret_objectid_arret_seq'::regclass),
    id_arret integer,
    nom_arret character varying(50) COLLATE pg_catalog."default",
    ref_etat_exploitation integer,
    abreviation_arret character varying(10) COLLATE pg_catalog."default",
    arret_regional smallint,
    arret_urbain smallint,
    sens_alle smallint,
    sens_retour smallint,
    url_horaire_passage character varying(255) COLLATE pg_catalog."default",
    url_horaire_passage_exception smallint,
    url_horaire_origine character varying(255) COLLATE pg_catalog."default",
    url_horaire_origine_exception smallint,
    url_horaire_destination character varying(255) COLLATE pg_catalog."default",
    url_horaire_destination_exception smallint,
    url_information character varying(255) COLLATE pg_catalog."default",
    url_information_exception smallint,
    niveau_equipement character varying(50) COLLATE pg_catalog."default",
    rem_equipement character varying(250) COLLATE pg_catalog."default",
    niveau_offre smallint,
    pers_montante smallint,
    pers_descente smallint,
    url_statistique character varying(255) COLLATE pg_catalog."default",
    url_statistique_exception smallint,
    no_localite smallint,
    commentaires character varying(250) COLLATE pg_catalog."default",
    niveau_service character varying(50) COLLATE pg_catalog."default",
    user_mise_a_jour character varying(255) COLLATE pg_catalog."default",
    date_mise_a_jour timestamp without time zone,
    x double precision,
    y double precision,
    geom geometry,
    CONSTRAINT arret_pkey PRIMARY KEY (objectid_arret)
)
WITH (
    OIDS = FALSE
);

创建Cadre Horaire表

DROP TABLE IF EXISTS sdt_transports.cadre_horaire;

CREATE TABLE IF NOT EXISTS sdt_transports.cadre_horaire
(
    objectid_cadre_horaire integer NOT NULL DEFAULT nextval('sdt_transports.cadre_horaire_objectid_cadre_horaire_seq'::regclass),
    id_cadre_horaire character varying(30) COLLATE pg_catalog."default",
    nom_cadre_horaire character varying(150) COLLATE pg_catalog."default",
    url_cadre_horaire character varying(255) COLLATE pg_catalog."default",
    url_cadre_horaire_exception smallint,
    commentaires character varying(250) COLLATE pg_catalog."default",
    user_mise_a_jour character varying(255) COLLATE pg_catalog."default",
    date_mise_a_jour timestamp without time zone,
    CONSTRAINT cadre_horaire_pkey PRIMARY KEY (objectid_cadre_horaire)
)
WITH (
    OIDS = FALSE
);

创建Arret与Cadre Horaire的中间表

DROP TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire;

CREATE TABLE IF NOT EXISTS sdt_transports.link_arret_cadre_horaire
(
    objectid_link_arret_cadre_horaire integer NOT NULL DEFAULT nextval('sdt_transports.link_arret_cadre_horaire_objectid_link_arret_cadre_horaire_seq'::regclass),
    objectid_arret integer,
    objectid_cadre_horaire integer,
    user_mise_a_jour character varying(255) COLLATE pg_catalog."default",
    date_mise_a_jour timestamp without time zone,
    CONSTRAINT link_arret_cadre_horaire_pkey PRIMARY KEY (objectid_link_arret_cadre_horaire)
)
WITH (
    OIDS = FALSE
);

通过外键创建关系

ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    ADD FOREIGN KEY (objectid_arret)
    REFERENCES sdt_transports.arret (objectid_arret) MATCH SIMPLE
    ON UPDATE NO ACTION
    ON DELETE NO ACTION
    NOT VALID;


ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    ADD FOREIGN KEY (objectid_cadre_horaire)
    REFERENCES sdt_transports.cadre_horaire (objectid_cadre_horaire) MATCH SIMPLE
    ON UPDATE NO ACTION
    ON DELETE NO ACTION
    NOT VALID;

解决方案

组合强度关系的核心是子记录依赖父记录存在,删除父记录时子记录需同步删除。要让QGIS识别这种关系,需从外键行为和表结构两方面调整,在PG Admin 4中操作如下:

1. 修改外键的删除/更新行为

将外键的ON DELETE设为CASCADE(父记录删除时同步删除中间表关联记录),ON UPDATE设为CASCADE(父记录主键更新时同步更新中间表关联字段):

图形界面操作步骤

  • 打开中间表(如link_arret_cadre_horaire)的属性窗口,切换到Constraints标签页,找到已创建的外键。
  • 双击外键进入编辑界面,在Actions区域:
    • 将On delete改为CASCADE
    • 将On update改为CASCADE
  • 保存修改并执行变更。

对应SQL语句

-- 更新Arret与中间表的外键
ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    DROP CONSTRAINT IF EXISTS link_arret_cadre_horaire_objectid_arret_fkey;

ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    ADD FOREIGN KEY (objectid_arret)
    REFERENCES sdt_transports.arret (objectid_arret) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    VALIDATE;

-- 更新Cadre Horaire与中间表的外键
ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    DROP CONSTRAINT IF EXISTS link_arret_cadre_horaire_objectid_cadre_horaire_fkey;

ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    ADD FOREIGN KEY (objectid_cadre_horaire)
    REFERENCES sdt_transports.cadre_horaire (objectid_cadre_horaire) MATCH SIMPLE
    ON UPDATE CASCADE
    ON DELETE CASCADE
    VALIDATE;

2. 优化中间表的主键设计(可选但推荐)

M:N关系的中间表通常用两个外键组成复合主键,这更符合组合关系语义,还能避免重复关联记录:

图形界面操作步骤

  • 打开中间表的属性窗口,切换到Constraints标签页,删除原有的单字段主键。
  • 添加新的主键约束,选择objectid_arret和objectid_cadre_horaire两个字段作为复合主键。
  • 保存修改。

对应SQL语句

-- 删除原有主键
ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    DROP CONSTRAINT IF EXISTS link_arret_cadre_horaire_pkey;

-- 添加复合主键
ALTER TABLE IF EXISTS sdt_transports.link_arret_cadre_horaire
    ADD CONSTRAINT link_arret_cadre_horaire_pkey PRIMARY KEY (objectid_arret, objectid_cadre_horaire);

3. 刷新QGIS数据库连接

完成上述修改后,在QGIS中重新加载数据库连接,打开数据库模型,中间表的关系会被识别为组合强度关系。


内容的提问来源于stack exchange,提问作者pablo olivares

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:25:24