检查多表上的重复数据

webghufk  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(243)

我们正在为公司制定分阶段实施的审批制度。出于这个目的,需求说我们需要一个模板,用于根据组织、位置、工作级别、职务和雇用类型对员工进行分组,这样每个具有相同模板的员工都有相同的步骤和审批者层。
这是高级erd
这是我的问题。来自组织、位置等的数据不是只有几行。假设组织、位置和其他3个实体各有50行,那么我必须从50^5行中进行选择,以检查一个员工有什么模板。
更不用说我需要检查一个组合是不是与其他模板相交,所以一个员工必须有不超过1个模板

示例:

在这个例子中,我只使用了organization、joblevel和jobtitle

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、职务级别经理和职务总经理的所有员工都必须使用此模板。
另一种情况是,我想用成员制作另一个审批模板:

Organization: BOD, ICT (note we can use combination here)
JobLevel: Manager, Senior
JobTITLE: General Manager, Senior Web Developer

此模板无效,因为这将使员工成为2个合格模板
为了检查这个组合副本,我创建了一个视图

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存储库

@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,则它是安全的/不与其他查询结果重复。
我很清楚,随着时间的推移,会出现性能问题,有人能推荐如何处理这个问题吗?每一个建议都会很有帮助

7gcisfzg

7gcisfzg1#

我们无法在不知道需求的情况下验证您的数据库模型,因此我假设它是正确的。不过,你的工作有重叠,这看起来很可疑 level 以及 title ,例如组合 senior 以及 junior developer 似乎没有意义,但您可以将其插入到模板中(或者换句话说:使模板适用于所有人) senior -工作,你需要把它们都列出来 titles 不管怎样,做 level 冗余)。不过,这可能只是示例数据的一个工件,实际的标题可能只是 Web Developer ; 但我会检查一下。
因为你的样品中没有提到,我忽略了 steps -表(这似乎是一个版本控制系统),但您可以通过添加一个附加的 join 也许是一个 group by step .
您的验证确实需要 join ,但您应该让数据库对此进行评估,而不是使用视图检索每个组合,并自己对照所有组合进行检查。优化 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 -表(和 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 或者警告。

相关问题