如何以规范化数据库形式存储用户的当前工作? 我正在使用PostgreSQL

问题描述

我有一个USERS表和一个EMPLOYMENT表,该表将多个工作链接一个用户。如何在用户可能没有当前工作且他们只能拥有一个当前工作的约束条件下为用户存储当前工作。

就业表isCurrent中的字段是否可以正常工作,因为认情况下,此表对当前只有一份工作没有限制?

我考虑过的另一个更可取的替代方案是拥有一个USER_CURRENT_EMPLOYMENT表,该表将用户与工作相关联,但是,要实现此功能,我又需要什么约束?

如前所述,我使用的是postgresql,但对于无论哪种语言,这种关系如何工作都感到好奇。

解决方法

使用唯一索引和where谓词对用户及其工作的最后一天(可以为空)强制实施唯一性。这样可以确保每位用户的最后一行中只有一行具有NULL值。

“在就业(user_id,(last_day IS NULL))上创建唯一的索引idx_current_employer,WHERE last_day IS NULL;”

下面是一个完整的脚本来说明如何使用它:

drop table if exists users;
drop table if exists employment;

create table users
(user_id int not null primary key,user_name varchar(30) not null)
;

create table employment
(id SERIAL PRIMARY KEY,user_id int not null,employer_id int not null,last_day date null)
;

--insert joe and his previous 2 employers
insert into users 
values(1,'Joe');

insert into employment (user_id,employer_id,last_day)
values(1,1,'20150831');
insert into employment (user_id,2,'20200831');


--unique index
create unique index idx_current_employer on employment (user_id,(last_day IS NULL)) WHERE last_day IS NULL;

--insert Joe's current employer (null last day)
insert into employment (user_id,3,null);

--this one fails - can't insert another employer with null last day  
insert into employment (user_id,6,null);

--set last day of previous employer first
update employment
set last_day = '20201006'
where user_id = 1
and last_day is null
;

--now insert succeeds
insert into employment (user_id,null);

--list all employment
select user_id,last_day,case when last_day is null then True else False end as is_current 
from employment 
order by 1,4 desc,3 desc
;