FIG-122

グラフデータベース — 友達の網を、引っ張ってたどる

データベース 2026.10.13 公開 読了 約9分

SNSの「知り合いかも」は、友達の友達を探して出しています。これをいつもの表(RDBMS)でやろうとすると、「友達関係」の表を1段たどるたびに表を引き直すことになります。2人先、3人先と深くなるほど、SQLも処理も重くなる。

グラフデータベースは発想が逆です。人を点(ノード)、関係を線(エッジ)として、クモの巣の形のまましまいます。1人をつまんで引っ張れば、つながっている人がビヨーンとついてくる。その「つながりの手触り」がそのままデータの持ち方です。下の図1で、人をドラッグして網を引っ張ったり、クリックして起点にして友達の輪をたどったりしてみてください。

GRAPH DATABASE — 関係を、クモの巣の形のまましまう
ドラッグで網を引っ張る / クリックでその人を起点にする
1人先にいる人 —
グラフDBがたどった線 —
表(RDBMS)なら、表を引き直す回数 —
RDBMS(SQL)— 1段ごとに JOIN が増える
 
グラフDB(Cypher)— 段数は数字を変えるだけ
 
READY
あおいさんの友達をたどってみる
上のボタンで何人先までたどるかを選ぶと、起点から波のように線が光っていきます。2人先、3人先にすると見つかる人が一気に増えること、そしてSQLがどんどん長くなることに注目してください。
図1 — グラフDBは起点から隣へ隣へと線をたどるだけ。表では1段ごとに友達関係の表を引き直し、そのたびに JOIN が1つ増える

表でたどると、1段ごとに表を引き直す

RDBMSで友達関係を持つなら、friendships(user_id, friend_id) のような表に「誰と誰が友達か」を1行ずつ書きます。あおいさんの友達なら、この表から user_id = 'あおい' の行を探せば済みます。

問題は2段目からです。「友達の友達」は、見つかった友達1人1人について同じ表をもう一度引く必要があり、SQLでは表を自分自身と JOIN します。3人先なら JOIN が2つ、4人先なら3つ。しかも1回1回が全員分の友達関係が入った巨大な表を探す作業なので、会員が増えるほど1段あたりも重くなっていきます。

グラフDBは、隣への道を持っている

グラフDBでは、1人1人のノードが「自分の友達はこの人たち」という線を直接持っています。友達の友達を探すときも、巨大な表を探し直すのではなく、いまいる人から出ている線を順にたどるだけ。かかる手間はたどった線の本数で決まり、網全体が100人でも1億人でも、あおいさんのまわりの手間は変わりません。

問い合わせ言語も、この形に合わせてあります。Cypherの (a)-[:FRIEND*2]-(p) は、矢印の絵そのままに「友達の線を2本たどった先の人」。3人先にしたければ *3 にするだけです。「おすすめの友達」「不正送金の資金の流れ」「部品の依存関係」など、つながりを何段もたどる質問が主役のとき、グラフDBは強みを発揮します。

逆に、「全会員の平均年齢」「先月の売上合計」のような表全体をまとめて集計する質問は、RDBMSのほうが得意です。グラフDBは、たどる質問のための専用の道具だと考えるのがよいでしょう。

用語ミニ辞書
ノード / エッジ
グラフの点と線。人や商品がノード、「友達」「購入した」などの関係がエッジ。
グラフデータベース
ノードとエッジをそのまま保存し、関係をたどる問い合わせを得意とするDB。Neo4jなど。
ホップ
エッジを1本たどること。「友達の友達」は2ホップ先。
自己JOIN
同じ表を自分自身とつなぐJOIN。表で関係を何段もたどると、段数分だけ必要になる。
Cypher
グラフDB向けの問い合わせ言語。(a)-[:FRIEND]->(b) のように、関係を矢印の絵で書く。

まとめ

グラフデータベースは、関係をクモの巣の形のまましまうデータベースです。表は「友達関係」を行として持つので、1段たどるたびに表を引き直し、JOIN が増えていきます。グラフDBは各ノードが隣への道を直接持っているので、手間はたどった線の本数だけ。つながりを何段もたどる質問が多いならグラフDB、表全体を集計するならRDBMS――データの「形」ではなく、よくする質問の形で選ぶのがコツです。