YSS

Write Less & Do More

问卷系统之数据库设计

背景

我们打算在基地搞一套表单系统,继而在这个表单系统之上生成一个问卷系统。

目的

构建一套问卷的后台系统,和基地生成的问卷做对接。

一些必要的说明

同时支持对内和对外两种

需要同时支持在 yuanfudao.com 和 zhenguanyu.com 下放问,意味着数据需要同时支持 ldap 和 userId。

考虑到两种在值层面就是有差别的,ldap是字母开头,userId 直接就只是数字。

不管是是同时对内和对外都是能区分开来的,那么是可以直接使用一个字段,然后分别填入。

字段信息存储和归类

问卷系统的表单是在额外的一个系统搭建,它会有一个自己的唯一的 ID 用于页面层面的展示,这个已经有专门的设计,不需要我们独立开发。

但如何和问卷进行关联和绑定是个大问题。

初期想的是基地提供一个接口让问卷系统去调,然后保证每次问卷的信息都提交 mktId,然后在后台查看的时候,可以通过 mktId 能反查问卷系统字段信息做到。

但,这么一来,问卷系统就不是一个独立的东西,而是依托于基地的一个系统,或者说是基地的附属系统。

这显然不是我们希望看到的。

所以,我们还是希望在搭建问卷的时候,一并生成一个问卷的唯一标识。

然后就是问卷的具体字段怎么去拿,两种方式:

基地服务提供一个接口反查。 在问卷生成和更新的时候,能一并把字段信息提交过来。

这其中第一个方式有个问题,就是如何把基地生成的问卷和问卷后台系统对应起来。而且会使得问卷系统还是一个强依赖基地的系统。

然后第二个,如果服务与服务之前有事件消息机制的话,这个事情是相对来说比较容易的。但是目前我们没有这个能力,能看到的直接做的也就是直接发一个 http 请求。

但第二个的好处就在于不用每次去读取,而是在每次有更新的时候才去做。最重要的是它是一个独立的系统。

整体看,第二个方式会使得整个问卷系统和基地是可以相互独立的系统。

问卷信息存储

问卷系统后台,是一个独立的部分,主体是在于收集问卷信息,然后归类合并或者做一些信息类的逻辑处理。

但是,每个问卷里的数据字段都是用户定义的,不过可以通过有规律的固定生成来做到。

然而,这种对于高度集成的问卷系统可以这样设计,但对于通用的方式来说,就显得不合适了。

那么,我们就考虑直接用一个大的 JSON 来存储。

所以,整体流程应该是:

问卷流程

权限

查看问卷系统的人,核心是本身做问卷的人,但是,还是希望可以让其他人去看到问卷的一个结果。

简单的做法就是,加一个对应关系,问卷ID 和 ldap 进行绑定,然后 只有创建者有权力去操作和更改。

关于 ladon

是否需要用 ladon

ladon 更关注于系统某个功能的权限,而针对这种细节到具体的某一项数据的权限,并且是一个动态生成的数据,其实是非常不适合的。

而且这个数据不见得需要很多人去看。

数据库设计

问卷封面(questionnaire)

id int(11) 自增 ID,返回给用户的时候是否要考虑加密? ldap varchar(128) 创建者,需要索引 name varchar(128) 问卷名称 url varchar(255) 问卷表单地址 url deadline timestamp 截止时间 fields text 字段对应的中文名的对应关系,值应该是这样的数据结构: [

{

key: 'xxx',

value: 'xxx',

sources: [{text: xxx, value: xxx}]// 可选,设置了数据源则为必填

},

]

问卷详情(questionnaire_item)

id int(11) 自增 ID

questionnaireId int(11) 问卷表 ID,需要索引 uid varchar(128) 提交者 ip int 用户的地区信息 userAgent varchar(255) 用户的设备信息 duration int 单位是 秒,从展示到提交的耗时 department varchar(128) 用户的部门信息,仅在内网提交时生效 content text 提交的表单数据,值应该是:

{

‘key_1’: ‘xxx’,

‘key_2’: ‘xxx2’,

}

联合唯一索引 index(questionnaireId, ldap)

问卷权限表(questionnaire_access) (一期不搞)

questionnaireId int(11) 问卷表 ID

ldap varchar(128) 权限人 owner varchar(128) 所有者 member varchar(128) 权限人 access int(1) 二进制位标识权限,00000001,只要是大于0的就是有权限的,后面有需求再细化具体的权限 联合唯一索引 index(questionnaireId, ldap)

静态数据源(questionnaire_data):

id int(11) 自增 ID ldap varchar(128) 创建者,需要索引 name varchar(128) 数据源名称 content text 数据源内容,是一个数组,支持四种形式:

只有 text 同时有 text 和 value 同时有 text 和 imageUrl 同时有 text 、value 和 imageUrl 需要实现跟基地对接的 API 接口

最后

这套设计下,数据库最好其实是用 MongoDB,奈何一是这块的建设还非常的不成熟,另外,我们之前也只有 MySQL 的使用经验。