內容分類擴充套件性標籤設計

蘇格團隊發表於2019-03-22
  • 蘇格團隊
  • 作者:YaoLang

角色:產品汪小T,程式設計師小C


小T:小C,有活幹了。我們想做個線上題庫系統,老師可以搜尋題目來備課。

小C看著簡易的需求稿,心想,我一分鐘幾百萬上下,竟然找我做這麼簡單的需求。建個題目表不就完事了。

小C:題目資料從哪裡來,包含什麼屬性?

小T:我們第一期題目資料是從A公司那裡買過來的,題目包含正文,選項,答案,題型,難度。

小C:嗯,也就是我要建一張question表,包括這五個屬性。那題型和難度有哪些呢?

小T:題型有五種,單選,多選,判斷,填空,解答。難度有3種,簡單,一般,困難。使用者可以根據題型或者難度來篩選。 小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:搜尋根據body, options模糊匹配,然後篩選讓前端傳入type = 1或者difficult = 3 進行題型和難度的篩選

小T:哇,果然靠譜,那我們上線吧。


小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稍微鬆了一口氣,之後你來一個公司的資料,如果有新的分類,就可以加標籤類別再加標籤值。如果同一分類下來新的值,先看一下分類的中文名是不是對應的上,對應不上新建標籤,然後讓產品去做標籤的整合或者就當成兩個不同的標籤來算。再也不怕整合資料了。

相關文章