简体   繁体   English

Postgresql具有相同外键唯一约束的多个表

[英]Postgresql multiple tables with same foreign key unique constraint

I have following tables on PostgreSQL 9.4 我在PostgreSQL 9.4上有以下表格

CREATE TABLE "user" (
    id SERIAL PRIMARY KEY,
    email CHARACTER VARYING NOT NULL,
    password CHARACTER VARYING NOT NULL
);

CREATE TABLE "dealer" (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL REFERENCES "user" (id) ON DELETE RESTRICT
);

CREATE TABLE "affiliate" (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL REFERENCES "user" (id) ON DELETE RESTRICT
);

Is it possible to force user_id value to be unique across tables dealer and affiliate ? 是否可以迫使user_id值在表dealeraffiliate之间是唯一的?

There are different setups to use for inheritance in SQL and for this you could just use an integer column type in the table user that marks the type of the user and would reference to table user_type (id,name) that would have the values 1,dealer and 2,affiliate : 在SQL中可以使用不同的设置来进行继承,为此,您可以在表user中使用整数列type来标记user的类型,并引用表user_type (id,name) ,其值将为1,dealer2,affiliate

CREATE TABLE user_type (
  id INTEGER PRIMARY KEY, --could be SERIAL
  name text
);
INSERT INTO user_type VALUES (1,'dealer'), (2, 'affiliate');

CREATE TABLE "user" (
    id SERIAL PRIMARY KEY,
    email CHARACTER VARYING NOT NULL,
    password CHARACTER VARYING NOT NULL,
    user_type INTEGER REFERENCES user_type NOT NULL,
    UNIQUE(id,user_type)
);

This in itself wouldn't force uniqueness across tables so after implementing this you would have the following options: 这本身不会在表之间强制唯一性,因此在实现此功能后,您将具有以下选择:

  • Drop the tables dealer and affiliate - you won't need them if you rely on the type field to see which one the user is. 删除表dealeraffiliate -如果您依靠类型字段来查看用户是哪一位,则不需要它们。

If you have to keep those inherited tables you can: 如果必须保留那些继承的表,则可以:

  • Use triggers - these triggers check the uniqueness and would be actived on INSERT or UPDATE 使用触发器 -这些触发器检查唯一性,并且将在INSERTUPDATE上激活
  • Another (a bit clumsy) solution: add user_type field to both subtables like this: 另一个(有点笨拙)的解决方案: user_type字段添加到两个子表中,如下所示:

     CREATE TABLE "dealer" ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL, user_type INTEGER NOT NULL DEFAULT 1 check (user_type = 1), FOREIGN KEY (user_id,user_type) REFERENCES "user"(id,user_type) ON DELETE RESTRICT ); CREATE TABLE "affiliate" ( id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL, user_type INTEGER NOT NULL DEFAULT 2 check (user_type = 2), FOREIGN KEY (user_id,user_type) REFERENCES "user"(id,user_type) ON DELETE RESTRICT ); 

    The checks and foreign keys together make sure you cannot have both types of user in the main table. 支票和外键共同确保您在主表中不能同时拥有两种类型的用户。 Note that user_id might be used as the PRIMARY KEY in the subtables too. 注意, user_id也可以用作子表中的PRIMARY KEY Currently a row in user might have several dealer rows linked to it so at least you might want to set user_id foreign keys in subtables as UNIQUE . 当前, user的一行可能已链接了多个dealer行,因此至少您可能希望将子表中的user_id外键设置为UNIQUE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM