グラフデータベースの表面を撫でてみた
グラフデータベースとは何か
データをノード(点)とエッジ(線)、プロパティ(属性)で表現します。リレーショナルデータベースとは異なり、複雑な関係性を持つデータの処理に適しています。
ノード(Nodes)とは
点や丸で表現します。データエンティティを表します。
エッジ(Edges)とは
矢印でノード間のリレーションシップを表現します。
プロパティ(Properties)とは
ノードやエッジに付与できる属性情報を表します。
グラフ構造とは
グラフ構造は、ノードとエッジで構成されています。ノードはエンティティ(オブジェクトや要素)を表し、それぞれのノード間のリレーションシップや接続をエッジ(線やリンク)が表します。
グラフデータベースが適した場面
点と線を結んだものなので、ソーシャルネットワーク分析、SNSの投稿やフォロワー、マッチング属性検索に適しています。一方RDBのようなjoinという概念がなくデータを横断的に参照できないため、統計情報の算出はできません。
どんな構造か
RDBと違いスキーマレスなのでダイナミックな構成変更ができます。またプロパティを追加することでさまざま検索ができるようになります。
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;
Discussion