欢迎来到表间约束或断言的痛苦世界 - 这是 ISO SQL 和几乎每个 RDBMS 都无法以符合人体工程学的方式处理的东西......
(虽然 ISO SQL 确实描述了延迟约束和数据库范围的断言,据我所知只有 PostgreSQL 实现了延迟约束,并且没有生产质量的 RDBMS 支持数据库范围的断言) .
一种方法是使用第三个表,它是 only 表,带有SERIAL(又名IDENTITY 又名AUTO_INCREMENT)和一个鉴别器列,该鉴别器列组合形成表的主键,那么其他两个表对该 PK 有一个 FK 约束 - 但它们也需要相同的鉴别器列(通过 CHECK 约束强制执行),但您永远不需要在大多数查询中引用该列。
由于您的帖子没有告诉我们真正的表名是什么,我将使用我自己的。
类似这样的:
CREATE TABLE postIds (
postId int NOT NULL SERIAL,
postType char(1) NOT NULL, /* This is the discriminator column. It can only contain ONLY either 'S' or 'G' which indicates which table contains the rest of the data */
CONSTRAINT PK_postIds PRIMARY KEY ( postId, postType ),
CONSTRAINT CK_type CHECK ( postType IN ( 'S', 'G' ) )
);
CREATE TABLE shitposts (
postId int NOT NULL,
postType char(1) DEFAULT('S'),
foobar nvarchar(255) NULL,
etc int NOT NULL,
CONSTRAINT PK_shitpostIds PRIMARY KEY ( postId, postType ),
CONSTRAINT CK_type CHECK ( postType = 'S' ),
CONSTRAINT FK_shitpost_ids FOREIGN KEY ( postId, postType ) REFERENCES postIds ( postId, postType )
);
CREATE TABLE goldposts (
postId int NOT NULL,
postType char(1) DEFAULT('G'),
foobar nvarchar(255) NULL,
etc int NOT NULL,
CONSTRAINT PK_goldpostIds PRIMARY KEY ( postId, postType ),
CONSTRAINT CK_type CHECK ( postType = 'G' ),
CONSTRAINT FK_goldpost_ids FOREIGN KEY ( postId, postType ) REFERENCES postIds ( postId, postType )
)
使用这种设计,shitposts 中的任何行都不可能与goldposts 中的帖子共享postId 值,反之亦然。
但是,postIds 中可能存在一行goldposts 和shitposts 中没有任何行。幸运的是,当您使用 PostgreSQL 时,可以将新的 FK 约束从 postIds 添加到 goldposts 和 shitposts,但将其与延迟约束一起使用。