我在另一个模式中有相同的表(User)。 一个架构 - 适用于一个租户。 用户有唯一的电子邮件 如何为所有模式设置独特的电子邮件字段?
如果这是不可能的,我可以从每个hql查询的其他模式中获取所有用户吗?
答案 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;然后,用户必须在视图上授予选择,插入,更新,删除权限(仅限),以防止用于每个租户的数据库用户能够看到其他租户的数据。