内容分类扩展性标签设计

  • 苏格团队
  • 做者:YaoLang

角色:产品汪小T,程序员小C前端


小T:小C,有活干了。咱们想作个在线题库系统,老师能够搜索题目来备课。程序员

小C看着简易的需求稿,心想,我一分钟几百万上下,居然找我作这么简单的需求。建个题目表不就完事了。json

小C:题目数据从哪里来,包含什么属性?数组

小T:咱们第一期题目数据是从A公司那里买过来的,题目包含正文,选项,答案,题型,难度。bash

小C:嗯,也就是我要建一张question表,包括这五个属性。那题型和难度有哪些呢?ui

小T:题型有五种,单选,多选,判断,填空,解答。难度有3种,简单,通常,困难。用户能够根据题型或者难度来筛选。 小C拿着笔画了一下:OK,表设计出来了编码

t_question表spa

字段 属性 描述
uid char(32) 惟一标示
body TEXT 正文
options JSON 题目选项
answer TEXT 答案
type int(11) 题目类型,1单选、2多选、3判断、4填空、5解答
difficult int(11) 题目难度,1简单、2通常、3困难

小C:搜索根据body, options模糊匹配,而后筛选让前端传入type = 1或者difficult = 3 进行题型和难度的筛选设计

小T:哇,果真靠谱,那咱们上线吧。code


小T:小C,咱们的题库系统发到市场上有不少用户反馈说题目量不太够,最近咱们找到了B公司合做,但愿能把B公司的题库也整合到咱们的系统,数据的结构和A公司的很类似,你看下要弄多久。

小C心想,敢情这产品汪不生产题目,只是题目的搬运工啊。

小C:导一下数据就完事了。把接口文档发我对接一下就行了。

小T:好,待会文档发你。

拿到B公司的题目接口,题目总体结构不变,但是题型和难度的分类都比A公司多一点。题型有单选题,多选题,分析题,通常分解题,APP分解题。题型有简单,通常,困难,极难。

小C心想:我去,我要以哪一个公司的题目分类做为标准。因而找到了小T

小C:数据若是作整合的话,可不能够将B公司的分析题,通常分解题,APP分解题变成咱们的解答题,极难不要,都变成困难。由于如今没有定义一个标准,我不太好整合数据。

小T:那好吧,先按你说的去作。


自那之后,小T又找了两家公司合做,让小C整合数据。而且小T认为其中一家公司的方法(配方法,消元法,排除法)和能力(推理能力,分析能力,计算能力)数据也是很重要的维度,但愿能作补充。

小C崩溃了,我一分钟几百万上下,居然找我来导数据。每次还要去看数据的分类值应该怎么作整合。还常常要加字段。如今由于要接入那两家公司的题库数据,要将表修改为

t_question表

字段 属性 描述
uid char(32) 惟一标示
body TEXT 正文
options JSON 题目选项
answer TEXT 答案
type int(11) 题目类型,1单选、2多选、3判断、4填空、5解答
difficult int(11) 题目难度,1简单、2通常、3困难
ability int(11) 能力属性,1推理能力,2分析能力 。。。。
method int(11) 方法属性,1配方法,2消元法,3排除法。。。
  1. 如今题库有300W数据,将来还会不断地增长,若是频繁改表的话,线上会直接锁表
  2. 若是每一个分类我还要去看哪些值应该映射为咱们定义的哪些值,后面确定会吃不消的,由于咱们没有一套统一的标准。。。

小C意识到本身跳到了一个大坑中,原来这东西并无一开始想的这么简单。

通过仔细的思考,小C得出结论:

  1. 行业内根本就没有一套标准,必须针对变化点作扩展
  2. 不一样的公司题目的维度数据不同(如某公司多了能力与方法两个维度)
  3. 不一样的公司同一维度的数据值不同(如B公司的题型和A公司不同)

专门针对标签创建表

  • 一个标签分类下有多个标签值
  • 一道习题有多个标签属性

t_tag表

字段 属性 描述
uid char(32) 惟一标示
tag_name varchar(64) 标签分类
tag_key varchar(64) 标签key

t_tag_value表

字段 属性 描述
uid char(32) 惟一标示
tag_id char(32) 标签分类id
value_name varchar(64) 标签值名
value_code varchar(64) 标签值编码

t_question_tag表

字段 属性 描述
id char(32) 惟一标示
tag_value_id char(32) 标签值id
question_id char(32) 题目id

当一次查询时,先将查询到的题目id到t_question_tag表中查出tag_value_id集合。 标签进行GROUP BY tag_id聚合后获得如下json

[{
分类名:难度, 
分类key: difficult,
值列表:[{
    值名:简单, 
    值编码: 1
},{
    值名:通常, 
    值编码: 2
},{
    值名:困难, 
    值编码: 3
}]}
]
复制代码

经过返回标签聚合,能够在前端展现

难度:简单,通常,困难
题型:选择题,判断题,做文,完形填空。。。
方法:配方法,消元法。。。。
复制代码

筛选时,传入标签key (difficult),标签value (1)获得tag_value_id 而后能够筛选出跟标签绑定的题目。

拓展总结:
  1. 当某张数据表将来可能数据量会很庞大的,不能由于需求变动频繁地增长表的字段,考虑增长中间表的方式来进行拓展
  2. 通常实体数据信息不肯定的时候,也能够考虑使用NOSQL检索,如设计成如下的文档,就能够利用NOSQL的数组查询功能检索标签对应的实体。
{
    "uid":"",
    "description":"",
    "tag_ids":["标签1","标签2","标签3"]
}
复制代码
  1. 该设计也能应用于电商中,如商品的分类筛选
颜色:黄色,蓝色,绿色
尺码:M,L,XL,XXL
风格:休闲,商务
复制代码
  1. 标签只适合用于有限个数的分类,如文件大小,价格这些不固定的属性是不能作成标签的。
  2. 标签字段是不会有排序需求的,如按照某个分类进行order by。由于标签订位是有限分类,排序没有任何的意义,标签只能用来作筛选。若是必定要排序,建议另外计算标签和其余属性计算出一个分数字段。
问题点:
  1. 为何标签值要分红标签uid和标签code呢

标签code属于多变的,能够自定义,如让简单定义为1,困难定义为2。若是直接让题目绑定1,极可能和其余的分类冲突。如题型的1为单选题。

  1. 为何要前端传入key和value不直接传标签uid

会有一些场景须要业务自定义标签,如省市区,用户使用时更想用101100这种全国通用的地区编码来作标签筛选。

作到这里,小C稍微松了一口气,以后你来一个公司的数据,若是有新的分类,就能够加标签类别再加标签值。若是同一分类下来新的值,先看一下分类的中文名是否是对应的上,对应不上新建标签,而后让产品去作标签的整合或者就当成两个不一样的标签来算。不再怕整合数据了。

相关文章
相关标签/搜索