🐡

グラフデータベースの表面を撫でてみた

2024/06/07に公開

グラフデータベースとは何か

データをノード(点)とエッジ(線)、プロパティ(属性)で表現します。リレーショナルデータベースとは異なり、複雑な関係性を持つデータの処理に適しています。

ノード(Nodes)とは

点や丸で表現します。データエンティティを表します。

エッジ(Edges)とは

矢印でノード間のリレーションシップを表現します。

プロパティ(Properties)とは

ノードやエッジに付与できる属性情報を表します。

グラフ構造とは

グラフ構造は、ノードとエッジで構成されています。ノードはエンティティ(オブジェクトや要素)を表し、それぞれのノード間のリレーションシップや接続をエッジ(線やリンク)が表します。

グラフデータベースが適した場面

点と線を結んだものなので、ソーシャルネットワーク分析、SNSの投稿やフォロワー、マッチング属性検索に適しています。一方RDBのようなjoinという概念がなくデータを横断的に参照できないため、統計情報の算出はできません。

どんな構造か

RDBと違いスキーマレスなのでダイナミックな構成変更ができます。またプロパティを追加することでさまざま検索ができるようになります。

図1

RDBとの違い

RDBは、データをテーブル形式で格納します。これらのテーブルは行と列によって構成され、特定のテーブルは特定のテーマ(たとえば、顧客や商品)を表します。テーブル間の関係は、通常、外部キーによるリンクを介して表現されます。
グラフデータベースとRDBの主な違いは、グラフデータベースがデータ間の関係を主要な部分として扱う点です。これに対してRDBでは、リレーションシップはテーブル間のリンクとして存在しますが、それ自体がデータモデルの主要な部分ではありません。

なぜ速いか?

RDBはインデックスの参照やテーブルを連結したビューの用意で時間がかかるのに対し、グラフDBはノードがもつ隣接ノードの情報をたどるだけなので、レスポンスが高速です(図1)。

neo4jをさわってみる

neo4jを用意し起動してみる

docker-compose.yml

services:
  neo4j:
    image: neo4j:latest
    container_name: neo4j
    ports:
      - "7474:7474"
      - "7687:7687"
    volumes:
      - neo4j_data:/data
    environment:
      NEO4J_AUTH: neo4j/123456789
volumes:
  neo4j_data:

起動すると下記ログが表示されます。

neo4j  | 2024-06-01 05:02:40.124+0000 INFO  Logging config in use: File '/var/lib/neo4j/conf/user-logs.xml'
neo4j  | 2024-06-01 05:02:40.129+0000 INFO  Starting...
neo4j  | 2024-06-01 05:02:40.633+0000 INFO  This instance is ServerId{ce6e9619} (ce6e9619-5f6a-4068-929d-266f8d05c407)
neo4j  | 2024-06-01 05:02:41.068+0000 INFO  ======== Neo4j 5.20.0 ========
neo4j  | 2024-06-01 05:02:41.995+0000 INFO  Anonymous Usage Data is being sent to Neo4j, see https://neo4j.com/docs/usage_data/
neo4j  | 2024-06-01 05:02:42.037+0000 INFO  Bolt enabled on 0.0.0.0:7687.
neo4j  | 2024-06-01 05:02:42.289+0000 INFO  HTTP enabled on 0.0.0.0:7474.
neo4j  | 2024-06-01 05:02:42.290+0000 INFO  Remote interface available at http://localhost:7474/
neo4j  | 2024-06-01 05:02:42.291+0000 INFO  id: 563B4C5CA4578DF8785872FA263CD1D673BF6ED093711B8B65905AA02449E240
neo4j  | 2024-06-01 05:02:42.291+0000 INFO  name: system
neo4j  | 2024-06-01 05:02:42.292+0000 INFO  creationDate: 2024-06-01T05:02:41.479Z
neo4j  | 2024-06-01 05:02:42.292+0000 INFO  Started.

起動しブラウザでアクセスします。

データを投入する

図1になるようにデータを投入します。
cypherクエリというものを使います。

// ノードの作成
CREATE (a:AOKI {name: '青木', age: 20});
CREATE (b:IIDA {name: '飯田', age: 30});
CREATE (u:UEHARA {name: '上原', age: 40});

// 友達関係の作成
MATCH (a:AOKI), (b:IIDA)
CREATE (a)-[:FRIEND]->(b);

MATCH (b:IIDA), (u:UEHARA)
CREATE (b)-[:FRIEND]->(u);

確認してみる

全ノードとその関係を抽出する

MATCH (n) RETURN n;

全ユーザーの名前と年齢を確認する

MATCH (u)
RETURN u.name AS 名前, u.age AS 年齢;

青木を高橋に修正する

MATCH (u {name: '青木'})
SET u.name = '高橋';

高橋を削除する

MATCH (u {name: '高橋'})
DETACH DELETE u;

参考資料

グラフデータベースとは何か ~ネットワーク状のデータ構造から瞬時に情報を検索するDBを解説

Discussion