在選擇數(shù)據(jù)庫的路上坊秸,我們遇到過哪些坑麸祷?(2)

【編者按】你會(huì)怎么選擇數(shù)據(jù)庫,是關(guān)系數(shù)據(jù)庫褒搔、XML 數(shù)據(jù)庫阶牍、資源描述框架(RDF),還是圖形數(shù)據(jù)庫星瘾?本文的第1部分深入而生動(dòng)地探討了各種選擇走孽。在第2部分,將深入介紹使用 Neo4j 的注意點(diǎn)琳状。文章系國內(nèi) ITOM 管理平臺 OneAPM 編譯呈現(xiàn)磕瓷。

過渡到 Neo4j 之后的經(jīng)驗(yàn)和教訓(xùn)

下面介紹一些有關(guān)運(yùn)行 Neo4j 的實(shí)用技巧:

1. 如果你是 Java 商城,請嵌入式地運(yùn)行 Neo4j

Neo4j 是本地 Java 平臺念逞,我們又是 Java 商城困食,用 Neo4j 相當(dāng)合適。嵌入 Neo4j 讓我們不用再進(jìn)行 REST 調(diào)用翎承,這對于安全來說確實(shí)很重要陷舅。有關(guān)進(jìn)行 REST 調(diào)用的進(jìn)一步危害,請觀看這段有關(guān) REST 安全漏洞的 JavaOne 討論审洞。

嵌入式地運(yùn)行 Neo4j 還為我們大幅降低了復(fù)雜性。我們可以直接在進(jìn)程中調(diào)用 Neo4j API待讳,從而快速了解 Cypher 語言芒澜,以便運(yùn)行 Cypher 和 Java API 這兩者的結(jié)合體。同時(shí)我們再也不需要托管和非托管的擴(kuò)展了创淡。

2. 摸清自己的優(yōu)勢

摸清自己的優(yōu)勢和所選擇的工具的優(yōu)勢痴晦,這一點(diǎn)極為重要。用工具來做不適當(dāng)?shù)氖铝詹剩Ч麜?huì)大打折扣誊酌。

本地圖形數(shù)據(jù)庫在關(guān)系方面的表現(xiàn)確實(shí)很好;在圖形中找到切入點(diǎn)露乏,然后按照需要深入地研究各種關(guān)系碧浊,這在 Neo4j 中快得驚人。但如果想要在單個(gè)節(jié)點(diǎn)之外進(jìn)行復(fù)雜的多值屬性全文檢索瘟仿,效果就大打折扣了 —— 但我們選擇圖形數(shù)據(jù)庫并不是為了做這個(gè)箱锐。

3. 了解查詢時(shí)會(huì)發(fā)生哪些事情

了解查詢時(shí)會(huì)發(fā)生哪些事情,這一點(diǎn)也極為重要劳较,這能夠優(yōu)化 Cypher 語言驹止。

請看下面這個(gè)非常簡單的查詢浩聋。我想要找到 Franklin Country 所有擁有狩獵執(zhí)照的男性,并且執(zhí)照上的地址需要和此人的家庭住址相匹配臊恋,以便我們確認(rèn)這是同一個(gè)人衣洁。

我有一個(gè)人員節(jié)點(diǎn),一個(gè)執(zhí)照節(jié)點(diǎn)抖仅,還有一個(gè)位置節(jié)點(diǎn)坊夫,每個(gè)節(jié)點(diǎn)上都有各種不同屬性:

在選擇數(shù)據(jù)庫的路上,我們遇到過哪些坑岸售?(2)

數(shù)據(jù)庫要做的第一件事就是找到切入點(diǎn)(可能有多個(gè)切入點(diǎn))践樱,然后圖形從切入點(diǎn)展開搜索。尋找切入點(diǎn)通常是個(gè)讓人頭痛的問題凸丸。為此要使用帶有靜態(tài)索引集的基于規(guī)則的規(guī)劃程序拷邢,這一軟件已于近期升級為基于費(fèi)用。這雖然還不夠完美屎慢,但無疑已經(jīng)朝著正確的方向前進(jìn)了一大步瞭稼。

索引

索引基本上會(huì)復(fù)制數(shù)據(jù)庫中的信息片段,這樣有利于它迅速找到節(jié)點(diǎn)腻惠。在本例中环肘,只使用信息片段來確定切入點(diǎn)。雖然不是必須要使用索引集灌,但它確實(shí)能派上用場悔雹。如果要在特定的節(jié)點(diǎn)屬性上進(jìn)行檢索,在節(jié)點(diǎn)上設(shè)置一個(gè)索引會(huì)是個(gè)好辦法欣喧,即使這會(huì)占用磁盤空間腌零。

索引分為兩種:schema 和 legacy。Schema 索引是最新版唆阿,使用內(nèi)部自定義的 Neo4j 內(nèi)置索引益涧,目前是默認(rèn)設(shè)置。

一旦利用 Cypher 或 Java API 創(chuàng)建 schema 索引后驯鳖,這些索引就會(huì)自動(dòng)由數(shù)據(jù)庫維護(hù)闲询。例如,如果你想在每個(gè)帶有“人員”標(biāo)簽和“性別”屬性的節(jié)點(diǎn)上創(chuàng)建索引浅辙,當(dāng)你創(chuàng)建新節(jié)點(diǎn)扭弧、更改節(jié)點(diǎn)值或刪除節(jié)點(diǎn)時(shí),數(shù)據(jù)庫將自動(dòng)對其進(jìn)行更新记舆。這時(shí)你也可以設(shè)置限定條件寄狼,比如必須存在屬性或?qū)傩员仨毷俏ㄒ坏摹?/p>

Legacy 索引是 Lucene 索引,是較早的版本但尚未棄用〔蠢ⅲ可以通過配置文件伊磺、Neo4j 屬性文件、Java API 或 Cypher 來設(shè)置 legacy 索引删咱。Legacy 索引使用的是 Lucene 而非 Neo4j 專有索引機(jī)制屑埋。我們在用 Neo4j 時(shí)幾乎沒有什么漏洞,而每次遇到的漏洞基本都和 legacy 索引有關(guān)痰滋。即使是這樣摘能,有時(shí)候這些索引也是必要的。

Apache Luke 是一款非常不錯(cuò)的開源工具敲街,用戶可以用它直接查看和搜索 Lucene 索引团搞。這也幫助我們修復(fù)了 legacy 索引中的異常行為。

自動(dòng)索引與手動(dòng)索引

Legacy 索引有兩種用法:自動(dòng)索引和手動(dòng)索引多艇。我建議使用自動(dòng)索引,因?yàn)樗菀拙S護(hù)峻黍「绰。基本上只要設(shè)置一次(可以在配置文件中設(shè)置也可以通過 API 設(shè)置)姆涩,然后設(shè)為在特定類型的節(jié)點(diǎn)上為特定類型的屬性編寫索引。自動(dòng)索引還能夠在必要時(shí)輕松重建索引骨饿。

但是用戶無法指定是哪種類型的索引亏栈。在 Lucene 中,schema 存在不同索引類型宏赘,例如字符串仑扑、區(qū)分大小寫,以及數(shù)值置鼻,這些都是物理上獨(dú)立的索引。

如果你在查詢 Lucene 時(shí)想要使用這些索引蜓竹,必須要做的第一件事就是告訴 Lucene 要使用哪個(gè)索引箕母。但如果進(jìn)行自動(dòng)索引,Neo4j 可以根據(jù)你要編寫索引的第一個(gè)對象來選擇使用哪個(gè)索引俱济。例如嘶是,如果你設(shè)置的第一個(gè)索引是藍(lán)色,Neo4j 就會(huì)明白藍(lán)色是字符串蛛碌,然后會(huì)永久性地將藍(lán)色放在字符串索引中聂喇。

如果你能很好地控制收到的數(shù)據(jù),這一索引方式效果會(huì)很不錯(cuò)。但我們的系統(tǒng)沒有這樣希太。我們從許多不同的來源接收數(shù)據(jù)克饶,所以收到的“blue”(藍(lán)色)屬性可能會(huì)指年齡。但如果這一屬性是最先收到的誊辉,Neo4j 就會(huì)把年齡作為基于字符串的屬性而不是數(shù)值屬性來編寫索引矾湃,如此一來,之后就沒法按照我希望的方式展開進(jìn)一步比對和排列了堕澄。在這種情況下邀跃,只能手動(dòng)創(chuàng)建索引。

使用自動(dòng)索引的另一個(gè)好處是蛙紫,如果目錄無故損壞拍屑,很容易就能修復(fù)目錄】痈担可以暫停整個(gè)數(shù)據(jù)庫僵驰,進(jìn)入 Lucene 索引目錄,刪除此目錄裁蚁,重啟數(shù)據(jù)庫矢渊,然后 Neo4j 會(huì)為所有節(jié)點(diǎn)重新編寫索引。但如果已經(jīng)進(jìn)行了手動(dòng)索引枉证,你只能返回矮男,然后為所有節(jié)點(diǎn)重新編寫索引。

范圍查詢

下面一系列幻燈片顯示了范圍查詢:

在選擇數(shù)據(jù)庫的路上室谚,我們遇到過哪些坑毡鉴?(2)

我想查詢“profile”(個(gè)人信息),所以我把 PROFILE 放在查詢內(nèi)容的前面秒赤。我想找到收入為特定數(shù)值(50500)的所有人群并且只返回最前面的兩個(gè)結(jié)果猪瞬。

這段代碼表明,我已經(jīng)有了某人的收入索引入篮,規(guī)劃程序的限值是 2陈瘦。NodeIndexSeek 用這一索引來查找數(shù)值,從一個(gè)擁有 22 萬人的樣本數(shù)據(jù)庫中進(jìn)行了大約 2800 次數(shù)據(jù)庫訪問潮售。

在接下來的范圍查詢中痊项,我準(zhǔn)備查找收入低于 50500 的人:

在選擇數(shù)據(jù)庫的路上,我們遇到過哪些坑酥诽?(2)

在這次的查詢中鞍泉,我們執(zhí)行了 NodeByLabelScan,由于沒有使用索引肮帐,我們進(jìn)行了多達(dá) 43 萬次數(shù)據(jù)庫訪問咖驮。在 Neo4j 第 2.3 版之前,schema 索引不支持范圍,所以你必須得用 legacy 索引托修,然后直接查詢 Lucene 索引忘巧,才能發(fā)揮作用。

第 2.3 版修復(fù)了這一問題诀黍;現(xiàn)在有了 NodeIndexSeekByRange袋坑,可在 schema 標(biāo)簽上提供范圍索引:

在選擇數(shù)據(jù)庫的路上,我們遇到過哪些坑眯勾?(2)

4. 不要使用內(nèi)部節(jié)點(diǎn) ID

使用當(dāng)前節(jié)點(diǎn) ID 是個(gè)很大的誘惑枣宫,但這種做法非常不可取,這是因?yàn)樵谀承r(shí)刻吃环,這種做法會(huì)導(dǎo)致數(shù)據(jù)庫內(nèi)容被刪除也颤。請閱讀這篇介紹,了解更多相關(guān)內(nèi)容郁轻。

Neo4j 使用增量日志翅娶。如果你刪除了某個(gè)節(jié)點(diǎn),最后系統(tǒng)會(huì)翻轉(zhuǎn)節(jié)點(diǎn) ID好唯,這樣你就可以重復(fù)使用這些數(shù)字竭沫。我們結(jié)合使用了節(jié)點(diǎn)標(biāo)簽和隨機(jī)選擇的 UUID,這樣如果你的 API 始終暴露在外骑篙,就可以提供額外的安全保障蜕提。

5. 數(shù)據(jù)建模很重要

數(shù)據(jù)模型的重要程度至少和查詢相當(dāng)。下面的說明很有用:可以通過多重關(guān)系類型或關(guān)系上的屬性來為部分關(guān)系建模靶端。兩種方法似乎同樣合理谎势,但它們的性能表現(xiàn)可能大相徑庭。一定要了解一下 GraphAware 對這一內(nèi)容的介紹杨名。其區(qū)別在于脏榆,一方定義不同類型的 personplace 之間的關(guān)系……

在選擇數(shù)據(jù)庫的路上,我們遇到過哪些坑台谍?(2)

……而另一方則表示有三種不同的屬性類型:

在選擇數(shù)據(jù)庫的路上须喂,我們遇到過哪些坑?(2)

性能表現(xiàn)提升了八倍趁蕊。上述 GraphAware 的文章深入詳細(xì)地解釋了這一概念坞生。

6. 優(yōu)化性能

EXPLAINPROFILE 絕對是你的良師益友。別擔(dān)心 Java API介衔,而查詢規(guī)劃程序還很年輕,在許多情況下都比 Cypher 要快骂因。如果你要設(shè)定基準(zhǔn)炎咖,一定要以溫備份數(shù)據(jù)庫設(shè)定基準(zhǔn)。這樣就能加載 Neo4j 的數(shù)據(jù)庫緩存。

7. 一定要交流乘盼!

Neo4j 擁有強(qiáng)大的支持社區(qū)升熊,包括谷歌論壇、Slack 協(xié)作頻道绸栅、Stack Overflow 網(wǎng)站和非常出色的支持團(tuán)隊(duì)级野。

8. 在工具欄里添加下面的代碼

借助下面的樣板代碼,可以檢查數(shù)據(jù)庫中的每個(gè)節(jié)點(diǎn)并修復(fù)所有問題粹胯。這一示例有時(shí)會(huì)抓取關(guān)系蓖柔,但你也可以對節(jié)點(diǎn)或其他限定條件進(jìn)行同樣的操作。

不管怎樣风纠,它都能事務(wù)性地依次通過數(shù)據(jù)庫中的所有節(jié)點(diǎn)况鸣。在本例中,每個(gè)事務(wù)是 90000 次操作竹观,如果有需要镐捧,還可以批量更改整個(gè)數(shù)據(jù)庫:

在選擇數(shù)據(jù)庫的路上,我們遇到過哪些坑臭增?(2)

本文系 OneAPM 工程師整理呈現(xiàn)懂酱。OneAPM 能為您提供端到端的應(yīng)用性能解決方案,我們支持所有常見的框架及應(yīng)用服務(wù)器誊抛,助您快速發(fā)現(xiàn)系統(tǒng)瓶頸列牺,定位異常根本原因。分鐘級部署芍锚,即刻體驗(yàn)昔园,性能監(jiān)控從來沒有如此簡單。想閱讀更多技術(shù)文章并炮,請?jiān)L問 OneAPM 官方技術(shù)博客默刚。

本文轉(zhuǎn)自 OneAPM 官方博客

原文地址:https://dzone.com/articles/from-good-to-graph-choosing-the-right-database

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市逃魄,隨后出現(xiàn)的幾起案子荤西,更是在濱河造成了極大的恐慌,老刑警劉巖伍俘,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邪锌,死亡現(xiàn)場離奇詭異,居然都是意外死亡癌瘾,警方通過查閱死者的電腦和手機(jī)觅丰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妨退,“玉大人妇萄,你說我怎么就攤上這事蜕企。” “怎么了冠句?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵轻掩,是天一觀的道長。 經(jīng)常有香客問我懦底,道長唇牧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任聚唐,我火速辦了婚禮丐重,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拱层。我一直安慰自己弥臼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布根灯。 她就那樣靜靜地躺著径缅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪烙肺。 梳的紋絲不亂的頭發(fā)上纳猪,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音桃笙,去河邊找鬼氏堤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搏明,可吹牛的內(nèi)容都是我干的鼠锈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼星著,長吁一口氣:“原來是場噩夢啊……” “哼购笆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虚循,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤同欠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后横缔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铺遂,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年茎刚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了襟锐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡膛锭,死狀恐怖粮坞,靈堂內(nèi)的尸體忽然破棺而出笛质,到底是詐尸還是另有隱情,我是刑警寧澤捞蚂,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站跷究,受9級特大地震影響姓迅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俊马,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一丁存、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柴我,春花似錦解寝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至界睁,卻和暖如春觉增,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背翻斟。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工逾礁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人访惜。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓嘹履,卻偏偏與公主長得像,于是被迫代替她去往敵國和親债热。 傳聞我的和親對象是個(gè)殘疾皇子砾嫉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容