如何在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
相关产品推荐
相关产品推荐

