前言
文章通俗明了暮的,故摘抄于此!
正文
角色:產品汪小T笙以,程序員小C
小T:小C,有活干了冻辩。我們想做個在線題庫系統(tǒng)猖腕,老師可以搜索題目來備課。
小C看著簡易的需求稿恨闪,心想倘感,我一分鐘幾百萬上下,竟然找我做這么簡單的需求凛剥。建個題目表不就完事了。
小C:題目數(shù)據(jù)從哪里來轻姿,包含什么屬性犁珠?
小T:我們第一期題目數(shù)據(jù)是從A公司那里買過來的,題目包含正文互亮,選項犁享,答案,題型豹休,難度炊昆。
小C:嗯,也就是我要建一張question表威根,包括這五個屬性凤巨。那題型和難度有哪些呢?
小T:題型有五種洛搀,單選敢茁,多選,判斷留美,填空彰檬,解答伸刃。難度有3種,簡單逢倍,一般捧颅,困難。用戶可以根據(jù)題型或者難度來篩選较雕。
小C拿著筆畫了一下:OK碉哑,表設計出來了
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困難 |
小C:搜索根據(jù)body, options模糊匹配远舅,然后篩選讓前端傳入type = 1或者difficult = 3 進行題型和難度的篩選
小T:哇,果然靠譜痕钢,那我們上線吧图柏。
小T:小C,我們的題庫系統(tǒng)發(fā)到市場上有很多用戶反饋說題目量不太夠任连,最近我們找到了B公司合作蚤吹,希望能把B公司的題庫也整合到我們的系統(tǒng),數(shù)據(jù)的結構和A公司的很相似随抠,你看下要弄多久裁着。
小C心想,敢情這產品汪不生產題目拱她,只是題目的搬運工啊二驰。
小C:導一下數(shù)據(jù)就完事了。把接口文檔發(fā)我對接一下就好了秉沼。
小T:好桶雀,待會文檔發(fā)你。
拿到B公司的題目接口唬复,題目整體結構不變矗积,可是題型和難度的分類都比A公司多一點。題型有單選題敞咧,多選題漠魏,分析題,一般分解題妄均,APP分解題柱锹。題型有簡單哪自,一般,困難禁熏,極難壤巷。
小C心想:我去,我要以哪個公司的題目分類作為標準瞧毙。于是找到了小T
小C:數(shù)據(jù)如果做整合的話胧华,可不可以將B公司的分析題,一般分解題宙彪,APP分解題變成我們的解答題矩动,極難不要,都變成困難释漆。因為現(xiàn)在沒有定義一個標準悲没,我不太好整合數(shù)據(jù)。
小T:那好吧男图,先按你說的去做示姿。
自那以后,小T又找了兩家公司合作逊笆,讓小C整合數(shù)據(jù)栈戳。并且小T認為其中一家公司的方法(配方法,消元法难裆,排除法)和能力(推理能力子檀,分析能力,計算能力)數(shù)據(jù)也是很重要的維度乃戈,希望能做補充褂痰。
小C崩潰了,我一分鐘幾百萬上下偏化,竟然找我來導數(shù)據(jù)脐恩。每次還要去看數(shù)據(jù)的分類值應該怎么做整合镐侯。還經常要加字段≌焯郑現(xiàn)在因為要接入那兩家公司的題庫數(shù)據(jù),要將表修改成
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排除法世杀。。肝集。 |
現(xiàn)在題庫有300W數(shù)據(jù)瞻坝,未來還會不斷地增加,如果頻繁改表的話包晰,線上會直接鎖表
如果每個分類我還要去看哪些值應該映射為我們定義的哪些值湿镀,后面肯定會吃不消的,因為我們沒有一套統(tǒng)一的標準伐憾。勉痴。。
小C意識到自己跳到了一個大坑中树肃,原來這東西并沒有一開始想的這么簡單蒸矛。
經過仔細的思考,小C得出結論:
行業(yè)內根本就沒有一套標準胸嘴,必須針對變化點做擴展
不同的公司題目的維度數(shù)據(jù)不一樣(如某公司多了能力與方法兩個維度)
不同的公司同一維度的數(shù)據(jù)值不一樣(如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
然后可以篩選出跟標簽綁定的題目。
拓展總結:
當某張數(shù)據(jù)表未來可能數(shù)據(jù)量會很龐大的吕晌,不能因為需求變更頻繁地增加表的字段芥牌,考慮增加中間表的方式來進行拓展
一般實體數(shù)據(jù)信息不確定的時候,也可以考慮使用NOSQL檢索聂使,如設計成以下的文檔壁拉,就可以利用NOSQL的數(shù)組查詢功能檢索標簽對應的實體。
{
"uid":"",
"description":"",
"tag_ids":["標簽1","標簽2","標簽3"]
}
該設計也能應用于電商中柏靶,如商品的分類篩選
- 顏色:黃色弃理,藍色,綠色
- 尺碼:M屎蜓,L痘昌,XL,XXL
- 風格:休閑炬转,商務
標簽只適合用于有限個數(shù)的分類辆苔,如文件大小,價格這些不固定的屬性是不能做成標簽的扼劈。
標簽字段是不會有排序需求的驻啤,如按照某個分類進行order by。因為標簽定位是有限分類荐吵,排序沒有任何的意義骑冗,標簽只能用來做篩選。如果一定要排序先煎,建議另外計算標簽和其他屬性計算出一個分數(shù)字段贼涩。
問題點:
為什么標簽值要分成標簽uid和標簽code呢
標簽code屬于多變的,可以自定義薯蝎,如讓簡單定義為1遥倦,困難定義為2。如果直接讓題目綁定1占锯,很可能和其他的分類沖突袒哥。如題型的1為單選題。
為什么要前端傳入key和value不直接傳標簽uid
會有一些場景需要業(yè)務自定義標簽烟央,如省市區(qū)统诺,用戶使用時更想用101100這種全國通用的地區(qū)編碼來做標簽篩選歪脏。
做到這里疑俭,小C稍微松了一口氣,之后你來一個公司的數(shù)據(jù)婿失,如果有新的分類钞艇,就可以加標簽類別再加標簽值啄寡。如果同一分類下來新的值,先看一下分類的中文名是不是對應的上哩照,對應不上新建標簽挺物,然后讓產品去做標簽的整合或者就當成兩個不同的標簽來算。再也不怕整合數(shù)據(jù)了飘弧。
————————————————
版權聲明:本文為CSDN博主「雪糕的爸爸」的原創(chuàng)文章识藤,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接及本聲明次伶。
原文鏈接:https://blog.csdn.net/YaoLang1995/article/details/89173978