Oracle DB和PostgreSQL,OpenGauss主外键一致性的区别
针对于unique索引在主外键上的表现,o和PG的行为确实不一致,测试样例:
PG:
测试1:
test=# CREATE TABLE gdb_editingtemplates ( objectid INTEGER NOT NULL, globalid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, type SMALLINT NOT NULL, name VARCHAR(255) NOT NULL, defaulttool VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, datasetguid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, subtype INTEGER NULL, description VARCHAR(1024) NULL, tags VARCHAR(2000) NULL, visible SMALLINT NOT NULL, hash VARCHAR(64) NOT NULL, useridentity VARCHAR(255) NULL, status INTEGER NULL);
CREATE TABLECREATE UNIQUE INDEX EdTemplates_Globalid_idx ON gdb_editingtemplates (globalid );
CREATE INDEXCREATE TABLE gdb_editingtemplaterelationships ( objectid INTEGER NOT NULL, type SMALLINT NOT NULL, originid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, destid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL);
CREATE TABLE
test=# ALTER TABLE GDB_EditingTemplateRelationships ADD CONSTRAINT EdTemplateRlships_OriginID_fk FOREIGN KEY (originid) REFERENCES GDB_EditingTemplates (globalid);
ALTER TABLE
test=# select version();version
---------------------------------------------------------------------------------------------------------PostgreSQL 11.5 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit
(1 行记录)
test=# drop table gdb_editingtemplaterelationships;
DROP TABLE
test=# drop table gdb_editingtemplates;
DROP TABLE
test=# CREATE TABLE gdb_editingtemplates ( objectid INTEGER NOT NULL, globalid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, type SMALLINT NOT NULL, name VARCHAR(255) NOT NULL, defaulttool VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, datasetguid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, subtype INTEGER NULL, description VARCHAR(1024) NULL, tags VARCHAR(2000) NULL, visible SMALLINT NOT NULL, hash VARCHAR(64) NOT NULL, useridentity VARCHAR(255) NULL, status INTEGER NULL);
CREATE TABLE
test=# alter table gdb_editingtemplates add constraint gdb_editingtemplates_global_uniq unique(globalid);
ALTER TABLE
test=# CREATE TABLE gdb_editingtemplaterelationships ( objectid INTEGER NOT NULL, type SMALLINT NOT NULL, originid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, destid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL);
CREATE TABLE
test=# ALTER TABLE GDB_EditingTemplateRelationships ADD CONSTRAINT EdTemplateRlships_OriginID_fk FOREIGN KEY (originid) REFERENCES GDB_EditingTemplates (globalid);
ALTER TABLE
test=# select version();version
---------------------------------------------------------------------------------------------------------PostgreSQL 11.5 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit
(1 行记录)
华为GaussDB for openGauss:
test_temp=> select version();
-[ RECORD 1 ]--------------------------------------------------------------------------------------------------------------
version | gaussdb (GaussDB Kernel 503.1.0 build f53b4ed8) compiled at 2023-03-27 00:43:20 commit 5356 last mr 10743 releasetest_temp=> select * from pg_database where datname=current_database();
-[ RECORD 1 ]----+----------
datname | test_temp
datdba | 18389
encoding | 0
datcollate | C
datctype | C
datistemplate | f
datallowconn | t
datconnlimit | -1
datlastsysoid | 12810
datfrozenxid | 0
dattablespace | 1663
datcompatibility | A
datacl |
datfrozenxid64 | 14613
datminmxid | 2
dattimezone | PRCtest_temp=> CREATE TABLE gdb_editingtemplates ( objectid INTEGER NOT NULL, globalid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, type SMALLINT NOT NULL, name VARCHAR(255) NOT NULL, defaulttool VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, datasetguid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, subtype INTEGER NULL, description VARCHAR(1024) NULL, tags VARCHAR(2000) NULL, visible SMALLINT NOT NULL, hash VARCHAR(64) NOT NULL, useridentity VARCHAR(255) NULL, status INTEGER NULL);
CREATE TABLE
test_temp=>
test_temp=> CREATE UNIQUE INDEX EdTemplates_Globalid_idx ON gdb_editingtemplates (globalid );
CREATE INDEX
test_temp=> CREATE TABLE gdb_editingtemplaterelationships ( objectid INTEGER NOT NULL, type SMALLINT NOT NULL, originid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, destid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL);
CREATE TABLE
test_temp=> ALTER TABLE GDB_EditingTemplateRelationships ADD CONSTRAINT EdTemplateRlships_OriginID_fk FOREIGN KEY (originid) REFERENCES GDB_EditingTemplates (globalid);
ALTER TABLE
test_temp=> drop table gdb_editingtemplaterelationships;
DROP TABLE
test_temp=> drop table gdb_editingtemplates;
DROP TABLE
test_temp=> CREATE TABLE gdb_editingtemplates ( objectid INTEGER NOT NULL, globalid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, type SMALLINT NOT NULL, name VARCHAR(255) NOT NULL, defaulttool VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, datasetguid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, subtype INTEGER NULL, description VARCHAR(1024) NULL, tags VARCHAR(2000) NULL, visible SMALLINT NOT NULL, hash VARCHAR(64) NOT NULL, useridentity VARCHAR(255) NULL, status INTEGER NULL);
CREATE TABLE
test_temp=> alter table gdb_editingtemplates add constraint gdb_editingtemplates_global_uniq unique(globalid);
NOTICE: ALTER TABLE / ADD UNIQUE will create implicit index "gdb_editingtemplates_global_uniq" for table "gdb_editingtemplates"
ALTER TABLE
test_temp=> CREATE TABLE gdb_editingtemplaterelationships ( objectid INTEGER NOT NULL, type SMALLINT NOT NULL, originid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, destid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL);
CREATE TABLE
test_temp=> ALTER TABLE GDB_EditingTemplateRelationships ADD CONSTRAINT EdTemplateRlships_OriginID_fk FOREIGN KEY (originid) REFERENCES GDB_EditingTemplates (globalid);
ALTER TABLE
PG和华为 gaussDB for openGauss(兼容o模式) ,在主表的关联键上建unique索引或者unique的constraint都可以。
O:
SQL> CREATE TABLE gdb_editingtemplates ( objectid INTEGER NOT NULL, globalid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, type SMALLINT NOT NULL, name VARCHAR(255) NOT NULL, defaulttool VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, datasetguid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NULL, subtype INTEGER NULL, description VARCHAR(1024) NULL, tags VARCHAR(2000) NULL, visible SMALLINT NOT NULL, hash VARCHAR(64) NOT NULL, useridentity VARCHAR(255) NULL, status INTEGER NULL);Table created.SQL> CREATE UNIQUE INDEX EdTemplates_Globalid_idx ON gdb_editingtemplates (globalid );Index created.SQL> CREATE TABLE gdb_editingtemplaterelationships ( objectid INTEGER NOT NULL, type SMALLINT NOT NULL, originid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL, destid VARCHAR(38) DEFAULT '{00000000-0000-0000-0000-000000000000}' NOT NULL);Table created.SQL> ALTER TABLE GDB_EditingTemplateRelationships ADD CONSTRAINT EdTemplateRlships_OriginID_fk FOREIGN KEY (originid) REFERENCES GDB_EditingTemplates (globalid);
ALTER TABLE GDB_EditingTemplateRelationships ADD CONSTRAINT EdTemplateRlships_OriginID_fk FOREIGN KEY (originid) REFERENCES GDB_EditingTemplates (globalid)*
ERROR at line 1:
ORA-02270: no matching unique or primary key for this column-listSQL> alter table gdb_editingtemplates add constraint gdb_editingtemplates_gid_unique unique(globalid);Table altered.SQL> ALTER TABLE GDB_EditingTemplateRelationships ADD CONSTRAINT EdTemplateRlships_OriginID_fk FOREIGN KEY (originid) REFERENCES GDB_EditingTemplates (globalid);Table altered.
在主表上的关联键上建unique索引,在建关联的时候会报错,需要建一个unique的constraint才可以,也就是说o上不认unique索引,只认constraint。
个人认为,PG的兼容性更好些。
有些国产数据厂商的兼容O模式,为了兼容Oracle,也会是这样的行为。