導入
「友達の友達を探す」というよくある要求を、表形式のデータベース(RDB)とグラフデータベースでそれぞれ考えてみると、両者の設計思想の違いがはっきり見えてきます。
説明
RDBで「人物」と「友達関係」を表すと、ふつう次のような2つの表になります。
Person表(id, name, …)Friendship表(person_id, friend_id)… 中間テーブル
graph TB
subgraph rdb["RDB: 中間テーブルで関係を表す"]
P["Person表<br/>id, name"]
F["Friendship表<br/>person_id, friend_id"]
P -.参照.-> F
F -.参照.-> P
end
「アリスの友達の友達は誰か」を調べるには、Person と Friendship を何度も JOIN(結合)する必要があります。友達を1ホップ(1段階)たどるごとにJOINが1つ増え、「友達の友達の友達」のように段数が増えるほどSQLは長く複雑になり、実行も遅くなりがちです。これがいわゆる「JOINの地獄」です。
一方、グラフデータベースでは関係がすでにデータとして直接つながっているため、Cypherでは次の1行で済みます。
MATCH (a:Person {name: 'Alice'})-[:KNOWS]->()-[:KNOWS]->(fof:Person)
RETURN DISTINCT fof.name
--> を1つ増やせば1ホップ増える、というシンプルな対応関係です。JOINのように毎回テーブルを結合し直すのではなく、あらかじめ張られた線をそのままたどるだけなので、つながりが深くなっても書き方の複雑さがほとんど増えません。これが、グラフデータベースが「つながりの探索」を得意とする理由です。