(1)存儲系統(tǒng)架構(gòu)
目前大規(guī)模的知識圖譜一般采用圖數(shù)據(jù)庫做為最基本的存儲引擎谈山。圖數(shù)據(jù)庫的優(yōu)點(diǎn)在于其天然的能表示知識圖譜結(jié)構(gòu),圖中的節(jié)點(diǎn)表示知識圖譜的對象庄萎,圖中的邊表示知識圖譜的對象關(guān)系辙纬;但是其缺點(diǎn)是圖數(shù)據(jù)庫的更新比較復(fù)雜生兆,對于復(fù)雜查詢的支持不夠瓷马。所以我們使用以圖數(shù)據(jù)庫為主拴还,結(jié)合其他系統(tǒng)的方式來存儲知識圖譜。
由于我們圖譜每天數(shù)據(jù)都會有變化欧聘,使用hadoop這種適合批量離線處理的系統(tǒng)做為離線更新系統(tǒng)片林,為了效率我們在hadoop上只計(jì)算增量變化;另外我們的圖譜支持用戶編輯怀骤,會將用戶的編輯操作記錄在mysql里费封,并且實(shí)時(shí)更新到圖數(shù)據(jù)庫里;圖數(shù)據(jù)庫做為存儲知識圖譜數(shù)據(jù)的系統(tǒng)蒋伦,用的是自己公司自己的分布式圖數(shù)據(jù)庫弓摘,對于開源的話一般是用neo4j或者titan;為了支持模糊和分詞查詢痕届,還將數(shù)據(jù)同步到了elastic search韧献。
(2)圖數(shù)據(jù)庫存儲結(jié)構(gòu)
在選擇圖數(shù)據(jù)庫做為存儲引擎之后,如何設(shè)計(jì)我們的存儲數(shù)據(jù)結(jié)構(gòu)呢研叫?
首先需要明確選用的圖數(shù)據(jù)庫是否支持schema free的锤窑。像我們的圖數(shù)據(jù)庫不是schema free的,每次節(jié)點(diǎn)增加屬性如果都需要清除數(shù)據(jù)重新導(dǎo)入嚷炉,肯定是無法接受的果复。因此我們抽取了所有節(jié)點(diǎn)的公有屬性做為節(jié)點(diǎn)基本屬性盼樟,比如“節(jié)點(diǎn)id”慢宗,“節(jié)點(diǎn)名稱”淑际,“創(chuàng)建時(shí)間”等,這樣的節(jié)點(diǎn)基本屬性一旦固定下來就需要不變化了独柑。
其次對于節(jié)點(diǎn)的非基本屬性,我們?nèi)孔鰹閳D中的邊來處理私植。比如音樂節(jié)點(diǎn)的“發(fā)行年份”屬性忌栅,我們鏈出一條邊指向String類型節(jié)點(diǎn),邊上有邊名和邊屬性曲稼,邊名就是“發(fā)行年份”索绪,邊屬性就是具體年份。但是后來我們發(fā)現(xiàn)會有海量節(jié)點(diǎn)都指向String贫悄,Double這種節(jié)點(diǎn)瑞驱,造成查詢效率問題。為了解決這個(gè)問題窄坦,我們將所有這種類型的邊指向節(jié)點(diǎn)本身唤反,這樣解決了海量節(jié)點(diǎn)問題凳寺。
最后是對于節(jié)點(diǎn)和節(jié)點(diǎn)之間的關(guān)系,使用邊來表示彤侍。比如姚明和葉莉之間有一條“丈夫”的邊肠缨,有一條“妻子”邊。另外我們的節(jié)點(diǎn)類型盏阶,也是用邊關(guān)系表示晒奕,例如姚明和籃球運(yùn)動(dòng)員之間,有一條“類型”的邊名斟。
(3)總結(jié)
知識圖譜的存儲結(jié)構(gòu)設(shè)計(jì)沒有統(tǒng)一的標(biāo)準(zhǔn)脑慧,我有看到對于數(shù)據(jù)量不是很大且結(jié)構(gòu)固定的圖譜就是使用傳統(tǒng)數(shù)據(jù)庫+關(guān)系表來存儲的,也有按照學(xué)術(shù)定義的rdf存儲的蒸眠。還是需要根據(jù)自己的應(yīng)用場景漾橙,數(shù)據(jù)情況來具體設(shè)計(jì),適合自己應(yīng)用場景的才是最好的楞卡。