2010年12月8日水曜日

Tutorial D で外部キーの定義 - 整合性制約で記述

Tutorial D の拡張と要約 - 値の計算と集約」のつづき

Tutorial D で関係変数の定義と代入」 では、以下のモデルに基いた関係変数を定義した。

5093301582_c738e3bb96

ソースコードはこちら。

上記 「割当て」 に対応した関係変数の定義は以下の通り。

var assignments base
  relation { id integer
           , p_id integer
           , g_id integer
           , date character }
    key {id};

「外部キー」を設定するのを忘れていたので、以下のように修正。

var assignments base
  relation { id integer
           , p_id integer
           , g_id integer
           , date character }
    key {id}
    foreign key {rename(p_id as id)} references persons
    foreign key {rename(g_id as id)} references groups;

しかし、Rel ではエラーが出て定義できない。 (+_+)

 

外部キーを整合性制約として記述する

Rel for M359 students によると「外部キー」は、

not defined in Tutorial D (use constraint instead,

Tutorial D では外部キーに対して特別な構文があるわけではなく、 「制約」 で記述するとのこと。

4873112753これに関して データベース実践講義 (p71) では次のように述べられている。

ここまで外部キーについて説明してきたのは、それらが実際に非常に重要であり、当初定義されたモデルの一部であるからだ。だが筆者が思うに、それらが実際には基本原理ではなく、現実に必要になることが多い特定の整合性制約の省略表記にすぎないことを強調しておくべきだろう。

 

制約の書き方

先ほどの "Rel for M359 students" には外部キーの制約を、

  • 半結合 
  • 関係が空であることを調べる IS_EMPTY 演算子

の二つを利用した方法が書かれている。

constraint 制約の識別子
  IS_EMPTY(参照元の関係変数 not matching 参照先の関係変数);

これを参考にして、上記の 「割当て」 に整合性制約を設定してみる。

 

「割当て」 の整合性制約

設定したい制約は、「割当て」 における 「人」 を指し示す属性 p_id に、「人」 として存在しないタプルのキーが入力されないようにすること。

大雑把に次のように言い換えることができる。

  • 「割当て」 から見て、「人」 へとリンクしない「割当て」のタプルがあってはならない。

これを制約として書くなら、

constraint AssignmentsFKPersons 
  IS_EMPTY(assignments not matching persons rename(id as p_id));

ただし、IS_EMPTY は大文字で記述する必要がある。

もう一つ、「割当て」における 「グループ」 を指し示す属性 g_id に、「グループ」 として存在しないタプルのキーが入力されないように制約を設定。

constraint AssignmentsFKGroups 
  IS_EMPTY(assignments not matching groups rename(id as g_id));

 

演算子は大文字・小文字を区別する

ところで、演算子 IS_EMPTY を is_empty と小文字で書くとエラーとなる。 Rel / Tutorial D Grammar を見ると is_empty がなかったので、最初 Rel では関係が空であることを確認する演算子が用意されていないのかと思った。

Language Enhancements によると、

Case sensitivity: Rel language keywords are not case sensitive. By convention, keywords are shown here in upper case to visually distinguish them, but the parser recognises them in lower case as well. Rel identifiers and string comparisons are case sensitive.

キーワードは大文字・小文字の区別をしないけれど、識別子は区別される。 よって、演算子の名前は大文字・小文字が区別される。 ( cf. op_def )

これに対して、Rel / Tutorial D Grammarsummary に定義されている COUNT 等は、キーワードなので小文字で書いても問題ないようだ。