我们正在为公司制定分阶段实现的审批制度。为此,需求说我们需要一个模板,用于根据组织、位置、职位级别、职位和就业类型对员工进行分组,以便每个使用相同模板的员工都有相同的步骤和批准人层级。
这是高级别 ERD
这是我的问题。来自组织、位置等的数据不只有几行。假设组织、位置和其他 3 个实体各有 50 行,那么我必须从 50^5 行中进行选择以检查员工使用的是什么模板。
更不用说我需要检查组合是否与其他模板相交,因此员工必须拥有不超过 1 个模板
示例:
在这个例子中我只使用组织、职位级别和职位
Employee A:
Organization: BOD
JobLevel: Manager
JobTitle: General Manager
Employee B:
Organization: ICT
JobLevel: Senior
JobTitle: Senior Web Developer
假设我有审批模板 与成员的“Manager Approver”:
Organization: BOD
JobLevel: Manager
JobTitle: General Manager
此审批模板意味着...所有具有指定组织 BOD、jobLevel Manager 和 jobTitle General Manager 的员工都必须使用此模板。
另一种情况,我想再做一个有member的审批模板:
Organization: BOD, ICT (note we can use combination here)
JobLevel: Manager, Senior
JobTITLE: General Manager, Senior Web Developer
此模板无效,因为这将使员工 A 有 2 个符合条件的模板
为了检查这个组合是否重复,我创建了一个 View
CREATE OR REPLACE VIEW approval_template_members_view AS
SELECT uuid() as id,
at_organizations.organization_id AS organization_id,
at_job_titles.job_title_id AS job_title_id,
at_job_levels.job_level_id AS job_level_id,
at.id AS approval_template_id
FROM at
INNER JOIN at_organizations ON at_organizations.approval_template_id = at.id
INNER JOIN at_job_titles ON at_job_titles.approval_template_id = at.id
INNER JOIN at_job_levels ON at_job_levels.approval_template_id = at.id;
为了检查重复项,我只使用 Jpa Repository
@Query("SELECT COUNT(m) From approval_template_members_view m where m.organization.id IN ?1 AND m.jobTitle.id IN ?2 AND m.jobLevel.id IN ?3")
Long countByMember(List<String> organizationIds, List<String> jobTitleIds, List<String> jobLevelIds);
并检查此查询结果是否为 0 那么它是安全的/不与其他的重复。
我很清楚随着时间的推移会出现性能问题,有人可以推荐如何处理这个问题吗?每条建议都会很有帮助
最佳答案
我们无法在不知道要求的情况下验证您的数据库模型,因此我假设它是正确的。尽管您在 level
和 title
中有重叠,但看起来很可疑,例如senior
和 junior developer
的组合似乎没有意义,但您可以将其插入到您的模板中(或者换句话说:使模板适用于所有 senior
-jobs,无论如何你都需要在 titles
中列出它们,使 level
变得多余)。不过,这可能只是您的示例数据的产物,实际标题可能只是 Web Developer
;但我会检查一下。
因为你没有在你的示例中提到它,我忽略了 steps
-table(它似乎是一个版本控制系统),但你可以通过添加额外的 join
并且可能是一个group by step
。
您的验证确实需要一个join
,但您应该让数据库对此进行评估,而不是使用 View 检索每个组合并自己对照所有组合进行检查。优化 join
并使用方法来限制中间结果集的大小(例如不生成所有 50^5 组合以检查其中是否有特定组合)是面包- 关系数据库系统的强大能力。
要验证您的任何模板中没有重复条目,您可以使用
select l.location_id, jt.job_title_id, jl.job_level_id,
count(*) as dupcount, group_concat(jt.id) as duplicates
from template_job_titles jt
join template_locations l on jt.id = l.id
join template_job_levels jl on jt.id = jl.id
group by l.location_id, jt.job_title_id, jl.job_level_id
having count(*) > 1;
列出表的顺序无关紧要,因为实际的执行顺序是 MySQL 将决定的事情之一;你想包括你的主要 approval_template
-table(和 steps
),但为了简单起见,我只是跳过了它。
要检查要添加的模板是否与任何现有模板冲突(例如,如果要检查是否可以安全地添加示例中的组合模板,每个表都有两个选项),请使用
select jt.id, l.location_id, jt.job_title_id, jl.job_level_id
from template_job_titles jt
join template_locations l on jt.id = l.id
join template_job_levels jl on jt.id = jl.id
where (jt.job_title_id = 'General Manager'
or jt.job_title_id = 'Senior Web Developer')
and (l.location_id = 'BOD' or l.location_id = 'ICT')
and (jl.job_level_id = 'Senior' or jl.job_level_id = 'Manager');
这比第一个查询要快得多。如果您从不添加冲突的模板(例如,总是先检查,然后使用交易),您将只需要第二个查询。
查询哪个用户有哪个模板,就相当于根据用户信息查询模板是否已经在表中,所以和第二个查询一样(当然没有组合);如果您怀疑只有一个模板,请添加 group by
或警告。
关于mysql - 检查多个表上的重复数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51996691/