2010年11月12日金曜日

Tutorial D の拡張と要約 - 値の計算と集約

Tutorial D でリレーショナル代数」のつづき

拡張

既存の属性を元に計算した結果を関係に追加する。 SQL では SELECT 句においてカラムに演算子を適用することに相当。Date によると、

「オリジナルで定義されたリレーショナル代数の範囲を超えてしまう」

(データベース実践講義, p101より)

ために 「拡張」 と呼ばれる。

例えば、「人」 に対して、

  • 年齢の 2 倍
  • 男性であるかどうか?

となる属性を関係に追加したい場合は、

extend persons 
  add(age * 2 as DoubleAge, gender = 1 as isMale)

311-12-2010CropperCapture[3]

(対象のデータベースはこちら)

 

拡張の後に制限

上記の書き方を見ると SQL の方が簡単に思えるが、Tutorial D の拡張により返されるのは 「関係」 であるため、返される値に対してスムーズに制限を適用できる。

先ほどの結果に対して、

  • 年齢を 2 倍したら 50 以上で、かつ、男性である人

を抽出したい場合、

extend persons
  add(age * 2 as DoubleAge, gender = 1 as isMale)
  where DoubleAge >= 50 and isMale

と書くことができる。

 

要約

「人」 の要素数を知りたい場合は、

summarize persons 
  add(count() as pCount)

411-12-2010CropperCapture[4]

最高齢の人を求めるには、対象となる属性 age を max に与える。

summarize persons 
  add(max(age) as pMax)

511-12-2010CropperCapture[5]

定義されている要約は summary を参照。

 

特定の基準で要約 - by

SQL で言う GROUP BY に相当するもの。

例えば、性別ごとの人数を得るには、

summarize persons 
  by {gender}
    add(count() as pCount)

611-12-2010CropperCapture[6]

per を使っても上記と同じ結果が得られる。

summarize persons
  per(persons {gender})
    add(count() as pCount)

ただし、これだと書くのが面倒なので、上記のように by が定義されているのかな。

 

他の関係変数と組み合わせる - per

per は別の関係変数と組み合わせたときに有用。

例えば、「割当て」 を 「人」 の id ごとにカウントしたい場合に by を使うと、

summarize assignments 
  by {p_id}
    add(count() as pCount)

811-12-2010CropperCapture[8]

当然ながら、「割当て」 がされてない人は表示されない。

これに対し、「人」 を基準にして 「割当て」 を要約すると、

summarize assignments 
  per((persons rename(id as p_id)) {p_id})
    add(count() as pCount)

 711-12-2010CropperCapture[7]

「割当て」 がされてない人も表示される。

by と per の定義については、summarizeper_or_by を参照。

Tutorial D で外部キーの定義 - 整合性制約で記述」につづく

Firefox の Adblock Plus でホワイトリストの設定

1. ホワイトリストの追加

追記(2013/06/08)Adblock Plus を有効にしていると利用できないサイトがある。その場合、Adblock Plus のホワイトリストにサイトを追加する必要がある。

特定のサイトをホワイトリストに追加するには、当該サイトをブラウザで開いておき、

  • Adblock Plus のアイコンをクリック > XXXXXX で無効

を選択する。 XXXXXX として、「ドメイン、ページ、すべてのサイト」を選択できる。

 

全ページで AdBlock を無効にしてから、ホワイトリストに追加する

追記(2013/06/25):上記の方法によりホワイトリストに追加できない場合、

  1. 全ページで AdBlock を無効にする。
  2. ホワイトリストに追加したいサイトを開き、当該サイトのみ Adblock を無効にする。
  3. 全ページで AdBlock を有効にする

AdBlock を有効にした状態で「楽天トラベル」を開いたら、何も表示されなくなった。このとき、上記の方法で「楽天トラベル」で Adblock が無効になるようにした。

 

2. ホワイトリストの編集

手動でホワイトリストを編集するには、Adblock Plus の設定より、「フィルタ設定」を開く。

  1. 「自作フィルタ」タブを開く
  2. デフォルトでは「ホワイトリスト」という名前のフィルタグループが存在するので、「アクション」を押す
  3. 「フィルタを表示/非表示」を選択すると、右側に「フィルタ」のリストが表示される。
  4. 「フィルタを追加」ボタンを押す。

SnapCrab_No-0260

ホワイトリストに追加したい URL の先頭に

@@

を付けてフィールドに入力。

例えば、Google AdSense をホワイトリストに登録したい場合は、

@@https://www.google.com/adsense/

とする。

 

3. 古いバージョンの Adblock

Adblock Plus の古いバージョンでは、設定ウィンドウを開き、「追加」ボタンを押す。

211-12-2010CropperCapture[2]

 

参考サイト

キーボードの入力を改善する方法

Majestouch 黒軸を軽く押して入力する目安」 のつづき

キーボードの置き方を変えてみる

ノートPC の上にキーボードを載せて使ったとき、なぜかキータッチがいつもより軽く感じた。

DSC03010

キーボードの後ろの爪は立てず、ペタンとそのまま置く形。手は少し浮いた状態で、たまごを掴むときのような形。

雑誌を下に敷く

試しに、薄めの雑誌をキーボードの下に敷き使ってみたら、ノートPCの上に置いたときと同じような感覚。 Filco の Majestouch 黒軸はこの打鍵位置が良いみたい。

imgkeyborad

追記(2012/05/05): 打鍵に慣れてくると、背面のツメを立て、使えるようになる。手を動かす範囲が狭く、最小限の力で打てるようになるには、相当の期間が必要。

 

関連記事

2010年11月11日木曜日

Tutorial D でリレーショナル代数

Tutorial D で関係変数の定義と代入」 のつづき

データベース実践講義」 における “5.2 オリジナル演算子” (pp.92-99) の練習。

SQL の相関サブクエリ (2)」 で利用したデータベースと同じものを使う。

5093301582_c738e3bb96

Tutorial D での定義は以下通り。

削除するときはこちらより。

 

制限

特定の条件に一致するタプルを含む関係を返す。例えば、男性を取得するには、

persons where gender = 1

111-11-2010CropperCapture[1]

SQL の WHERE 句に相当し、同じキーワード where を使うので覚えやすい。

 

射影

特定の属性を含む関係を返す。人の名前と年齢を取得するには、

persons { name, age }

211-11-2010CropperCapture[2]

SQL の SELECT 句に相当する。こちらは位置も表現も異なる。

SQL との違いは、以下を評価するとハッキリとする。

persons { gender }

411-11-2010CropperCapture[4]

リレーショナル代数で 「関係」 が返されるわけだから、重複はない。 SQL では SELECT 句で DISTINCT を指定することに相当。

 

結合

「人」 と 「割当て」 を結合する。 SQL の自然結合に相当。

persons rename(id as p_id) join assignments

ただし、結合には同じ属性名が使われるので、結合前に属性名を変更するため rename 演算子を利用する。

ここでは assignments で 「人」 を示すための属性として p_id を利用しているので、上記では persons の属性 id を p_id に変更している。

311-11-2010CropperCapture[3]

次に 「人」 「割当て」 「グループ」 の 3 つを結合し、「人の名前、グループ名、日付」 を表示する。

(persons rename(id as p_id)
  join assignments
  join groups rename(id as g_id, name as g_name))
    {name, g_name, date}

複数の属性名を一気に変更する場合は、rename 演算子において prefix を利用する。

(persons rename(prefix "" as "p_") 
  join assignments
  join groups rename(prefix "" as "g_"))
    {p_name, g_name, date}

結合は、join { A, B, C … } のように書くことができる。

join { persons rename(prefix "" as "p_")
     , assignments
     , groups rename(prefix "" as "g_")}
  {p_name, g_name, date}

 

交わり

「人」 の属性 id と 「割当て」の属性 p_id の交わりを求める。

(persons rename(id as p_id)) {p_id} 
  intersect assignments {p_id}

1011-11-2010CropperCapture[10]

交わりは、属性が全て同じ関係の結合と見なせるので、join を使っても書ける。

(persons rename(id as p_id)) {p_id} 
  join assignments {p_id}

 

デカルト積

「人」の名前 と 「グループ」名 のすべての組み合わせを求めたい。

デカルト積は、共通属性がない関係の結合と見なせるので、結合したい関係の属性名が重ならないように rename 演算子を用いる。このとき、prefix を利用すると便利。

(persons rename(prefix "" as "p_")
  join groups rename(prefix "" as "g_"))
    {p_name, g_name}

1111-11-2010CropperCapture[11]

SQL では FROM 句にテーブル名を並べることに相当。

 

半結合

「グループ」 に 「割当て」 られている 「人」 を抽出したい。

persons semijoin assignments

911-11-2010CropperCapture[9]

データベース実践講義 (p94) によると、

(半結合についてこれまでに聞いたことがないかもしれないが、実がとても重要な演算子である)。定義は次の通り。 r と s の半結合は、 r と s の結合であり、結果は r の属性に射影される。

semijoin の代わりに matching と書くこともできる。こちらの方が言葉としては理解しやすいかな。

SQL では exists 述語を利用して記述できる。

 

「人」 と 「人」 の和。

 (persons where id = 1) union 
  relation {tuple {id 100, name "Gonzou", gender 1, age 100}}

1211-11-2010CropperCapture[12]

 

直和

共通のタプルがあった場合に、エラーが出力される和も用意されている。

(persons where id <= 3)
  d_union (persons where id >= 3)

この場合、「人」 の id が 3 の人が共通してるのでエラーとなる。

 

特定の 「人」 を取り除きたい場合。

persons { name } minus
  relation { tuple { name "Hanko" }
           , tuple { name "Jirou" }
           , tuple { name "Sadayo" }}

 

半差

先ほどの 「半結合」 とは対照的な 「半差」。 SQL では not exists 述語に相当する演算子。

persons rename(id as p_id) 
  semiminus assignments

111-11-2010CropperCapture[1][4]

差は、属性が全て共通している関係の半差と見なせる。

persons { name } semiminus
 relation { tuple { name "Hanko"}
          , tuple { name "Jirou"}
          , tuple {name "Sadayo" }}

 

その他

「商」 はどうやって書いたらいいんだろう。。 (+_+)

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

2010年11月10日水曜日

Tutorial D で関係変数の定義と代入 - Rel を利用して

SQL に対する批判

4873112753 C.J.Date の 「データベース実践講義」 には、SQL に対する批判が随所に書かれている。

例えば、1 章の 「概要」 だけ見ても、初っ端から次のようにある。

リレーショナルモデルに関する知識が SQL の知識にのみ基づくものであるならば、リレーショナルモデルを十分に理解しているとは言えない。 (p1)

既存の実装に対しても手厳しい。

SQL をリレーショナルに使用することはもちろん可能だが(...)、既存の実装は完璧というにはほど遠いため、そのように使用するとパフォーマンスが大幅に低下することがある。その場合には、「完全にリレーショナル」ではない方法に頼らざるを得ないだろう (同上, p4)

一貫して主張されているのが null の否定。

実体整合性のルールには、実は問題がある。それは、筆者が 「null」 の概念を完全に否定しているからである。すなわち、null はリレーショナルモデルに存在する意味がないというのが、筆者のこだわりなのである。(同上, p7)

また、リレーショナルモデルにおける 「関係」 が SQL で正しく扱われていないことも指摘。

  • SQL では行の重複が許されていること。

... 関係に重複するタプルが含まれることはあり得ない。なぜなら、本体はタプルの集合であり、数学における集合に重複する要素が含まれることはないためである。ところで、これは SQL には当てはまらない。知ってのとおり、SQL のテーブルには重複する行が含まれていてもかまわない。このため、一般的には、SQL のテーブルは関係ではない。 (同上, pp.14-15)

これは重複を許すと、RDB はリレーショナル代数に基いているのにも関わらず、「関係」 に対する演算が「関係」でなくなるため、 代数 ではなくなってしまうということかな。

  • 列に順序があること。

... 関係の属性についても、左から右への順序付けがあるわけではない。なぜなら、見出しも数学的な集合だからである。... SQL のテーブルの列は、左から右へ順序付けされている。(このこともまた、SQL のテーブルが一般的に関係でない理由の一つである)。 (同上, p15)

テーブルとビューについては、扱う 「関係」 という点から見れば、本質的には変わらないことが述べられている。

... こうした状況は SQL 規格 (...) からもうかがわれるほどで、一般的には (...) 「テーブルとビュー」という表現が使われている。当然ながら、そうした表現が使われたのでは、誰もがテーブルとビューが別のものであると勘違いし、「テーブル」が物理的なもので「ビュー」が実体のないものであると思い込んでしまうだろう。... ビューは「通常の関係」なので、通常の関係で実行できる処理は(少なくともリレーショナルモデルでは)ビューでも同じように実行できる。(同上, p17)

リレーショナルモデルで扱うのは 「関係」 という値と、それに対する演算であって、実装の問題は別腹と考えるのはシンプルですっきりしている。

 

Tutorial D

… 本書では可能な限り SQL を使って例を示すが、このように何らかの理由でそれが不可能である場合には、 Tutorial D というきわめて直感的な (そして真のリレーショナル) 言語を使用する。 (同上, p19)

ということで、真のリレーショナルと言われる Tutorial D を試してみる。

第3のマニフェスト – Wikipedia によると、

第3のマニフェストは、デイトとダーウェンが考案したデータベース言語 Tutorial D を使って、関係モデルを説明している。 Tutorial D は、データベース言語仕様 D の実装の一つである。 D は、関係データベースデータベース言語が満たすべき要件の集合である。

http://dbappbuilder.sourceforge.net/Rel.php

Rel via kwout

実装として挙げられている中で、お手軽に試せるのが Java で実装された Rel

SourceForge.net より、ダウンロードしてインスール。

スタート > すべてのプログラム > Rel > DBrowser を起動。

sys.Catalog

を入力して Evaluate すると、データベースに定義されている変数の一覧が表示される。

 

Rel に慣れるために

以下ざっと目を通す。

簡単な計算を評価すると、

1 + 2

`3’ と結果が表示される。

 

タプル、関係の評価

タプルを評価すると、

tuple {name "Tarou",  age 10 }

結果は、

111-10-2010CropperCapture[1][4]

「関係」を評価すると、

relation {
  tuple {name "Tarou",  age 10 },
  tuple {name "Hanako", age 20 },
  tuple {name "Jirou",  age 30 }}

結果は、

311-10-2010CropperCapture[3]

Character, Integer と型を指定しなくても、属性の型が表示された。

 

式 と 文

上記の評価では、最後に `;’ を付けないことに注意。

Rel / Tutorial D Grammar を見ると、は、

evaluate ::= ( compound_statement_body ";" )? expression ( <EOT> | <EOF> )

これに対して、は末尾に `;’ を付ける。

statement := statement_body ";"

 

関係変数の定義と代入

変数の定義

SQL で最初にテーブルを作成するときの要領で、「関係」 を値に持つ関係変数 (relvar) を定義してみる。

例えば、以下の表にある 「人」 型の関係変数を定義。

var persons base
  relation { id     integer
           , name   character
           , gender integer
           , age    integer}
    key {id};

変数 persons は relation で指定した型となる。ここでは組み込みの型のみを使って定義した。

末尾に `;’ を付けるのを忘れずに。

 

値を変数に代入

次に、関係変数を定義したので、変数に値である 「関係」 を代入する。

persons :=
  relation{
    tuple { id 1, name "Tarou",   gender 1, age 10 },
    tuple { id 2, name "Hanako",  gender 2, age 20 },
    tuple { id 3, name "Jirou",   gender 1, age 30 },
    tuple { id 4, name "Saburou", gender 1, age 40 },
    tuple { id 5, name "Akemi",   gender 2, age 8  },
    tuple { id 6, name "Sadayo",  gender 2, age 70 },
    tuple { id 7, name "Hiroko",  gender 2, age 15 }};

先ほどの relation が型を返すのに対して、この relation は値を生成する。

関係変数の内容を表示させたい場合は、

persons

と入力して Evaluate する。 `;’ を末尾に付けない。

411-10-2010CropperCapture[4]

 

変数の削除

作成した関係変数を削除したい場合は、

drop var persons;

Tutorial D でリレーショナル代数」へつづく

 

関連記事