コレーションとは、基本的に、比較すべき2つのキャラクタを制御する方法で、2つの与えられたキャラクタを比較した結果が、等しいか、小さいか、あるいは大きいかを調べるものである。
なせこれに悩むのか?
コレーションに悩まされるには、2つの理由がある:
1) 国際的なキャラクタ問題
2) 大文字・小文字を区別して比較操作するという問題 国際的なキャラクタ問題
FrontBase は、Unicodeをサポートしており、これにより、漢字やハングルといった、いわゆる国際的なキャラクタを扱うことができる。Unicodeにおけるこれら国際的なキャラクタのコード値は、2つのキャラクタ順序付けに使うことはできず、少なくとも、順序付けをきれいに行ったとしても、ほとんどの人にとってはあまり意味をなさない。
例:フランス語のキャラクタç;(ラテン文字の小文字のcの下に、セリダをつけたもの)は、もともとの値としては231(10進数)であり、小文字のcは99で順序はまったく関係がない。もし、çと d を比較した場合、ユーザの好みにかかわらず、 d の方が、çよりも小さな文字となる。
大文字・小文字を区別して比較操作するという問題
通常、キャラクタ・ストリングは、大文字・小文字についてはユーザが入力したとおりに、データベースにストアされる。ユーザの中には、小文字のみで入力することを好む人間もいるし、大文字のみで入力したがるユーザもいる。FrontBaseといった具合に、語句の先頭文字だけ大文字にするユーザもいるだろう。普通、検索の際、ユーザは、大文字・小文字がどのように入力されていたかを知ることはない。よって、検索のときには、このことに気を配らねばならない:
この大文字・小文字の問題については、次のようにして処理することができる:
SELECT * FROM T0 WHERE UPPER(CITY) = 'COPENHAGEN';
上記の SELECTは、T0.CITYで定義されたインデックスが使用できないとき、インデックス使用可能時に比べて、SELECTステートメントの実行が遅くなるという点にある。
いわゆるCOLLATION(コレーション)を定義することで、キャラクタの並び順を効果的に決定することができる。つまり、順序付けされた値を、順序にしたがって、マッピングするのである。たとえば、'a'を、'A'と同じ値にマップするのだ。そうすれば、'a'は、'A'と同じものと考えることができる。
FrontBaseの配布パッケージには、CaseInsensitive.coll1と呼ばれるコレーション・テーブルが含まれている(<FB home>/Coll tionsディレクトリに置いてある)。このファイル名を適用すれば、このコレーションを、大文字・小文字を区別した比較に使うことができる。
まず、コレーションを定義しなければならない:
CREATE COLLATION CASE_INSENSITIVE
FOR INFORMATION_SCHEMA.SQL_TEXT
FROM EXTERNAL('CaseInsensitive.coll1');
COMMIT;
コレーションは、テーブル作成時に使われる:
CREATE TABLE T0(
...
DB VARCHAR(128) COLLATE CASE_INSENSITIVE,
...
);
CREATE INDEX ON T0(DB);
COMMIT;
DB列の値が他のストリングと比較されたとき、指定されたコレーションが自動的に用いられる。これは、インデックスを構築するときの比較も対象として含む。
例:
INSERT INTO T0(DB) VALUES 'frontbase', 'FrontBase', 'FRONTBASE';
COMMIT;
SELECT DB FROM T0 WHERE DB = 'FrOnTbAsE';
-- Will return all 3 rows
SELECT DB FROM T0 WHERE DB LIKE 'f%';
-- Will return all 3 rows
なんらかの理由によって、大文字・小文字を区別して比較したい場合には、独自のコレーションを定義しなければならない(FBUnicodeManagerアプリケーションを使えばよい)。そして、できあがったコレーションを、たとえば、CaseSensitive.coll1といった名前で、<FB home>/Collationsディレクトリに保存してやる。
CREATE COLLATION CASE_SENSITIVE
FOR INFORMATION_SCHEMA.SQL_TEXT
FROM EXTERNAL('CaseSensitive.coll1');
COMMIT;
SELECT DB FROM T0 WHERE DB = 'FrontBase' COLLATE CASE_SENSITIVE;
-- Will return 1 row
SELECT DB FROM T0 WHERE DB LIKE 'F%' COLLATE CASE_SENSITIVE;
-- Will return 2 rows
上記の2つのSELECTステートメントは、列DB上に作成されたインデックスを使っているのではないことに注意すること。大きなテーブルに対し、2つのSELECTステートメントを実行すると、インデックスが利用可能な場合に比べて、かなり遅くなる。
もし、大文字・小文字を区別して検索したい場合や、検索結果について、大文字・小文字の条件に完全一致したものだけを示したい場合は、どうすればいいだろうか?簡単な方法は、次のようなものである::
SELECT DB FROM T0 WHERE
DB = 'FrontBase'
AND
DB = 'FrontBase' COLLATE CASE_SENSITIVE;
最初のWHEREコンポーネントで、'frontbase'、'FrontBase'、 'FRONTBASE'を返し、2回目のWHEREコンポーネントで、結果を 'FrontBase'のみに絞り込むのだ: |