データベースはcreate database文で作成できます。 このSQL文はDoqueDBの拡張です。
create database DB1;
pathの指定によりデータベースを構成するファイルの場所を明示することもできます。
create database DB1 path '/DOQUEDB/data/DB1' logicallog '/DOQUEDB/log/DB1' system '/DOQUEDB/system/DB1';
pathの直後はデータファイル、logicallogの直後は論理ログファイル、systemの直後はスキーマファイルの格納場所です。 一部の指定を省略することもできます。この場合、省略された部分はデフォルト値が使用されます。
create database DB1 path logicallog '/DOQUEDB/log/DB1';
ディスク破損のリスクを考えると、データファイルと論理ログファイルは異なるパーティションに置いたほうが安全です。 データファイルを置いてあるパーティションが破損しても、バックアップファイルと論理ログファイルがあればロールフォワードリカバリーにより最新の状態に戻すことができます。
データベース名には、一部を除いた任意の文字が使用できます。 使用できない文字は、OSでパス名を構成する文字(スラッシュ、バックスラッシュ、コロンなど)とセミコロンです。 大文字小文字の違いは無視されます。 データベース名に構文要素などのキーワードを使用したり空白や引用符を含めるときは、データベース名全体を2重引用符で囲みます。 2重引用符を含めたいときは2重引用符を2つ書きます。
create database "This is a database"; create database "Use ' and "" in a name";
表はcreate table文で作成できます。
create table <表名> ( <列定義>, ... <表制約>, ... );
表名に対する制限はデータベース名に対するものとほぼ同様です。 50文字を超えるとエラーになります。
表制約には以下のものが使用できます。
primary key unique
その他の表制約(foreign keyなど)は未サポートです。
表を定義すると、列定義に書いたものの前にROWIDという名前の列が定義されます。 ROWIDには表に挿入するごとに0から1ずつ増える値が割り当てられます。 通常の列と同じように条件などに指定できますが、以下の制限があります。
列定義は以下のように書きます。
<列名> <型> [ <DEFAULT指定> または <IDENTITY指定> ] <列制約> <HINT>
列名の制限は表名と同様です。
型には以下のものが指定可能です。
char(N) N文字固定長文字列(ASCIIのみ) varchar(N) 最大N文字の可変長文字列(ASCIIのみ) varchar(no limit) 無制限可変長文字列(ASCIIのみ) nchar(N) N文字固定長文字列 nvarchar(N) 最大N文字の可変長文字列 nvarchar(no limit) 無制限可変長文字列 int 32bit符号付整数 bigint 64bit符号付整数 float 倍精度浮動小数点 datetime 日時 binary(N) Nバイト固定長バイナリー binary(no limit) 無制限可変長バイナリー blob バイナリーLOB nclob 文字列LOB DoqueDB拡張 language 言語 ntext = nvarchar(no limit) fulltext = nvarchar(no limit) image = binary(no limit) uniqueidentifier = char(36)
配列型を定義することもできます。 以下のように型の後ろにARRAYを指定します。
create table TBL ( f int ARRAY[10], 最大要素数10のint配列型 g nvarchar(100) ARRAY[no limit] 要素数無制限のnvarchar(100)配列型 );
配列型にはB+木索引をつけることはできません。
DEFAULT指定にはリテラルまたはCURRENT_TIMESTAMPを書くことができます。
create table TBL1 ( f int DEFAULT 10, g datetime DEFAULT CURRENT_TIMESTAMP );
INSERT文で値を指定しない場合、DEFAULT指定に記述された値が使用されます。 CURRENT_TIMESTAMPの場合はその文を実行している時点の日時が使用されます。 DEFAULT指定を省略するとDEFAULT NULLと解釈されます。
DEFAULT指定でIDENTITY COLUMNを定義することもできます。 以下のように定義します。
create table TBL2 ( id int GENERATED BY DEFAULT AS IDENTITY, f int );
INSERT文で値を指定しない場合、0から順番に1ずつ増える値が割り当てられます。 IDENTITY COLUMNはひとつの表に対して2つ以上定義できません。 以下のようにすると10から始めることができます。
create table TBL3 ( id int GENERATED BY DEFAULT AS IDENTITY (START WITH 10), f int );
IDENTITYには以下のようなオプションが指定できます。 複数のオプションを指定するときは空白で区切ります。 同じ種類のオプションを重複して指定するとエラーになります。
START WITH N 割り当てる値をNから始めます。無指定時は0です。 INCREMENT BY N 割り当てる値を前回の値+Nにします。無指定時は1です。 MAXVALUE N 割り当てる値の最大値をNにします。無指定時は2147483647です。 NO MAXVALUE MAXVALUEの無指定時と同じです。 MINVALUE N 割り当てる値の最小値をNにします。INCREMENT BYに負数が与えられたときなど。 無指定時は0です。 NO MINVALUE MINVALUEの無指定時と同じです。 CYCLE 最大値(INCREMENTが負のときは最小値)に到達したときに、次の割り当て値を 最小値(INCREMENTが負のときは最大値)にします。無指定時はNO CYCLEです。 NO CYCLE 最大値または最小値に到達したとき、次に割り当てが要求されたらエラーにします。 DoqueDB拡張 GET MAX 値を明示してINSERTやUPDATEをしたとき、それに続く値を次に割り当てます。 無指定時は値を明示しても次の割り当て値に影響しません。
値を明示することを禁止することもできます。以下のようにALWAYSを使って定義します。
create table TBL4 ( id int GENERATED ALWAYS AS IDENTITY, f int );
列制約には以下のものが指定可能です。
NOT NULL
primary keyやuniqueは表制約として指定してください。
HINTは列値の解釈や格納方法に関するオプションを指定するときに使います。 以下のものが指定可能です。複数指定するときは空白で区切ってください。
HEAP その列値だけを格納するレコードファイルを別途作成します。 NONTRUNCATE 可変長文字列に入れる文字列の末尾に空白があっても削除しません。 'compressed' 文字列やバイナリーを圧縮して格納します。 'fixed' 文字列やバイナリーは固定長の型でも可変長用のファイルに格納されます。 上限値が小さい文字列やバイナリーにこのヒントを設定すると、 固定長用のファイルに格納され、速度が改善することがあります。
列の型にblobやnclobを指定すると、その列値はLobファイルという特殊な機能を持ったファイルに格納され、Locatorという特殊なアクセス手段を用いた処理ができます。 Locatorには以下のような機能があります。
append 末尾にデータを追加します。 replace データの一部を別のデータに置き換えます。 get データの一部を取得します。 length データの長さを取得します。
Locatorを用いることで、大きなデータの全体を読み込まずに更新や一部取得の処理ができます。 ただし、Locatorのインターフェースそのものは利用者に公開されません。 Locatorの機能は以下のようなSQL文を通じて使用できます。
select SUBSTRING(lobdata FROM 10 FOR 20) from TBL; getにより10文字目から20文字だけ取得します。 select CHAR_LENGTH(lobdata) from TBL; lengthにより長さを取得します。 update TBL set lobdata = lobdata || 'xxx'; appendにより'xxx'を追加します。 update TBL set lobdata = overlay (lobdata PLACING 'xxx' FROM 10); replaceにより10文字目から3文字を'xxx'に置き換えます。
1つまたは複数の列に対して特定の条件判定を高速に行うための索引を作成することができます。 索引はcreate index文で作成します。 このSQL文はDoqueDBの拡張です。
create <索引タイプ> <索引名> on <表名>(<キー列名>, ...) <hint>;
表名で指定された表に属する列のうち、キー列名のリストで指定された1つ以上の列をキーとした索引を作成します。
索引タイプには以下が指定できます。
索引タイプなし B+木索引 bitmap ビットマップ索引 fulltext 全文索引 unique hint unique(後述)を指定したものと同じ array 配列索引 all rows NULL値も格納するB+木索引
それぞれ以下のような特徴があります。
各索引が処理できる条件は以下の通りです。
B+木索引 =, <, >, <=, >=, in, between, like 'xxx%' (前方一致) ビットマップ索引 =, <, >, <=, >=, in 配列型に対しては、左辺が任意要素指定(x[] = 10)である必要があります。 全文索引 like, contains 配列索引 B+木索引と同様ですが、左辺が任意要素指定(x[] = 10)である必要があります。
索引名には表名と同様の長さ制限があります。 また、同じデータベースに属する異なる表に同じ名前の索引をつけることはできません。
索引タイプごとに、キーにする列に対して制約があります。
char(N), varchar(N), nchar(N), nvarchar(N), int, bigint, float, datetime, languageビットマップ索引は以下の型の列をキーにできます。
char(N), varchar(N), nchar(N), nvarchar(N), int, bigint, float, datetime, language 上記の配列型全文索引は以下の型の列をキーにできます。
char(N), varchar(N), varchar(no limit), nchar(N), nvarchar(N), nvarchar(no limit) 上記の配列型
char(N), varchar(N) ((n+1)/4+1)*4 nchar(N), nvarchar(N) (n/2+1)*4 int 4 bigint 8 float 8 datetime 8 language 16
hintは索引の動作を制御するために指定します。
B+木索引には以下のヒントをつけることができます。
複数指定するときは空白で区切ります。
unique 同じ値を持ったキー(複数の場合は同じ値の組み合わせ)がないことを保証する。 'normalized' 文字列に対して簡単なあいまい検索を可能にする(大文字小文字、全角半角の同一視)。
全文索引には以下のヒントをつけることができます。 全体を引用符で囲み、複数指定するときはカンマで区切ります。 なお、ここではすべてが説明されているわけではありません。 全文索引のさらに詳しい作成方法は「全文索引をつかいこなす」を参照してください。
delayed 遅延更新によりデータの更新操作を高速化します。 sectionized 配列型に定義したときに、条件がどの配列要素に合致したのかを取得できるようにします。 inverted=(...) 全文索引を構成する転置ファイルの動作を制御します。
表を構成する列値は、原則としてRecordファイルに格納されます。 (BLOBとNCLOBは別のLobファイルに格納されます。) Recordファイルは固定長用のファイルと可変長用のファイルから構成されます。 固定長のファイルには、固定長型(ROWID, int, bigint, float, datetime)の列値と可変長ファイルに格納される可変長オブジェクトへのポインターが格納されます。 hint heapつきの列やLOBがあるときは、そのオブジェクトへのポインターも格納されます。 また、hint 'fixed'が指定されている列も固定長のファイルに格納されます。 可変長のファイルには、可変長型(char, varchar, nchar, nvarchar, binary)の列値をひとまとまりにした可変長オブジェクトが格納されます。 以下の例を見てください。
create table TBL ( id int, title nvarchar(100), contents nvarchar(no limit) );
このとき、固定長ファイルには以下のデータが格納されます。
ROWID (4byte) id (4byte) 可変長へのポインター (6byte)
また、可変長ファイルには以下のデータが格納されます。
title (最大200byte) contents (無制限)
ここで、簡単な検索アプリを考えてみます。 idが指定した範囲にあるデータの一覧を得ることにします。 一覧なのでidとtitleがあればいいでしょう。
select id, title from TBL where id between ? and ?;
この処理をするためにはidとtitleの値があればいいのですが、 可変長オブジェクトにtitleとcontentsがまとめられているため、 不必要なcontentsのデータまで読み込むことになります。 このような場合、contentsをヒープにします。
create table TBL ( id int, title nvarchar(100), contents nvarchar(no limit) hint heap );
こうすると、固定長ファイルには以下のデータが格納されます。
ROWID (4byte) id (4byte) contentsへのポインター (6byte) 可変長へのポインター (6byte)
可変長ファイルには以下のデータが格納されます。
title (最大200byte)
contentsの値は別のRecordファイルに格納されます。
ここで先ほどのSQL文を考えてみます。
select id, title from TBL where id between ? and ?;
こんどはtitleだけが取得されるので、無駄な読み込みがなくなり速度が改善されます。
ただし、titleとcontentsを同時に取得することが多い場合には逆効果になることもあります。
さらに、titleを固定長ファイルに格納してしまうことも可能です。
create table TBL ( id int, title nvarchar(100) hint 'fixed', contents nvarchar(no limit) hint heap );
hint 'fixed'のほうは引用符で囲まれていることに注意してください。 こうすると、固定長ファイルには以下のデータが格納されます。
ROWID (4byte) id (4byte) title (200byte) contentsへのポインター (6byte)
このとき可変長ファイルは作られません。
titleに対応する部分は最大長の100文字分=200byteが領域として確保されます。
こんどは固定長ファイルしか読まれないので、その分処理は簡単になります。
ただし、固定長のデータサイズが著しく増加しています(20⇒214)。
このことによりバッファリングの効果が薄れるので、一度に大量のレコードを読み込む場合は逆効果になるおそれがあります。
しかし、一般に固定長データと同時に取得されることが分かっている比較的短い可変長データには、hint 'fixed'をつけたほうがいいと予想されます。
索引を効果的につけると、特定のSELECT文が高速に実行できます。 しかし、更新操作は索引ファイルにも操作を行うので、むやみに索引をつけると更新操作が遅くなります。 また、選択性の悪い列にB+木索引をつけるなど、データのばらつき度合いと索引タイプが合っていないと、更新操作が遅くなるだけでなく、検索操作も逆に遅くなる場合があります。 想定される検索操作とデータのばらつき度合いに応じて、効果的な索引定義を心がけるようにしてください。
select * from TBL where f < 10; -- fの値にばらつきが大きい場合、以下のような索引をつけると速くなる。 create index IDX on TBL(f);
select * from TBL where f < 10 and g = 500; -- fの値にばらつきが大きく、gの値は同じものが多い場合、以下のような索引をつけるとよい。 create index IDX on TBL(f, g);この複合索引はfだけをキーにした索引としても使用できるので、fだけの索引を重複して定義する必要はありません。
select * from TBL where f = 'male' and title like '%senior%'; -- fの値にばらつきがほとんどない場合、以下のような索引をつけると速くなる。 create bitmap index IDX on TBL(f);ビットマップ索引は、データのばらつきが大きくなると更新操作が著しく遅くなることがあるため、データの異なり数の上限が予測できない列には使用を避けてください。
具体的には以下のような場合が該当します。
create table TBL (f int NOT NULL, g int, h int); create index IDX1 on TBL(f); -- NOT NULL制約のついた列 f 単独の索引 create index IDX2 on TBL(g); -- g 単独の索引 create index IDX3 on TBL(h, g); -- h と g の複合索引 … select * from TBL order by f; -- IDX1を用いてfの昇順にレコードを取得する。 select * from TBL where g > 10 order by g; -- g>10の条件によりNULLが無視できるので、 -- IDX2を用いてgの昇順にレコードを取得する。 select * from TBL where h = 100 order by g; -- IDX3を用いてh=100を満たすレコードをgの昇順に取得する。create all rows indexを用いると、NULL値を持つ列についてもソートキーとして索引が使用されます。
Copyright (c) 2023 Ricoh Company, Ltd. All rights reserved.