sep*_*hdo 8 sql postgresql foreign-keys database-normalization
员工被组织成团队。每个团队可以有多个员工,每个员工可以属于多个团队。这种多对多关系由team_membership表表示。
每个项目分配给一个团队。项目细分为任务,每个任务分配给一名员工。
是否可以保证任务的员工是相应项目团队的成员,而不添加触发器或冗余列?
CREATE TABLE employee
(
employee_id bigserial PRIMARY KEY,
employee_name text
);
CREATE TABLE team
(
team_id bigserial PRIMARY KEY,
team_name text
);
CREATE TABLE team_membership
(
team_id bigint NOT NULL REFERENCES team,
employee_id bigint NOT NULL REFERENCES employee,
PRIMARY KEY (team_id, employee_id)
);
CREATE TABLE project
(
project_id bigserial PRIMARY KEY,
team_id bigint NOT NULL REFERENCES team,
project_name text
);
CREATE TABLE task
(
task_id bigserial PRIMARY KEY,
task_name text,
project_id bigint NOT NULL REFERENCES project,
employee_id bigint NOT NULL REFERENCES employee
);
Run Code Online (Sandbox Code Playgroud)
使用触发器在数据更改时检查有效性。这将需要为employee和team_membership表编写类似的触发器过程。
CREATE FUNCTION check_employee_member_of_team() RETURNS trigger AS $$
BEGIN
IF NOT new.employee_id IN (
SELECT employee_id FROM team_membership tm
JOIN project pr ON tm.team_id = pr.team_id
WHERE pr.proejct_id = new.project_id
) THEN
RAISE EXCEPTION 'Employee is not a member of project';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER insert_or_update_task_trigger
BEFORE INSERT OR UPDATE ON task
FOR EACH ROW EXECUTE PROCEDURE check_employee_member_of_team();
Run Code Online (Sandbox Code Playgroud)
team_id向任务表中添加一列,并使用复合外键强制执行约束。project.team_id并且task.team_id是多余的。
CREATE TABLE project
(
project_id bigserial PRIMARY KEY,
team_id bigint NOT NULL REFERENCES team,
project_name text,
UNIQUE (project_id, team_id)
);
CREATE TABLE task
(
task_id bigserial PRIMARY KEY,
task_name text,
project_id bigint NOT NULL,
team_id bigint NOT NULL,
employee_id bigint NOT NULL REFERENCES employee,
FOREIGN KEY (project_id, team_id) REFERENCES project (project_id, team_id),
FOREIGN KEY (team_id, employee_id) REFERENCES team_membership (team_id, employee_id)
);
Run Code Online (Sandbox Code Playgroud)
添加冗余列team_id并将task新列添加到外键引用中project。这需要对 进行冗余的唯一约束project(team_id, project_id)。
task然后创建一个从到 的外键约束team_membership。那么任务只能分配给团队成员。
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |