多个模式的唯一元素

时间:2016-06-09 16:53:43

标签: sql postgresql

我在另一个模式中有相同的表(User)。 一个架构 - 适用于一个租户。 用户有唯一的电子邮件 如何为所有模式设置独特的电子邮件字段?

如果这是不可能的,我可以从每个hql查询的其他模式中获取所有用户吗?

2 个答案:

答案 0 :(得分:1)

没有标准功能可以确保跨多个模式的唯一性。您可以使用公共表来实现此功能,如以下示例所示。

现有表格。

create schema tenant1;
create schema tenant2;
create table tenant1.users (email text);
create table tenant2.users (email text);

为触发器创建公共表和函数:

create schema sys;

create table sys.emails (email text primary key);

create or replace function sys.email_trigger()
returns trigger language plpgsql as $$
begin
    if tg_op = 'INSERT' then
        insert into sys.emails 
        values (new.email);
    elsif tg_op = 'UPDATE' then
        update sys.emails 
        set email = new.email 
        where email = old.email;
    end if;
    return new;
end $$;

定义所有users表的触发器:

create trigger users_before_insert_or_update
before insert or update on tenant1.users
for each row execute procedure sys.email_trigger();

create trigger users_before_insert_or_update
before insert or update on tenant2.users
for each row execute procedure sys.email_trigger();

并尝试在两个表中插入相同的电子邮件:

insert into tenant1.users values ('abc@some.com');
insert into tenant2.users values ('abc@some.com');

ERROR:  duplicate key value violates unique constraint "emails_pkey"
DETAIL:  Key (email)=(abc@some.com) already exists.

您可以使用表格的全名在一个查询中访问不同模式中的表格,例如使用union列出所有用户:

select * from tenant1.users
union all
select * from tenant2.users;

答案 1 :(得分:1)

您可以创建包含users表的全局模式。然后,对于每个租户架构,创建一个仅选择与该租户相关的用户的视图。

create schema global;
create schema tenant1;
create schema tenant2;

create table global.users
(
  id serial primary key,
  tenant integer not null,
  email varchar(254) not null unique,
  ... other columns
);

create view tenant1.users
as
select id, email, ... --<<< don't select the tenant here!
from global.users
where tenant = 1
with check option;

create view tenant2.users
as
select id, email, ... --<<< don't select the tenant here!
from global.users
where tenant = 2
with check option;

视图可自动更新,无需任何触发器。

基表视图必须由不同的数据库用户拥有,然后由每个租户的模式中的其他表拥有。那&#34;全球&#34;然后,用户必须在视图上授予选择,插入,更新,删除权限(仅限),以防止用于每个租户的数据库用户能够看到其他租户的数据。