つながったデータの基礎 — RDF・オントロジー・SPARQL

Asterism は、表を「つながったデータ」に変える道具です。この章では、その裏側にある考え方を、はじめての人向けに説明します。操作はありません。読むだけの章です。

表のままだと何が困るか

料理のレシピを書きためた表です。

作成者: 山田                          ← 表の外(ファイルの先頭に書かれている)
作成日: 2026-09-01
出典: 家庭料理の記録
----------------
料理名,食材名,分量,単位              ← ここから下が表
カレー,にんじん,2,本
カレー,じゃがいも,3,個
肉じゃが,にんじん,1,本

人が見ればわかりますが、機械にとっては文字が並んだ格子です。この形だけからは、次のことがわかりません。

  • 分量 の 2 が何の 2 なのか(本数なのか、人前なのか)
  • 1 行目と 3 行目の「にんじん」が、同じにんじんのことなのか
  • 隣の人が作った価格表の「にんじん」と、この「にんじん」は同じものなのか

つながったデータとは、この「わからないこと」を機械が読める形で明記したデータのことです。人が毎回説明しなくても、機械が正しく解釈できます。

事実は 3 つ組で書く

つながったデータでは、すべてを「なにが — どんな項目で — どんな値か」という 3 つ組で書きます。この 3 つ組ひとつが、事実 1 件です。標準の用語ではトリプル(triple)と呼びます。

上の表の 1 行目は、こう書き換わります。主語の名前に料理名が入っていることに注目してください(理由は次の節)。

カレーのにんじん  ──[ 分量 ]──▶  2
カレーのにんじん  ──[ 単位 ]──▶  本
カレーのにんじん  ──[ 食材 ]──▶  にんじん

1 行 3 列だった表が、事実 3 件になりました。Asterism の画面が「事実 33 件」のように数えているのは、この 3 つ組の数です(11 行 × 3 項目 = 33)。

表の 1 行が、主語ひとつと 3 つの述語・値の組に展開される図

1 行が事実 3 件になる。主語は 1 つ、述語(項目)が 3 つ、目的語(値)が 3 つ。

3 つ組の各部分には名前があります。

位置標準の用語意味上の例
1 番目主語(subject)何についての事実かカレーのにんじん
2 番目述語(predicate)どの項目の話か分量
3 番目目的語(object)その値2

RDF とは、この「事実は 3 つ組で書く」という決まりごとの名前です。特別なソフトではなく、書き方の約束です。

IRI — 世界でひとつの名前

3 つ組の主語と述語は、ただの文字列ではいけません。「にんじん」という名前は、世界のあちこちの表に出てくるからです。そこで世界でひとつに決まる名前を使います。これが IRI です。見た目は URL とそっくりです。

IRI を、データの所在を表す部分・集まりを表す部分・1 件を指す部分に分解した図

IRI が同じなら同じもの、違えば違うもの。この一点だけで、別々の場所で作られたデータがあとから機械的につながる。

IRI は 2 種類あります。

種類何につける名前例
実体(データ)の IRI実際のもの 1 件ずつ.../resource/使用量/カレー/にんじん
語彙(項目)の IRI項目や種類そのもの.../ontology#分量

Asterism が ID の作り方を必ず人に確認するのは、この 1 件を指す部分をどの列から組み立てるかを決めるためです。ここを間違えると、別々のものが同じ名前になってしまい、あとから直すのが大変になります。

長い IRI を毎回書くのは大変なので、先頭部分に短い別名(接頭辞、prefix)を付けて recipe:分量 のように略記します。ファイルの先頭に並ぶ prefixes: は、この対応表です。

スラッシュは区切りで、階層ではありません。 使用量/カレー/にんじん は「使用量の下にカレーがある」という意味ではなく、ただの一意な文字列です。並べ方に決まりもないので、カレー/使用量/にんじん でも動きます。

それでも種類の名前を先に置くのが慣習です。理由は 2 つあります。

  • IRI の頭を見れば、それが何の IRI か分かる
  • 同じキーで別の種類があっても衝突しない(料理/カレー と 使用量/カレー/にんじん)

なお、このあとの図や表では末尾だけを取り出して使用量/カレー/にんじん のように短く書くことがあります。実際の IRI は、上の図のようにドメインから始まる 1 本の文字列です。

ID が衝突しないとはどういうことか

ここが設計でいちばん間違えやすいところなので、実例で説明します。上の使用量のID は、こう組み立てられています。

recipe:使用量/{料理名}/{食材名}
                │        └─ その行の食材
                └────────── その行の料理

もし 食材名 だけで名前を作ると、こうなります。

行料理食材食材名だけの ID料理名も使った ID
1カレーにんじん使用量/にんじん使用量/カレー/にんじん
4肉じゃがにんじん使用量/にんじん ← 同じ使用量/肉じゃが/にんじん

食材名だけだと、カレーのにんじん(2 本)と肉じゃがのにんじん(1 本)が同じ 1 件に潰れます。あとから取り込んだ方が前の分量を上書きしてしまいます。

食材名だけだと 1 件に潰れるが、料理名と組み合わせると別々の ID になることを示す図

ID の一意性は「どの範囲で一意か」で決まる。食材名 はこの表の中で何度も出てくるので、それだけでは名前にならない。

表の外の値も ID に使えます。 このファイルの先頭にある 作成者: 山田 は表の列ではありませんが、取り込みのとき表の全行に配られるので、ID の材料にできます(「読み取りの確認」で表の外の行の扱いを聞かれるのは、これを決めるためです)。別の人が作った同じ形のレシピ表と混ざらないようにしたいなら、作成者を ID に加えます。

これを人が確かめる場所が、かんたんモードの「できた形をたしかめる」の画面にある②「ID がひとつずつを指しているか確かめる」です。ID が重ならないか(✓ / ⚠)が表示され、⚠ が出たら組み合わせを選び直せます。

ID が重ならないことと、つながっていることは別です。 上の ID には料理名が文字として入っていますが、これは「料理という別のもの」への参照ではありません。「カレーに使う食材を全部」のような質問に答えられるようにするには、料理そのものをデータの種類として設計に足し、使用量からそこへの参照を持たせる必要があります(次の節)。

クラスと属性

事実をたくさん集めると、同じ形のものが繰り返し現れます。

  • 使用量は、どれも料理・食材・分量・単位を持つ
  • 食材は、どれも名前を持ち、店ごとの価格を持つ

この「使用量」「食材」という種類がクラス(class)です。そして、その種類が持つ項目が属性(プロパティ)です。3 つ組の述語に来るのが属性だと考えてください。

クラス「使用量」
 ├ 属性 分量        (値は数値)
 ├ 属性 単位        (値は文字)
 ├──▶ 料理         (別のものへの参照)
 └──▶ 食材         (別のものへの参照)

クラス「食材」
 └ 属性 名前        (値は文字)

属性の値には 2 種類あり、この違いが「つながる/つながらない」を決めます。

値の種類中身例できること
値そのもの数値・文字・日付分量 = 2大小をくらべる、絞り込む
別のものへの参照相手の IRIこの使用量 → にんじんまたいでたどる

後者があるから、データは網目状につながります。「にんじんを使う料理を全部」のような質問に答えられるのは、参照でつながっているときだけです。Asterism が「つながっていません」と指摘するのは、この参照が無い状態のことです。

何を種類にするか — 問いたいことが決める

ここに決まった正解はありません。ただし実用的な指針が 1 つあります。その値自身が、何かを持つ必要があるかです。

同じレシピ表でも、聞きたいことが違えば、種類にすべきものが変わります。

聞きたいこと種類にするなぜ
にんじんはどの店が安い?食材にんじん自身が価格を持つ必要がある
カレーの材料を全部料理カレー自身が材料を持つ必要がある
カレーのにんじんは何本?使用量料理と食材の組み合わせ自身が分量を持つ

かんたんモードの「意味をつける」の「他のデータとつながる手がかりはどれ?」(列に ☑ を付ける問い)も、同じことを別の言い方にしたものです。画面は、他でも同じ表記で出てくる言葉や番号に ☑ を付けるよう案内します。これは、外の世界も同じ名前で呼ぶ値・後から何か言いたくなる値・2 つ以上の種類から参照したい値、とおおむね重なります。

そして迷ったら種類にしてください。余分な種類はあとで消せますが、足りない種類は設計をやり直さないと足せず、公開したあとは動かせません。判断が非対称なので、多いほうに倒すのが安全です。

同じ項目を 2 か所に書きたくなったら

種類を増やすと「この項目は両方に要るのでは」と感じることがあります。ほとんどは次の 3 つに分かれ、うち 2 つは書かずに済みます。

① 参照で足ります。 「にんじんを使う料理」を引きたいから食材の側にも料理を持たせたい、と感じる場面です。要りません。SPARQL は矢印を逆にもたどれるので、片方に 1 本あれば十分です。

② 「何の性質か」を突き詰めると 1 か所に決まります。 価格表の「調査日」を店にも価格にも付けたくなりますが、よく考えると「その価格がいつ調べられたか」なので、価格の性質です。店は日付を持ちません。

③ 数えれば分かる値は、持たせません。 「カレーの材料数は 3」を料理に持たせると、材料を 1 つ足したときに直し忘れて矛盾します。問うときに数えるのが原則です。

なお、同じ列が複数の役割で現れるのは重複ではありません。

役割例(料理名 の列)
属性として料理の名前 ← ここだけが「属性」
ID の材料として使用量/カレー/にんじん
参照のキーとして使用量 → 料理 のつながり

禁じられているのは「同じ事実を 2 か所に書くこと」だけです。片方だけ直したときに、どちらが正しいか決められなくなるからです。

種類・1 件・絞り込みは、別のもの

「カレーの材料」のような言い方は、種類のように聞こえますが種類ではありません。この 3 つを分けておくと、設計で迷いにくくなります。

例IRI を持つか
種類(クラス)料理・食材・使用量持つ(語彙の IRI)
1 件(個体)カレー・にんじん・カレーのにんじん持つ(実体の IRI)
絞り込んだ集まりカレーの材料・にんじんを使う料理持たない

絞り込んだ集まりは、質問の答えとして得るものです。名前を付ける対象ではありません。

SELECT ?食材 WHERE { ?使用量 recipe:料理 料理:カレー ; recipe:食材 ?食材 . }

この問いは「カレーの材料」を返しますが、その集まり自体に名前は要りません。条件を変えれば別の集まりになるからです。

種類は「同じ形のものが繰り返し現れる単位」で決めます。「カレーの材料」を種類にしてしまうと、料理が増えるたびに種類が増えてしまいます。

そして 1 件のものは、外とつながるかどうかに関係なく IRI を持ちます。 事実を書くには主語が要るからです。「外とつながるか」が効くのは、何を種類にするかの判断のほうです。

オントロジー — 用語

クラスと属性を決めて、名前(IRI)を与え、「このクラスはこの属性を持つ」「この属性の値は数値」といった決まりを書いたもの。それがオントロジーです。データそのものではなく、データを書くための語彙集だと考えるのがいちばん近いです。

Asterism の画面では、これを用語と呼んでいます。ホームの星図の上の帯の札と、メニューの「知りたいこと」の「要る用語」が、いま使われているクラスと属性です。

語彙を他の人と揃えるほど、データはつながります。だから Asterism には、自分のデータ専用の言葉を、世界で使われている標準の語彙(QUDT・schema.org など)に結びつける機能があります(vocab-and-grounding.md)。

SPARQL — つながったデータへの問い方

Excel に対する検索やフィルタにあたるものが、つながったデータにもあります。それが SPARQL です。3 つ組の「わからないところ」を ?名前 にして書くと、あてはまる組み合わせを全部返してくれます。

SELECT ?料理 ?分量 WHERE {
  ?使用量  recipe:食材   ?食材 .        # 食材が
  ?食材    schema:name  "にんじん" .    # にんじん であるものを探し
  ?使用量  recipe:料理   ?料理 ;        # その料理と
           recipe:分量   ?分量 .        # 分量を返す
}
ORDER BY DESC(?分量)

Asterism では、SPARQL を自分で書く必要はありません。チャットでふつうの言葉で聞けば、内部でこの問い合わせが組み立てられ、答えと一緒に出どころが返ります。

用語の関係 — 何が何を必要とするか

ここまでの 6 つの言葉は、並べると同じ層のように見えますが、層が違い、必要とする向きが決まっています。

IRI を土台に RDF が乗り、その上に SPARQL が乗る。クラスと属性も IRI を使い、オントロジーがそれを束ねる依存関係の図

矢印は「必要とする」向き。逆向きの依存はない。

これを使うにはIRIRDFクラス・属性オントロジー
IRI を作る—不要不要不要
RDF で事実を書く必須—不要不要
クラス・属性を定める必須必須—不要
オントロジーを作る必須必須必須—
SPARQL で問う必須必須任意任意

IRI だけが何も必要としません。ただの名前の規則なので、クラスも属性も要りません。逆に、クラスと属性のほうが IRI を必要とします。IRI が根っこにあるのは、一度公開したら動かせないからでもあります。名前は動かせず、意味は後から直せます。

そして SPARQL にクラスもオントロジーも必須ではありません。次の問いは、何も知らなくても動きます。

SELECT * WHERE { ?s ?p ?o } LIMIT 10

三つの空間 — 交わっていそうで、疎

もう一つの見方があります。名前の空間・事実の空間・語彙の空間の 3 つで、後ろの2 つは同じ名前を使っているという事実だけでつながっています。

事実の空間と語彙の空間が別々にあり、両者は同じ IRI を使うことだけでつながっている図

事実の空間と語彙の空間の間にあるのは、点線 1 本だけ。

RDF は「この項目は定義済みか」を確かめません。だから次のことが起きます。

  • 語彙を決めずに、いきなり事実を書ける
  • あとから語彙を足しても、事実は書き換えなくてよい
  • 語彙の間違いが、事実を壊さない

裏を返せば、放っておくと何も結びつきません。結びつけるには、形の検査・推論・人のいずれかが要ります。

どれが SPARQL で引けるか

Asterism では、この疎結合が保存場所にも現れています。

どこにあるかSPARQL で引けるか
事実(使用量 分量 2)グラフの中引ける
型付け(使用量 a 使用量クラス)グラフの中引ける
外の標準に合わせた対応専用のグラフ引ける
種類と項目の細かい定義ファイル(model.yaml)引けない

星図に並ぶ種類と項目は、公開済みの事実から逆算して作られます(実際に使われている種類と項目を数える)。だから定義を書かなくても動く一方、「この種類は、あの種類の一種である」といった用語どうしの関係は、書いて公開しないかぎり質問には効きません。

画面の言葉との対応

Asterism はこれらの用語を、なるべくやさしい言葉に置き換えて表示しています。文献や他のツールを読むときのために、対応を挙げておきます。

Asterism の画面標準の用語ひとことで言うと
事実トリプル(triple)3 つ組ひとつ = 事実 1 件
データの種類クラス(class)料理・食材などの区分
項目属性 / プロパティ種類が持つ列にあたるもの
ID・ID の作り方IRI・IRI テンプレート世界でひとつの名前
用語オントロジー / 語彙使ってよいクラスと属性の一覧
つながり参照(オブジェクト属性)別のものを IRI で指すこと
高度な検索(SPARQL)SPARQL クエリつながったデータへの問い合わせ
変換ルールRML マッピング表を 3 つ組に変える規則
公開する昇格(promote)引用できる状態にすること

関連

  • 各ファイルが何をしているかは dataset-files.md を参照してください。
  • 語彙を標準に合わせる話はvocab-and-grounding.md を参照してください。
  • データどうしをつなぐ話は crosswalk.md を参照してください。