はじめに
Amazon Neptuneって何?って思って書き始めました。
Graph系は社内でも知見がなく、Re:Inventで収集しようと考えています。
そこでいろいろ学ぼうと思い、インプットしたので、Qiitaでアウトプットしようと思います。
目次
Amazon Neptuneとは
Neptuneの「グラフ」とは何か
導入事例(国内/海外)
Neptuneが得意な場面の考え方
なぜTechouseはRDBではなくてNeptuneなのか
Property GraphとRDFの違い
🕸️ Amazon Neptuneとは
概要
Amazon Neptuneは、フルマネージドのグラフデータベースサービスです。
「ノード(頂点)」と「エッジ(関係)」でデータを表現する構造を持ち、複雑な関係性を高速に検索できます。
対応グラフモデル
| モデル | クエリ言語 | 用途のイメージ |
|---|---|---|
| Property Graph | Gremlin | ソーシャルネットワーク、アクセス権モデル |
| RDF (Resource Description Framework) | SPARQL | ナレッジグラフ、意味論的Web、メタデータ検索 |
特徴
| 特徴 | 説明 |
|---|---|
| ⚙️ フルマネージド | 高可用性構成(マルチAZ)や自動バックアップが標準装備。 |
| 🔍 高速な関係探索 | リレーショナルDBでは困難な「つながりの深い」検索を最適化。 |
| 🔄 Gremlin/SPARQL対応 | 標準的なグラフクエリ言語をサポートしている。 |
| 🧠 機械学習連携 | Amazon Neptune MLでグラフベースの予測(例:レコメンド)も可能。 |
利用イメージ
たとえば「このユーザーと共通の興味を持つ人を3段階先まで探す」といった検索は、
RDBではJOINが多くて重いですが、Neptuneではグラフ構造で高速に処理できます。
🕸️ Neptuneの「グラフ」とは何か
Neptuneは、「グラフ理論的なデータモデル」を扱うデータベースです。
つまり、
• ノード(Node) = もの・人・場所など「存在するもの」
• エッジ(Edge) = それらの間の「関係性」
を明示的に持つ構造です。
たとえばPowerPointで描くとこうなります:
[Alice] ── follows ──▶ [Bob]
[Alice] ── works_with ──▶ [Charlie]
[Charlie] ── belongs_to ──▶ [Team X]
これをNeptuneに保存すると、
• Alice, Bob, Charlie, Team X がノード
• follows, works_with, belongs_to がエッジ
として登録されます。
💾 Neptuneに保存する目的
Neptuneの目的は、「関係性の探索」や「つながりの発見」にあります。
例1:SNSのフォロー関係
• 「ユーザーAのフォロワーを3段階先まで辿る」
• 「AとBが共通でフォローしている人を探す」
例2:組織や権限構造
• 「この権限を持つ人の上司・部下の関係をトレース」
• 「このサービスにアクセスできる経路を辿る」
例3:ナレッジグラフ/推薦システム
• 「この製品を買った人が次に買った製品」
• 「この単語と意味的に関連する概念」
👉 RDB(リレーショナルDB)ではJOINが多重に必要な関係探索を、
Neptuneではエッジをたどるだけで高速に処理できます。
⚙️ Neptuneのデータモデルは2種類
モデル 概要 クエリ言語 主な用途
Property Graph ノードとエッジに属性(プロパティ)を持たせる。
例:ユーザー名や年齢 Gremlin ソーシャルグラフ、アクセス権管理
RDF (Resource Description Framework) 「主語 - 述語 - 目的語」というトリプル形式。
例:「Alice は Bob をフォローしている」 SPARQL ナレッジグラフ、意味論的Web
📊 Neptuneと「機械学習」との関係
Neptune自体は「学習アルゴリズム」を直接持つわけではありません。
しかし、Neptune ML という拡張機能を使うことで、
保存されたグラフ構造から「関係性を学習」することができます。
Neptune MLでできること
• 「この人は誰をフォローしそうか」
• 「この製品と似た属性を持つものは何か」
• 「このノードとつながる可能性の高いノードを予測」
つまり、
• Neptune(通常):関係性を保存・探索する
• Neptune ML:関係性を学習・推論に活用する
という関係になります。
🧠 まとめ:PowerPointの矢印を「クエリ可能に」したDB
観点 Neptune
グラフの意味 ノードとエッジの関係構造(PowerPointの矢印的な意味)
保存するもの エンティティ(ノード)と関係(エッジ)
得意な処理 「つながり」や「経路」を辿る検索
数値解析との違い 相関・回帰などの数値グラフではない
拡張機能 Neptune MLにより、関係性をAIが学習・推論可能にする
🏛️ 導入事例(国内/海外)
経済産業省(日本) — 法人情報検索 “gBizINFO”
• 概要:日本の法人情報(法人番号、所在地、補助金、特許、調達実績など)を集約・公開するデータ基盤(gBizINFO)に、Neptuneを LOD(Linked Open Data)基盤 として採用。Amazon Web Services, Inc.
• 利用目的:法人間の関係性や属性をリンクさせて、2次利用しやすい形で公開すること
• 特徴:SPARQL(RDFモデル)でのクエリAPIを提供し、検索性能を改善した事例。Amazon Web Services, Inc.
→ この例は「公共機関+オープンデータ+関係性重視」の典型です。
Techouse/クラウドハウス労務(日本、SaaS企業)
• 概要:SaaS型の人事労務サービスにおいて、Neptuneを組織構造や権限管理用グラフDBとして導入した事例。Techouse Developers Blog
• 利用目的:
・企業組織の階層構造(親部署/子部署など)を深くたどる処理
・権限データベースとして、誰がどの部署・サブ部署で何の権限を持つかを即時判定
• RDBと比較して
・再帰的な階層構造を扱いやすい
・深い関連を辿るクエリが効率的
という点が評価されて導入に至ったようです。Techouse Developers Blog
この事例は、個人開発に近いスケール感でも「組織構造」「権限管理」などでグラフDBを使える可能性を示しています。
Nike — ソーシャルグラフ
• 概要:Nike が自社アプリ/ソーシャル要素を拡張するため、既存のシステム(Cassandra + EC2構成)から Neptune に移行したという情報があります。Speaker Deck+1
• 利用目的:
・ユーザー同士の関係性(フォロー・関係リンク)を管理
・複数のクエリ処理を Neptune 単体に統合、処理効率を向上させる
・運用負荷/保守性の改善
• 効果:
・同等の処理をより少ないリソースで実現
・複数クエリを一つのグラフクエリで扱えるように削減 Speaker Deck
この事例は “大規模なソーシャルグラフ処理” の用途として Neptune を使っている典型例です。
LexisNexis — 法務・引用関係
• 概要:法律・引用データベースを扱う LexisNexis が、文献引用関係を扱うグラフ構造を Neptune で管理しているとの導入事例。YouTube
• 利用目的:
・判例や論文、法令などが互いに “引用/参照” し合う関係性をグラフとして扱う
・法律文書を編集・参照する際、「この文書は何を参照しているか」「どの文書に参照されているか」を高速に探索
• 効果:
・引用の追加・変更を即時反映
・検索や参照関係の探索時間を大幅に短縮
Siemens — ナレッジグラフ / 部品関係可視化
• 概要:Siemens Energy が Turbine(タービン機器)に関する ナレッジグラフ を Neptune 上に構築。Amazon Web Services, Inc.
• 利用目的:
・タービン機器の部品同士の関係(共通部品、交換履歴、部品間相関)を可視化
・類似部品や交換候補部品を探索
・メンテナンス支援、信頼性分析
• 効果:
・部品の相関関係を直感的にたどれるようになった
・運用負荷を低減しつつ、探索性能を確保
🧾 まとめとヒント
• Neptune を採用している会社・組織でも、関係性を扱う用途が多く見られます(ソーシャルグラフ、組織構造、文書引用、ナレッジグラフなど)。
• 特に「参照関係」「階層構造」「共通属性によるリンク」「探索クエリが複雑になる関係」などが絡む場面で威力を発揮しています。
• これらは、個人開発でも十分応用可能なテーマです(例えば、趣味マッチング、用語辞典、キャラクター相関図など)。
🧭 Neptuneが得意な場面の考え方
通常のRDB(MySQLなど)で得意なこと Neptune(グラフDB)で得意なこと
「Aという商品がいくつ売れた?」 「Aを買った人と似た行動をする人は?」
「社員ID=123の所属部署は?」 「この社員から3段階上の上司は誰?」
「投稿の一覧を表示」 「投稿した人たちの人間関係をもとにおすすめを出す」
→ 要は、**「1対多」「多対多」「深い関連づけ」**が登場する場面に強いです。
💡 個人開発での利用例5選
① SNSやマッチングアプリ(人と人の関係グラフ)
• アプリ例:
「共通の興味を持つ人をつなぐSNS」「趣味でマッチングするアプリ」
• Neptuneの使いどころ:
「誰が誰をフォローしているか」「共通の友達が何人いるか」「似た興味の人を推薦」
• クエリ例(Gremlin):
• g.V('Alice').out('follows').out('follows')
→ Aliceの「友達の友達」を取得。
📌 イメージ:PowerPointで描くような「友達ネットワーク」をそのまま検索可能にしたアプリ。
② ナレッジグラフ型のWiki / 知識ベース
• アプリ例:
「用語間の関連をたどれる技術用語辞典」や「社内知識グラフ」
• Neptuneの使いどころ:
「この用語に関連する概念は?」「この技術と一緒に使われるものは?」
• イメージ:
Wikipediaを“つながり”で横断検索できるようなアプリ。
例えば「Kubernetes → Pod → Container → Image」とたどっていく感じ。
📌 個人でも、「勉強ノートをNeptuneに入れて、関連知識をグラフ検索できる」なんて使い方も面白いです。
③ レコメンドエンジン(「あなたにおすすめ」機能)
• アプリ例:
「映画・音楽・商品」などの推薦アプリ。
• Neptuneの使いどころ:
「似た嗜好のユーザーが見た作品」「共通タグを持つアイテム」を探索。
• 補足:
ここにNeptune MLを使うと、グラフ構造から「似ているノード」を自動で予測できます。
📌 例:「あなたが好きなAを見た人はBも好き」的なNetflix風推薦を自作できる。
④ ネットワーク・依存関係の可視化
• アプリ例:
「インフラ構成の可視化」「アプリの依存関係グラフ」
• Neptuneの使いどころ:
「どのサービスがどのAPIを呼んでいるか」「このサーバーが通信する相手は?」
• イメージ:
AWSのVPC構成図やアプリの依存関係を、クエリでたどれるようにする感じ。
📌 個人でも「自分のAWSリソースをGraph構造で整理する可視化ツール」を作るのに使えます。
⑤ 物語・ストーリーマップ/創作系
• アプリ例:
「登場人物の関係図」「ストーリー分岐マップ」
• Neptuneの使いどころ:
「このキャラは誰とどんな関係?」「この出来事に関係する人物は誰?」
• イメージ:
小説やゲームのキャラ関係図を“クエリで検索できる”ようにしたもの。
📌 例:「Aが敵対しているがBとは盟友」「CはBを裏切った」などをデータで管理。
なぜTechouseはRDBではなくてNeptuneが良いのか
🧱 前提:Techouseのような構造をざっくり想像
クラウドハウス労務のような人事SaaSでは、
会社 → 部署 → チーム → メンバー みたいな階層があります。
さらに:
• 部署は「親部署」「子部署」などツリー構造
• メンバーは「複数部署に所属」することもある
• 権限(承認権限など)は上の階層から引き継がれる
つまり、ざっくりこんな関係です:
Company
└── HR Department
├── Payroll Team
│ └── Alice
└── Hiring Team
└── Bob
💡 ① RDB(リレーショナルデータベース)の場合
テーブル構造
たとえば departments テーブルがこうあるとします:
| id | name | parent_id |
|---|---|---|
| 1 | Company | NULL |
| 2 | HR Department | 1 |
| 3 | Payroll Team | 2 |
| 4 | Hiring Team | 2 |
「親部署の下にある部署」を表すために、parent_id というカラムを使います。
🔁 課題1:深い階層をたどるのが大変
たとえば「Payroll Teamのすべての上位部署を取得したい」とき、
RDBではSQLをこんな感じで書く必要があります:
WITH RECURSIVE hierarchy AS (
SELECT id, name, parent_id
FROM departments
WHERE id = 3 -- Payroll Team
UNION ALL
SELECT d.id, d.name, d.parent_id
FROM departments d
INNER JOIN hierarchy h ON d.id = h.parent_id
)
SELECT * FROM hierarchy;
つまり、再帰CTEというSQLの特殊構文を使って、
自分の上にある親を1段ずつたどる必要があります。
これが「階層が5段、10段」と深くなったり、
同じようなJOINが大量に必要な場面ではクエリが複雑&重いです。
🔁 課題2:多対多関係の横断が重い
さらに、部署と社員が多対多の関係(1人が複数部署に所属)になると、
departments_employees のような中間テーブルが必要になります。
例えば「Aさんと同じ上位部署に所属する人」を探したい場合、
SQLはかなり複雑になります。
SELECT e2.name
FROM employees e1
JOIN departments_employees de1 ON e1.id = de1.employee_id
JOIN departments d1 ON de1.department_id = d1.id
JOIN departments d2 ON d1.parent_id = d2.id
JOIN departments_employees de2 ON de2.department_id = d2.id
JOIN employees e2 ON e2.id = de2.employee_id
WHERE e1.name = 'Alice';
JOINだらけです😅
階層が増えるほど、クエリが爆発的に複雑になります。
🕸️ ② Neptune(グラフデータベース)の場合
Neptuneでは、部署や社員を「ノード」として登録し、
「所属している」「上位部署である」という関係を「エッジ」として登録します。
(Alice) ── member_of ──▶ (Payroll Team)
(Payroll Team) ── child_of ──▶ (HR Department)
(HR Department) ── child_of ──▶ (Company)
✅ クエリが直感的になる(Gremlin例)
例えば「Payroll Teamの上位部署をすべてたどりたい」なら:
g.V('Payroll Team').repeat(out('child_of')).emit().values('name')
👉 repeat() で上位に上る処理を再帰的に実行。
SQLのCTEよりも1行で書けて、深さが増えても同じ構文で済みます。
✅ 関連探索も簡単
「Aliceと同じ上位部署に所属する人」を探すなら:
g.V('Alice').
out('member_of'). # Aliceの部署へ
repeat(out('child_of')).emit()# 上位部署をたどる
in('member_of'). # その部署に所属する人
values('name')
JOINもサブクエリも要りません。
人 → 部署 → 上位部署 → 人というつながりを矢印のようにたどるだけ。
RDBで5行必要なSQLを、Gremlinでは1文で表現できます。
🚀 ③ なぜNeptuneが勝っているか(Techouse事例の本質)
| 比較項目 | RDB | Neptune |
|---|---|---|
| 構造 | 表形式(テーブルとカラム) | グラフ構造(ノードとエッジ) |
| 階層の扱い | 再帰CTEが必要で複雑 | repeat() や path で自然に書ける |
| 階層が深い場合の性能 | JOINが増えて遅くなる | エッジをたどるだけなので高速 |
| 多対多関係の扱い | 中間テーブルが必要 | エッジを直接張れる |
| スキーマ変更 | テーブル変更が必要 | ノードやエッジを追加すればOK |
| クエリの直感性 | SQL的(構文が重い) | 「つながり」を直感的に書ける |
Techouseのような「組織構造・権限・所属」系の処理は、
• 再帰(上司・親部署)
• 多対多(複数所属・権限委譲)
• 動的関係(組織変更・異動)
などが日常的に発生するため、
RDBでは管理もクエリも複雑化しがちなんです。
Neptuneなら「関係性を中心に設計する」ため、
組織が変わっても柔軟に追従できる構造になります。
🧠 まとめ:「深い関係」を“自然に”扱えるのがNeptune
RDBだと Neptuneだと
「JOINでつなぐ」 「エッジでたどる」
「再帰SQLが必要」 「repeat()で辿る」
「多段JOINで重い」 「探索が軽い」
「構造を無理やりテーブルに押し込む」 「つながりをそのまま表現できる」
Property GraphとRDFの違い
🏫 前提:共通の現実世界
学校A, 学校B, 学校C がある
それぞれ 1〜3年生
学年ごとに Aは5組, Bは6組, Cは7組ある
🧱 Property Graph(構造をたどるタイプ)
■ 目的
アプリやシステムの中で「構造的にたどりたい」場合に使います。
つまり、「誰がどこに所属しているかを効率的に操作したい」という用途です。
💡 どんな場面で使うか
• 校務システムや出席簿アプリ
• 組織ツリーのように「階層をたどる」ことが多いケース
• 例:「生徒Xが所属するクラス → 学年 → 学校をたどる」
🧩 構造イメージ
(学校A) ── has_grade ──▶ (1年)
(1年) ── has_class ──▶ (1組)
(1組) ── has_student ──▶ (山田太郎)
🔍 クエリ例(Gremlin)
山田太郎が所属する学校名を知りたい
g.V("山田太郎").in("has_student").in("has_class").in("has_grade").values("name")
→ 「山田太郎」→「1組」→「1年」→「学校A」まで矢印を辿る。
→ 結果:「学校A」
✅ 向いている状況まとめ
目的 例
階層をたどる 生徒→クラス→学年→学校
深い構造の中で探索したい 1年1組に所属する全員を取る
組織変更がよく起きる クラス追加や転校も柔軟に対応
アプリ開発の内部構造 JSON的・ツリー的なデータ操作
👉 つまりProperty Graphは「学校というツリーを辿るアプリ的用途」向き。
🌐 RDF(意味・共通語彙でつなぐタイプ)
■ 目的
異なるデータソース同士を**“意味でつなぐ”**場合に使います。
つまり、「世界中の教育データを共通の言葉で検索・共有したい」という用途です。
💡 どんな場面で使うか
• 文部科学省や自治体が公開する「教育オープンデータ」
• 学校の情報・学年・クラスを他の省庁データとリンクしたい場合
例:
o 「学校Aがある市区町村の教育統計」
o 「この学校に設置されているICT設備」
o 「全国の3年1組の生徒数を比較」
🧩 RDF構造(トリプル)
それぞれを文の形で表します:
<学校A> <hasGrade> <1年> .
<1年> <hasClass> <1組> .
<1組> <hasStudent> <山田太郎> .
<山田太郎> <type> <Student> .
<学校A> <locatedIn> <東京都練馬区> .
<1年> <rdf:type> <Grade> .
🔸すべてURI(世界共通ID)で書ける
→ https://school.example.jp/A のように外部と連携可能
🔍 クエリ例(SPARQL)
全国の「東京都にある学校」の1年生を全部取りたい
SELECT ?school ?grade
WHERE {
?school <locatedIn> <東京都> .
?school <hasGrade> ?grade .
?grade <rdf:type> <Grade> .
}
→ 出力:「学校Aの1年」「学校Bの1年」「学校Cの1年」...
✅ 向いている状況まとめ
| 目的 | 例 |
|---|---|
| 意味で検索したい | “hasGrade”を持つ全学校 |
| 他データとつなげたい | 教育統計、地域データなど |
| 世界共通フォーマットで共有 | LOD(Linked Open Data) |
| 公開・再利用されるデータ | 政府系、研究系、学術系 |
👉 つまりRDFは「“教育という概念”を世界と共有するデータ形式」向き。
🎯 違いを一言でまとめると
| 観点 | Property Graph | RDF |
|---|---|---|
| 目的 | 構造をたどる | 意味をつなぐ |
| イメージ | 学校の中の関係図 | 教育全体の共通語彙 |
| 向いている使い方 | 学校アプリや出席管理 | 政府や研究機関のデータ公開 |
| クエリ方式 | 「生徒→クラス→学校」経路探索 | 「学校という意味を持つ全データ」検索 |
| クエリ言語 | Gremlin | SPARQL |
🧠 たとえで言い直すと…
| たとえ | Property Graph | RDF |
|---|---|---|
| 例 | 教務システムで生徒を管理 | 教育オープンデータで全国の学校情報を共有 |
| 操作感 | 「この生徒がどこに属してる?」 | 「全国で“学校”という概念を持つエンティティは?」 |
| クエリ思考 | 経路(構造) | 意味(セマンティクス) |
似てるけど違う 組織図を“辿る” vs 世界中の学校を“つなぐ”
✅ まとめの一言で言うと:
• Property Graph は「学校の中を動き回る」ための地図。
• RDF は「“学校”という概念を他の地図と共有する」ための言語。