您不必求助于触发器,但它可能会有所帮助。改变结构会有很大帮助,但它通常依赖于 CHECK 约束。在 MySQL 中,如果需要 CHECK 约束,则必须编写触发器或添加另一个使用外键约束的表。
您有额外的负担,因为兼职员工以后可能会成为全职员工,反之亦然。
在这里,我将如何为更标准的 SQL 平台编写它。
create table emp (
emp_id integer primary key,
emp_type char(1) not null check (emp_type in ('f', 'p')), -- FK in your schema
emp_name varchar(50) not null,
start_date date not null default current_date,
unique (emp_id, emp_type)
);
create table full_time_emp (
emp_id integer primary key references emp (emp_id),
emp_type char(1) not null default 'f' check (emp_type = 'f'),
foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
salary decimal(14,2) not null check (salary > 15000)
);
create table part_time_emp (
emp_id integer primary key references emp (emp_id),
emp_type char(1) not null default 'p' check (emp_type = 'p'),
foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
rate decimal(14,2) not null check (rate > 0 and rate < 100)
);
在表full_time_emp中,这两个约束
check (emp_type = 'f'),
foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
一起防止兼职员工出现在全职表中。如果“emp”中引用的行包含“p”,则外键引用将失败;如果您尝试将“p”插入“full_time_emp”,则检查约束将失败。
在这种情况下,您可以将检查约束替换为单行表和外键引用。该表应仅包含“f”。(或您用来代表全职员工的任何 ID 号。)同样适用于“part_time_emp”。因此,您可以为 full_time_emp执行此操作,而不是 CHECK 约束。
create table full_time_emp_check (
full_time_emp_type char(1) primary key
);
insert into full_time_emp_check values ('f');
alter table full_time_emp
add constraint full_time_emp_check
foreign key (emp_type) references full_time_emp_check (full_time_emp_type);
part_time_emp 的更改类似。您可能希望在这两个表上都有一个触发器,以确保它们永远不会包含超过一行。
甚至对薪水和费率的检查也可以通过附加表和外键引用来实现。不过,有点像在海滩上踢死鲸鱼。我可能会在 MySQL 中使用触发器来实现这种范围约束。
恕我直言,对于员工类型,CHAR(1) 代码优于整数。人类可读的代码不需要连接。