关于按照机构、岗位、职位、用户组等维度灵活指定允许用户参与范围的设计

需要实现一个集团级企业使用的调查问卷功能,每个调查发布时必须指定参与人员的范围,不能对全员发布。
发布调查时管理员可以按照机构(是否包含子机构)、岗位、职位、用户组等维度指定参与人员的范围。
用户端只能查看到参与人员的范围中包含本人的调查,不能查看参与人员的范围中没有本人的调查。

机构是树形结构,选中一个机构时,如果选择了包含子机构,那么选中机构及其所有子机构的用户都可以看到此调查。如果未选择包含子机构,那么只能是选中机构下的用户能够看到此调查。

用户组也是一个多种维度的用户分类,如用户组1是北京分公司30岁以下男员工和上海分公司30以上党员的集合。

各位大师帮忙说说具体如何设计才能保证性能,如果用户端通过多个union all sql 查询到本人能够查看到的调查列表效率太低了
十分感谢!

这个设计中,有一个很重要的场景,就是在发布问卷后,有新员工入职该公司,是否可以看到此份调查问卷。
如果业务要求必须看到,那么这个设计就会相对复杂;如果业务方接受可以看不到,那么这个就相对简单。
即,在问卷发布时,根据参与人员的范围,直接生成"问卷id-用户id-是否已填写"这三列数据,之后用户来检索自己需要的问卷时,就无需关联其他表即可获得自己需要填写的问卷。
至于生成这个清单,是用or还是union,建议都测试一下,但无论这个清单怎么生成,只要在用户查询前生成了,那么就不会影响到用户的查询效率。
如果生成这个清单所消耗的时间在应用端不可忍受,那么可以引入一个异步处理,即增加"发布中"的状态,等后台程序处理完了,再更新状态,这样前端也可以通过手动刷新页面来查看是否发布成功


问卷平均有效期多长?
建议用两个不同的表,一个是当前处于生效及待生效的"问卷-用户"清单,一个是处于失效期的清单,每晚批处理将前一日失效数据转至失效问卷表内,这样可以让经常被查询的这个表处于一个相对稳定的行数。况且如果不把这个列表记录下来,如果要查历史某个问卷的参与度,就无法计算了,因为当前的用户数并不代表历史的用户数。而且字段少的话并不会占用多少存储空间,只是要注意考虑到历史数据清理,建议表上要有日期字段,甚至可以按时间范围来对表进行分区。
至于新员工入职,可以在新员工信息创建的时候,扫一次问卷,看看哪些问卷是需要填的,自动补几行记录到上面说的这个表


两个极致,

  1. 粗暴定时全量刷新,逻辑简单,较为准确,但消耗太大;
  2. 把逻辑写到用户信息变更这个环节,只要提交了任意一个用户信息变更,就根据这个用户最新的资料,匹配一次问卷,对当前该用户的问卷列表进行刷新,这样可以将开销分散到每一次用户信息变更里。这个功能可以封装成一个单独的接口,传入用户id即可刷新此用户的问卷列表,虽然增加了耦合性,但也不会太高,出现问题可以紧急先停掉,将第一种方案的全量刷新作为一个应急方案或者说数据修复方案,两手准备

其实不用那么多union all,单表即可查看某个用户的问卷信息,方案设计如下:
设计如下表结构:
1、用户表,包含用户的基础信息, 账号、名称、岗位、职位等
2、机构表,包含机构的基础信息,机构名称、机构编码、父级机构(父级的id)等
3、机构用户表,机构和用户的中间表
4、组管理表,包含基础的组信息,比如组名称、组编号、组备注等
5、用户-组关联表,用户和组管理的关联表
6、问卷表,包含问卷的基础信息,标题、内容、、问题、备注等信息
7、用户问卷表,主要用于存储问卷信息和用户的关联关系,包含问卷id、用户id等字段

数据存储:
当发起问卷调查时,根据选择的机构、岗位、职位、用户组等信息,先去关联表找到对应的所有用户,以机构为例,当选择机构时,将选择的机构下的所有人员获取到,然后将用户问卷数据写到用户问卷表,查询时可以根据用户的唯一标识就可以在用户问卷表查询出该用户有哪些问卷可以参与;
如果选择了组,发起问卷时,先获取用户组对应的所有成员信息,然后将用户问卷数据写进用户问卷表,然后根据用户的唯一标识就可以在用户问卷表查询出该用户有哪些问卷;
如果选择了职位,发起问卷调查,首先查询出该职位下的所有用户,然后将用户问卷数据写进用户问卷表,根据用户的唯一标识就可以在用户问卷表查询出该用户有哪些问卷;如果选择了岗位,以此类推。
如果同时选择了多个维度,可以将每个维度下的用户当做一个集合,然后利用集合的交集方法合并为一个新的用户集合,然后把多维度的用户问卷数据写进用户问卷表,查询用户问卷时查询该单表即可

如果对你有所帮助,望采纳

1、首先调查是关于用户的查询应该是最多的,所以调查表应该关联到用户表上
2、用户和调查表的关联信息中应该包含该用户是否参与该调查
3、调查表中应包含是否是对用户的调查
4、再选中机构时应该是选中最底层的用户去保存到数据库
这样是在选择用户组和机构时便没有压力,在单人查询的调查时效率应该不低了

上个伪图,希望对你有帮助

img


伪sql:
select t.*,l.id
from user u
left join role_user ru on u.id = ru.user_id
left join role_template rt on ru.role_id = rt.role_id and ru.role_type = rt.role_type
left join template t on rt.template_id = t.id
left join log l on l.user_id = u.id and l.template_id = t.id
where u.id = ?
t的结果就是user需要的问卷,l存在就说明已经填写过了

可以在发布问卷的时候先批量生成哪些用户需要做问卷,这样用户直接查这张表就可以了

一个选择框,装入:机构、岗位、职位、用户组
一个年龄范围
一个性别选择框
其他条件
接下来是调查问卷
确定执行后
调查问卷存入后台表
得到一个调查问卷唯一ID
根据选择框内容查询用户表,存入临时表
调查问卷唯一ID、用户ID写入一个用户调查问卷结果表,(给状态,已调查、未调查),调查结果,时间必须有,什么开展调查,用户什么时候完成调查。
用户根据用户ID获取用户调查问卷结果表未调查的纪录,得到调查问卷唯一ID,通过这个ID获得调查问卷内容,调查结果写入调查问卷结果表

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632