TOP / データベース / Derby

Derby

はじめに

Apache Derbyが気になったので少し触れてみた時のメモです。Derbyは元々IBMのCloudscapeという製品であったため、そのドキュメントを参考にすれば詳細な使い方は理解できると思います。このメモは、全体像を簡単に掴むためのものです。

2005年8月5日にApache Derby 10.1.1.0がリリースされました。それまではApacheのインキュベーションというカテゴリに入っていましたが、調査段階を終了してプロジェクトの1つとなりました。

このメモでは、インキュベーション時のバージョンである10.0.2.1を利用していますが、10.1.1.0とは極端な変更はないと思われます。

組み込みデータベースの種類

商用利用する場合はライセンスが対応しているか確認するためいくつか組み込みデータベースを調べてみました。いくつかの組み込みデータベースのライセンスや歴史などを調べてみた結果です。

Derby

Javaで書かれた組み込みデータベース。IBMのCloudscapeをApache Software Foundationに2004年8月に寄与。Cloudscapeは1996年に作られた。

2005年5月22日時点ではあまり日本語情報が存在しない。

ライセンスは、Apache License, Version 2.0

HSQLDB

Javaで書かれた組み込みデータベース。OpenOffice.org2.0, JBoss, Hibernateなどに組み込まれている。実績は申し分ない。ライセンスは、独自ライセンス。

Berkeley DB

Sleepycat Softwareの非常に有名なBerkeleyDB。Javaでの実装もある。実績は申し分ない。

ライセンスは複雑なようだ。オープンソースである場合問題なく利用できるが、ソースコードを公開しないアプリケーションなどは、Sleepycat Software社のライセンスを購入しなければならない。

MySQL

MySQLは日本でも非常に使われているのでインターネット上の日本語情報が豊富。組み込み版MySQLがある。ライセンスは、複雑なようだが日本の代理店で確認できる。

SQLite

PHP5に付属している組み込みデータベース。無償で商用利用できるライセンスでもある。

調べた組み込みデータベースの一覧表

商用利用の場合、DerbyとSQLLite以外はソースコードの公開やライセンス購入など何らかの対応をしなければならないという事が理解できた。

データベース名 実装 ライセンス
Derby Java Apache Licence 2.0
HSQLDB Java 独自。
BerkeleyDB Java, C/C++ 独自。商用で実装する場合、ライセンスが必要。
MySQL C/C++ 独自。商用で実装する場合、ライセンスが必要。
SQLite C/C++ パブリック・ドメイン。

Apache Derbyのインストール

Derbyのダウンロードサイトから10.0.2.1をダウンロードして展開します。

ダウンロードサイトには名前の異なるファイルがいくつかあります。incubating-derby-10.0.2.1-XXX.bin.zipとなっています。XXXの部分がbinのものはドキュメントや開発用javadocが入っています。libのものはjarファイルのみでつまりライブラリです。srcはソースコードが入っています。開発時はbinなどを利用して本番の環境ではlibのものを利用すればよいでしょう。

初心者用のインストールマニュアルは、Get Started with Derbyとしてダウンロードサイトにあります。JDBC実装経験者用のチュートリアルもありますがまだ整備されていないようです。

Derbyをインストールすると、ツールが3つだけで非常に分かりやすいのが理解できます。

  • ij -- SQLを実行するためのツール
  • dblook -- スキーマ抽出するツール
  • sysinfo -- バージョンやクラスパスなど情報を確認するツール

環境変数の設定

バッチファイルによる設定

毎回、環境変数の設定やWindowsのコントロールパネルに設定をするのが面倒なので環境設定用バッチファイルを用意しました。これを利用する事でコマンドラインから容易にデータベースに触れる事が出来ます。


@rem derby setup batch file.
@rem create: 2005/05/22
@rem author: satoshiokita
@rem
@rem set env
@rem
set MY_CURRENT_DIR=E:\rfid_dev\eclipse\workspace\trunk
set JAVA_HOME=E:\j2sdk1.4.2_08
set PATH=%JAVA_HOME%\bin;%PATH%
set DERBY_INSTALL=E:\rfid_dev\eclipse\workspace\trunk\lib\incubating-derby-10.0.2.1-lib
set CLASSPATH=%DERBY_INSTALL%\lib\derby.jar;%DERBY_INSTALL%\lib\derbytools.jar;
%CLASSPATH%cd %MY_CURRENT_DIR%
echo "java org.apache.derby.tools.sysinfo"
echo "java org.apache.derby.tools.ij"
start
pause

sysinfoコマンドでの動作確認

sysinfoコマンドでDerbyやJavaの設定が確認できます。


E:\>java org.apache.derby.tools.sysinfo
------------------ Java Information ------------------
Java Version: 1.4.2_08
Java Vendor: Sun Microsystems Inc.
Java home: E:\j2sdk1.4.2_08\jre
Java classpath: E:\incubating-derby-10.0.2.1-bin\lib\derby.jar;
E:\incubating-derby-10.0.2.1-bin\lib\derbytools.jar;
E:\incubating-derby-10.0.2.1-bin\lib\derby.jar;
OS name: Windows 2000
OS architecture: x86
OS version: 5.0
Java user name: a1
Java user home: E:\Documents and Settings\a1
Java user dir: E:\
--------- Derby Information --------
[E:\incubating-derby-10.0.2.1-bin\lib\derby.jar] 10.0.2.1 - (106978)
[E:\incubating-derby-10.0.2.1-bin\lib\derbytools.jar] 10.0.2.1 - (106978)
[E:\incubating-derby-10.0.2.1-bin\lib\derby.jar] 10.0.2.1 - (106978)
------------------------------------------------------
----------------- Locale Information -----------------
------------------------------------------------------

コマンドラインからの実行

ijコマンドによりDerbyのコマンドプロンプトを起動します。セミコロンとリターンキーでコマンドを実行します。またhelp;と入力する事でDerbyで利用できるコマンド一覧くぉ表示する事が可能です。

java org.apache.derby.tools.ij

データベースインスタンスの作成

connectコマンドを実行時にcreate属性の値をtrueとする事でデータベースインスタンスを作成する事が出来ます。


E:\rfid_dev\eclipse\workspace\trunk>java org.apache.derby.tools.ij
ij version 10.0
ij> connect 'jdbc:derby:test_db;create=true';

再接続

disconnectコマンドでデータベースの接続を終了します。


ij> disconnect current;
ij> connect 'jdbc:derby:test_db';
ij>

テーブル作成

ceate table文を実行してテーブルの作成を行い、insertとselectを実行してみます。最後にdisconnectでデータベース接続を終了して、quitコマンドでコマンドプロンプトを終わりにします。


E:\rfid_dev\eclipse\workspace\trunk>java org.apache.derby.tools.ij
ij version 10.0

ij> create table test_tbl ( test_id integer, test_name varchar(12));
0 rows inserted/updated/deleted
ij> commit;

ij> insert into test_tbl values (1, 'aaa');
1 row inserted/updated/deleted
ij> insert into test_tbl values (2, 'bbb');
1 row inserted/updated/deleted
ij> commit;
ij> select * from test_tbl;

TEST_ID |TEST_NAME
------------------------
1 |aa
2 |bbb
2 rows selected

ij> disconnect;
ij> quit;

sqlスクリプトの実行

ijコマンドプロンプトでrunコマンドを利用すると外部のsqlファイルを読み込んで実行できます。


ij> run 'apache_derby_rfid_ddl.sql';
ij> -- $Id$
-- $Date$ $Rev$
-- Author: satoshiokita
-- 2005 Copyright satoshiokita All Rights Reserved.
--
--
--
drop table rfid_user;
0 rows inserted/updated/deleted

ij> create table rfid_user (
rfid char(10) not null,
username varchar(128),
attendance_start_date date,
attendance_end_date date,
lock char(1),
reg_date date not null,
upd_date date not null);
0 rows inserted/updated/deleted

ij> alter table rfid_user add constraint pk_rfid_user primary key (rfid);
0 rows inserted/updated/deleted

ij> drop table user_history;
0 rows inserted/updated/deleted

ij> create table user_history (
rfid char(10) not null,
reg_date date not null,
upd_date date not null
);
0 rows inserted/updated/deleted

ij> alter table user_history add constraint pk_user_history primary key (rfid);
0 rows inserted/updated/deleted

またMS-DOSコマンドプロンプトからもijコマンドを実行する時にSQLファイルを引数に指定するとSQLを読み込むことが可能です

E:\rfid_dev\eclipse\workspace\trunk>java org.apache.derby.tools.ij test.sql 

登録、変更、更新、削除

データベースの基本処理を行ってみたいと思います。また以下のサンプルは、エラーメッセージがどのように出力されるか確認できるようにわざとエラーのSQLを実行しています。


E:\rfid_dev\eclipse\workspace\trunk>java org.apache.derby.tools.ij
ij version 10.0
ij> insert into hoge_user values (1,'hoge',currentdate,currentdate,'1',currentdate,currentdate);
IJ ERROR: Unable to establish connection

ij> connect 'jdbc:derby:testdb';
ij> insert into hoge_user values
 (1, 'hoge', currentdate, currentdate, '1', currentdate, currentdate);

ERROR 42X04: Column 'CURRENTDATE' is not in any table in the FROM list or it appears 
within a join specification and is outside the scope of the join specification 
or it appears in a HAVING clause and is not in the GROUP BY list. 
If this is a CREATE or ALTER TABLE statement then 
'CURRENTDATE' is not a column in the target table.

ij> insert into hoge_user values
 (1, 'hoge', current_date, current_date, '1', current_date, current_date);

ERROR 42821: Columns of type 'CHAR' cannot hold values of type 'INTEGER'.

ij> insert into hoge_user values 
 ('1a','hoge',current_date,current_date,'1',current_date,current_date);
1 row inserted/updated/deleted
ij> commit;

ij> update hoge_user set upd_date = current_date;
1 row inserted/updated/deleted
ij> commit;

ij> delete hoge_user where hoge_id = '1a';
ERROR 42X01: Syntax error: Encountered "hoge_user" at line 1, column 8.
ij> delete from hoge_user where hoge_id = '1a';
1 row inserted/updated/deleted
ij> commit;

ij> insert into hoge_user values
 ('1a', 'hoge', current_date, current_date, '1', current_date, current_date);
1 row inserted/updated/deleted
ij> commit;

ij> select * from hoge_user;
HOGE_ID |USERNAME |START_DATE|END_DATE |LOCK|REG_DATE |UPD_DATE
---------------------------------------------------------------------
1a |hoge|2005-06-03|2005-06-03|1 |2005-06-03|2005-06-031 row selected

ij>

Javaからの実行

testdbに接続


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SampleDerbyConnection {

	/**
	 * 
	 */
	public SampleDerbyConnection() {
		super();
		// TODO 自動生成されたコンストラクター・スタブ
	}

	public static void main(String[] args) {
		
		// 組み込み環境では同じJVM上でDerbyが動作する
		try {
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

			/* データベースが存在しない時は作成 */
			Connection conn = DriverManager.getConnection(
				"jdbc:derby:testdb");
			
			/* システム情報 */
			System.out.println(conn.getMetaData().getURL());
		} catch (SQLException e1) {
			// TODO 自動生成された catch ブロック
			e1.printStackTrace();

		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}
} 

testdbに接続2

DriverManager#getConnectionメソッドの引数にcreate=true属性を記述することでデータベース・インスタンスが存在しない場合作成してくれる。


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SampleDerbyConnection {

	/**
	 * 
	 */
	public SampleDerbyConnection() {
		super();
		// TODO 自動生成されたコンストラクター・スタブ
	}

	public static void main(String[] args) {
		
		// 組み込み環境では同じJVM上でDerbyが動作する
		try {
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

			/* データベースが存在しない時は作成 */
			Connection conn = DriverManager.getConnection(
				"jdbc:derby:testdb;create=true");
			
			/* システム情報 */
			System.out.println(conn.getMetaData().getURL());
		} catch (SQLException e1) {
			// TODO 自動生成された catch ブロック
			e1.printStackTrace();

		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}
} 

テーブルの削除と作成


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SampleDerbyConnection {

	/**
	 * 
	 */
	public SampleDerbyConnection() {
		super();
		// TODO 自動生成されたコンストラクター・スタブ
	}

	public static void main(String[] args) {
		
		// 組み込み環境では同じJVM上でDerbyが動作する
		try {
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

			/* データベースが存在しない時は作成 */
			Connection conn = DriverManager.getConnection(
				"jdbc:derby:testdb;create=true");
			
			/* システム情報 */
			System.out.println(conn.getMetaData().getURL());
			
			Statement stmt = conn.createStatement();
			
			/* テーブルが存在する時は削除 */
			String sqlDrop = "drop table user_tbl";
			try {
				stmt.executeUpdate(sqlDrop);
			} catch (SQLException e) {
				System.out.println("drop error. maybe no exist.");
			}

			/* テーブル作成 */
			String sqlCreate = "create table user_tbl (" +
			"zid char(10) not null," +
			"stamped_time date" + 
			")";
			stmt.executeUpdate(sqlCreate);
			System.out.println("create table");
			
			stmt.close();
			conn.close();
		} catch (SQLException e1) {
			// TODO 自動生成された catch ブロック
			e1.printStackTrace();

		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}
}

登録、変更、更新、削除


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SampleDerbyConnection {

	/**
	 * 
	 */
	public SampleDerbyConnection() {
		super();
		// TODO 自動生成されたコンストラクター・スタブ
	}

	public static void main(String[] args) {
		
		// 組み込み環境では同じJVM上でDerbyが動作する
		try {
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

			/* データベースが存在しない時は作成 */
			Connection conn = DriverManager.getConnection(
				"jdbc:derby:testdb;create=true");
			
			/* システム情報 */
			System.out.println(conn.getMetaData().getURL());
			
			Statement stmt = conn.createStatement();
			
			/* テーブルが存在する時は削除 */
			String sqlDrop = "drop table user_tbl";
			try {
				stmt.executeUpdate(sqlDrop);
			} catch (SQLException e) {
				System.out.println("drop error. maybe no exist.");
			}

			/* テーブル作成 */
			String sqlCreate = "create table user_tbl (" +
			"zid char(10) not null," +
			"stamped_time date" + 
			")";
			stmt.executeUpdate(sqlCreate);
			System.out.println("create table");
			
			/* insert */
			for ( int i = 0; i < 10; i++) {
String sqlInsert = "insert into user_tbl values('1" + i + "1',current_date)";
			  stmt.executeUpdate(sqlInsert);
			}
			
			/* select */
			String sqlSelect = "select zid, stamped_time from user_tbl";
			ResultSet rs = stmt.executeQuery(sqlSelect);
			while (rs.next()) {
				System.out.print(rs.getString(1));
				System.out.println(rs.getDate(2));
			}
			/* delete */
	        int deleteFlag = 
              stmt.executeUpdate("delete from user_tbl where zid > '150'");
			System.out.println(deleteFlag);
			
			/* update */
			int updateFlag = stmt.executeUpdate("update user_tbl set zid = '555'");
			System.out.println(updateFlag);

			/* select */
			rs = stmt.executeQuery(sqlSelect);
			while (rs.next()) {
				System.out.print(rs.getString(1));
				System.out.println(rs.getDate(2));
			}			
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e1) {
			// TODO 自動生成された catch ブロック
			e1.printStackTrace();

		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}
} 

システムディレクトリの変更

Derbyはデフォルトでは、カレント・ディレクトリにデータファイルを作る。場合によってはデータを別のディスクや分散をしたいと思う。そういう場合は、Javaのシステム・プロパティにderby.system.homeを設定する。以下のカレント・ディレクトリはE:\rfid_dev\....であるが、-Dオプションでderby.system.homeを設定しているのでe:\derby_system_testディレクトリにデータができる。


"> E:\rfid_dev\eclipse\workspace\trunk>java -Dderby.system.home=E:\derby_system_tes
t org.apache.derby.tools.ij
ij version 10.0
ij>
;
ij> connect 'jdbc:derby:hogefugaDB;create=true';
ij> disconnect;
ij> exit;

Javaプログラムの場合は、connectをする前にシステム・プロパティを設定すればよい。以下は、java.util.Propertiesで設定している。


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author satoshiokita
 *
 * この生成されたコメントの挿入されるテンプレートを変更するため
 * ウィンドウ > 設定 > Java > コード生成 > コードとコメント
 */
public class SampleDerbyConnection2 {

	/**
	 * 
	 */
	public SampleDerbyConnection2() {
		super();
		// TODO 自動生成されたコンストラクター・スタブ
	}

	public static void main(String[] args) {
		
		// 起動時にderby.system.homeを設定
		Properties props = System.getProperties();
		props.put("derby.system.home", "E:\\derby_system_test");
		
		// 組み込み環境では同じJVM上でDerbyが動作する
		try {
			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

			/* データベースが存在しない時は作成 */
			Connection conn = DriverManager.getConnection(
				"jdbc:derby:testdb2;create=true");
			
			/* システム情報 */
			System.out.println(conn.getMetaData().getURL());
			
			Statement stmt = conn.createStatement();
			
			/* テーブルが存在する時は削除 */
			String sqlDrop = "drop table user_tbl";
			try {
				stmt.executeUpdate(sqlDrop);
			} catch (SQLException e) {
				System.out.println("drop error. maybe no exist.");
			}

			/* テーブル作成 */
			String sqlCreate = "create table user_tbl (" +
			"zid char(10) not null," +
			"stamped_time date" + 
			")";
			stmt.executeUpdate(sqlCreate);
			System.out.println("create table");
			
			/* insert */
			for ( int i = 0; i < 10; i++) {
	  String sqlInsert = "insert into user_tbl values('1" + i + "1',current_date)";
			  stmt.executeUpdate(sqlInsert);
			}
			
			/* select */
			String sqlSelect = "select zid, stamped_time from user_tbl";
			ResultSet rs = stmt.executeQuery(sqlSelect);
			while (rs.next()) {
				System.out.print(rs.getString(1));
				System.out.println(rs.getDate(2));
			}
			/* delete */
	int deleteFlag = stmt.executeUpdate("delete from user_tbl where zid > '150'");
			System.out.println(deleteFlag);
			
			/* update */
			int updateFlag = stmt.executeUpdate("update user_tbl set zid = '555'");
			System.out.println(updateFlag);

			/* select */
			rs = stmt.executeQuery(sqlSelect);
			while (rs.next()) {
				System.out.print(rs.getString(1));
				System.out.println(rs.getDate(2));
			}			
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e1) {
			// TODO 自動生成された catch ブロック
			e1.printStackTrace();

		} catch (ClassNotFoundException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}
}

Derbyの設定ファイル

derby.propertiesというファイルを自分で作ることで、設定ができる。例えばログ出力ファイル名や、ユーザ認証を行うようにするなど。これはデフォルトでは存在しないし、Derbyデータベースが上書きとかすることもないので、自分で作る。場所は、カレント・ディレクトリで、もしderby.system.homeを設定していたらそのディレクトリに配置する。

カレントディレクトリにderby.propertiesファイルをおいた。ファイルには、derby.infolog.append=trueとしてログファイル出力をオンにした。


E:\derby_system_test>dir
 ドライブ E のボリューム ラベルがありません。
 ボリューム シリアル番号は 6830-FF68 です

 E:\derby_system_test のディレクトリ

2005/06/09  20:47       <DIR>          .
2005/06/09  20:47       <DIR>          ..
2005/06/09  20:39                  386 derby.log
2005/06/09  20:47                   25 derby.properties
2005/06/07  00:40       <DIR>          hogefugaDB
2005/06/09  20:39       <DIR>          testdb2
               2 個のファイル                 411 バイト
               4 個のディレクトリ  116,763,213,824 バイトの空き領域

E:\derby_system_test>more derby.properties
derby.infolog.append=true

Derbyを動かしてみる。ログが計れるはず。


E:\derby_system_test>java org.apache.derby.tools.ij
ij version 10.0
ij> connect 'jdbc:derby:testdb2';
ij> disconnect;
ij> exit;

derby.logというファイルで、ログを出力した。


----------------------------------------------------------------
2005-06-09 11:53:06.359 GMT:
Booting Derby version The Apache Software Foundation - Apache Derby - 10.0.2.1 
- (106978): instance c013800d-0104-60f2-41e9-000000162ad8
on database directory E:\derby_system_test\testdb2
Database Class Loader started - derby.database.classpath=''
2005-06-09 11:53:21.750 GMT:
Shutting down instance c013800d-0104-60f2-41e9-000000162ad8
----------------------------------------------------------------

とりあえず以下のプロパティがある。(Bold文字はログ関連)、認証、承認、ロック、ストレージのキャッシュなどがある。使ってみないと分からん。

  • derby.authentication.ldap.searchAuthDN
  • derby.authentication.ldap.searchAuthPW
  • derby.authentication.ldap.searchBase
  • derby.authentication.ldap.searchFilter
  • derby.authentication.provider
  • derby.authentication.server
  • derby.connection.requireAuthentication
  • derby.database.defaultConnectionMode
  • derby.database.forceDatabaseLock
  • derby.database.fullAccessUsers
  • derby.database.propertiesOnly
  • derby.database.readOnlyAccessUsers
  • derby.infolog.append
  • derby.language.logStatementText
  • derby.locks.deadlockTimeout
  • derby.locks.deadlockTrace
  • derby.locks.escalationThreshold
  • derby.locks.monitor
  • derby.locks.waitTimeout
  • derby.storage.initialPages
  • derby.storage.minimumRecordSize
  • derby.storage.pageCacheSize
  • derby.storage.pageReservedSpace
  • derby.storage.pageSize
  • derby.storage.tempDirectory
  • derby.stream.error.file
  • derby.stream.error.logSeverityLevel
  • derby.system.home
  • derby.user.UserName

Derbyの型

SQL規約のSQL型とさほど差分はない。

  • BIGINT
  • CHAR FOR BIT DATA
  • VARCHAR FOR BIT DATA
  • BLOB
  • CHAR
  • CLOB
  • DATE
  • DECIMAL
  • DOUBLE PRECISION
  • FLOAT
  • INTEGER
  • LONG VARCHAR FOR BIT DATA
  • LONG VARCHAR
  • NUMERIC
  • REAL
  • SMALLINT
  • TIME
  • TIMESTAMP

型変換

文字列をDATE型に変換。文字列をTIMESTAMP型に変換


ij> values cast('2005-07-12' as DATE);
1
----------
2005-07-12

1 row selected
ij> values cast('2005' as VARCHAR(4));
1
----
2005

1 row selected
ij> values cast('2005-07-21' as timestamp);
ERROR 22007: The syntax of the string representation of a datetime value is inco
rrect.
ij> values cast('2005-07-12 12:12:12' as TIMESTAMP);
1
--------------------------
2005-07-12 12:12:12.0

1 row selected

組み込み関数一覧

Derbyは非常に関数が少ない。OracleなどSelect文の時に、ある程度データの変換や計算を行って取得できるが、Derbyの場合は、使用するプログラミング言語側でデータ変換や文字列のフィルターなどを作りこんでいかなければならない。

  • ABS or ABSVAL
  • AVG
  • BIGINT
  • CAST
  • CHAR
  • LENGTH
  • Concatenation
  • NULLIF and CASE expressions
  • COUNT
  • COUNT(*)
  • CURRENT DATE
  • CURRENT_DATE
  • CURRENT ISOLATION
  • CURRENT SCHEMA
  • CURRENT TIME
  • CURRENT_TIME
  • CURRENT TIMESTAMP
  • CURRENT_TIMESTAMP
  • CURRENT_USER
  • DATE
  • DAY
  • DOUBLE
  • HOUR
  • IDENTITY_VAL_LOCAL
  • INTEGER
  • LOCATE
  • LCASE or LOWER
  • LTRIM
  • MAX
  • MIN
  • MINUTE
  • MOD
  • MONTH
  • RTRIM
  • SECOND
  • SESSION_USER
  • SMALLINT
  • SQRT
  • SUBSTR
  • SUM
  • TIME
  • TIMESTAMP
  • UCASE or UPPER
  • USER
  • VARCHAR
  • YEAR

組み込みファンクション

デフォルトでは、APPスキーマが割り当てられ、システム情報はSYSスキーマにある。

SYSCS_UTIL.SYSCS_CHECK_TABLE('スキーマ','テーブル')

[テーブルに矛盾が無いかチェックできる。正常はSMALLINT型の1を返し、エラー時は例外


ij> create table mytable (mycol int);
0 rows inserted/updated/deleted
ij> create index aaaa on mytable(mycol);
0 rows inserted/updated/deleted
ij> insert into mytable values (1), (2), (3);
3 rows inserted/updated/deleted
ij> commit;
ij> values syscs_util.syscs_check_table('APP','MYTABLE');
1
-----------
1

1 row selected


ij> values syscs_util.syscs_check_table('APP','MYTABLaa');
1
-----------
ERROR 42X05: Table 'APP.MYTABLaa' does not exist.

SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS

実行計画(execute plan)とstatisticsの取得


ij> VALUES SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS();
1
----------------------------------------------------
NULL

1 row selected

SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY

現在の接続情報を取得するファンクション。Derbyのプロパティファイルを読み込めるのか確認したが出来なかった。


ij> VALUES SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY('derby.system.home');
1
-------------------------------------------------------------------------------
NULL

1 row selected
ij> VALUES SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY('derby.locks.monitor');
1
-------------------------------------------------------------------------------
NULL

1 row selected
ij> VALUES SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY('derby.infolog.appned');
1
-------------------------------------------------------------------------------
NULL

1 row selected

組み込みプロシージャ

ijプロンプト上のCALLコマンドで呼ぶ。Javaプログラムからも呼べる。

  • SYSCS_UTIL.SYSCS_COMPRESS_TABLE
  • SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS
  • SYSCS_UTIL.SYSCS_SET_STATISTICS_TIMING
  • SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY
  • SYSCS_UTIL.SYSCS_FREEZE_DATABASE
  • SYSCS_UTIL.SYSCS_UNFREEZE_DATABASE
  • SYSCS_UTIL.SYSCS_CHECKPOINT_DATABASE
  • SYSCS_UTIL.SYSCS_BACKUP_DATABASE
  • SYSCS_UTIL.SYSCS_EXPORT_TABLE
  • SYSCS_UTIL.SYSCS_EXPORT_QUERY
  • SYSCS_UTIL.SYSCS_IMPORT_TABLE
  • SYSCS_UTIL.SYSCS_IMPORT_DATA

SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1) 実行計画の取得を有効にする, 引数を0にすると無効

ij> CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1);
0 rows inserted/updated/deleted
ij> select * from mytable;
MYCOL
-----------
1
2
3

3 rows selected
ij> VALUES SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS();
1
----------------------------------------------------
Statement Name:
        null
Statement Text:
        select * from mytable
Parse Time: 0
Bind Time: 0
Optimize Time: 0
Generate Time: 0

ij> CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(0);
0 rows inserted/updated/deleted
ij> select * from mytable;
MYCOL
-----------
1
2
3

3 rows selected

 

SYSCS_UTIL.SYSCS_SET_STATISTICS_TIMING(1); statisticsの取得を有効にする, 引数を0にすると無効

こんな感じに使う。

ij> CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1);
0 rows inserted/updated/deleted
ij> CALL SYSCS_UTIL.SYSCS_SET_STATISTICS_TIMING(1);
0 rows inserted/updated/deleted
ij> select * from mytable;
MYCOL
-----------
1
2
3

3 rows selected
ij> VALUES SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS();
1
----------------------------------------------------
Statement Name:
        null
Statement Text:
        select * from mytable
Parse Time: 0
Bind Time: 0
Optimize Time: 0
Generate Time: 0

 

SYSCS_UTIL.SYSCS_FREEZE_DATABASE(),SYSCS_UTIL.SYSCS_UNFREEZE_DATABASE()

データベース・バックアップ時にFREEZE,UNFREEZEする。FREEZEをうまく日本語訳に出来ないが、バックアップ用に一時停止して再始動する感じだと思う。このプロシージャを実行した後も接続は保たれているので、停止、再起動ではないようだ。

ij> connect 'jdbc:derby:testdb';
ij> select * from mytable;
MYCOL
-----------
1
2
3

3 rows selected
ij> call SYSCS_UTIL.SYSCS_FREEZE_DATABASE();
0 rows inserted/updated/deleted
ij> call SYSCS_UTIL.SYSCS_UNFREEZE_DATABASE();
0 rows inserted/updated/deleted
ij> select * from mytable;
MYCOL
-----------
1
2
3

3 rows selected
ij>

 

メモリ上のキャッシュされたデータをディスクに吐き出す。 CALL SYSCS_UTIL.SYSCS_CHECKPOINT_DATABASE()

ij> CALL SYSCS_UTIL.SYSCS_CHECKPOINT_DATABASE();
0 rows inserted/updated/deleted

SYSCS_UTIL.SYSCS_BACKUP_DATABASE

ディレクトリ名を入れてバックアップをとる。圧縮やダンプファイルではなく、単純にデータベースのファイル群を対象のディレクトリにコピーするだけのようだ。

ij> CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE('c:/');
0 rows inserted/updated/deleted

ほかには後4つある。

  • SYSCS_UTIL.SYSCS_EXPORT_TABLE
  • SYSCS_UTIL.SYSCS_EXPORT_QUERY
  • SYSCS_UTIL.SYSCS_IMPORT_TABLE
  • SYSCS_UTIL.SYSCS_IMPORT_DATA

Derby System Tables ディクショナリ

select * from テーブル名を実行する事でいろいろな情報が取得できます。ある程度推測は出来ますが、実際にコマンドを実行して確認してみるとよいでしょう。

また、システムテーブルは、SYSスキーマにあり、基本的なテーブルしかないので分かりやすいです。

  • SYSALIASES
  • SYSCHECKS
  • SYSCOLUMNS
  • SYSCONGLOMERATES  テーブルや索引のストレージ
  • SYSCONSTRAINTS
  • SYSDEPENDS
  • SYSFILES
  • SYSFOREIGNKEYS
  • SYSKEYS
  • SYSSCHEMAS
  • SYSSTATISTICS
  • SYSSTATEMENTS
  • SYSTABLES
  • SYSTRIGGERS
  • SYSVIEWS

 

SYSALIASES

プロシージャとファンクションの確認

JAVACLASSNAMEというカラムがある事から、プロシージャがJava言語で実装されているのが分かる。

ij> select * from SYS.SYSALIASES;
ALIASID                             |ALIAS|SCHEMAID
  |JAVACLASSNAME |&|&|SYST&|ALIASINFO      |SPECIFICNAME 
--------------------------------------------------------------------------------------
601a400f-0104-600f-33b7-000075b19812|SQLCAMESSAGE |c013800d-00f8-5b53-28a9-00000019ed
88|org.apache.derby.catalog.SystemProcedures |P|P|false|SQLCAMESSAGE(I&|SQL050609044535970

f81e0010-0104-600f-33b7-000075b19812|SQLPROCEDURES|c013800d-00f8-5b53-28a9-00000019ed
88|org.apache.derby.catalog.SystemProcedures |P|P|false|SQLPROCEDURES(&|SQL050609044535990

80220011-0104-600f-33b7-000075b19812|SQLTABLEPRIVILEGES |c013800d-00f8-5b53-28a9-00000019ed
88|org.apache.derby.catalog.SystemProcedures |P|P|false|SQLTABLEPRIVIL&|SQL050609044535991

SYSCHECKS

CONSTANTS(定数?)の確認

そもそもデータベースの定数が調べていないので分からない。要調査。

ij> select * from SYS.SYSCHECKS;
CONSTRAINTID                        |CHECKDEFINITION |REFERENCEDCOLU&
---------------------------------------------------------
0 rows selected

SYS.SYSCOLUMNS

すべてのテーブルのカラム確認

SYSCONSTRAINTS,SYSFOREIGNKEYS,SYSTABLES,SYSTRIGGERS,SYSVIEWSなども似たようなイメージ

ij> select * from SYS.SYSCOLUMNS;
REFERENCEID                         |COLUMNNAME|COLUMNNUMB&|COLUMNDATATYPE |COLUMN
DEFAULT  |COLUMNDEFAULTID |AUTOINCREMENTVALUE  |AUTOINCREMENTSTART  |AUTOINCREMENTINC
--------------------------------------------------------
80000010-00d0-fd77-3ed8-000a0a0b1900|SCHEMAID|1|CHAR(36) NOT N&|NULL |NULL|NULL|NULL|NULL
80000010-00d0-fd77-3ed8-000a0a0b1900|TABLEID |2|CHAR(36) NOT N&|NULL |NULL|NULL|NULL|NULL
80000010-00d0-fd77-3ed8-000a0a0b1900|CONGLOMERATENUMBER|3|BIGINT NOT NULL|NULL|NULL|NULL|NULL|NULL
80000010-00d0-fd77-3ed8-000a0a0b1900|CONGLOMERATENAME  |4|VARCHAR(128)   |NULL|NULL|NULL|NULL|NULL

SYSFILES

ファイル。だが読めなかった。

select * from SYS.SYSFILES;
FILEID    |SCHEMAID   |FILENAME            |GENERATIONID
--------------------------------------------------------

0 rows selected

 

SYSSCHEMAS

スキーマ一覧

ij> select * from SYS.SYSSCHEMAS;
SCHEMAID                            |SCHEMANAME|AUTHORIZATIONID 
--------------------------------------------------------
c013800d-00f8-5b53-28a9-00000019ed88|SYSIBM    |DBA
8000000d-00d0-fd77-3ed8-000a0a0b1900|SYS       |DBA
c013800d-00fb-2641-07ec-000000134f30|SYSCAT    |DBA
c013800d-00fb-2642-07ec-000000134f30|SYSFUN    |DBA
c013800d-00fb-2643-07ec-000000134f30|SYSPROC   |DBA
c013800d-00fb-2644-07ec-000000134f30|SYSSTAT   |DBA
c013800d-00fb-2647-07ec-000000134f30|NULLID    |DBA
c013800d-00fb-2648-07ec-000000134f30|SQLJ      |DBA
c013800d-00fb-2646-07ec-000000134f30|SYSCS_DIAG|DBA
c013800d-00fb-2649-07ec-000000134f30|SYSCS_UTIL|DBA
80000000-00d2-b38f-4cda-000a0a412c00|APP       |APP

パフォーマンステスト

Javaでプログラミングされたデータベースを使った事がなかったので、簡単なコードを書いて乱数のテストを行っていました。無償のツールを探したら、JDBCBenchというのを見つけたのでパフォーマンスのテストを行うのに便利かもしれません。

最後に

Derbyを少し触れてみた感想は、ツールの機能が絞られているのであまり迷う必要がない。関数が現時点では少ないため、プログラミング言語側でロジックを書かなければならない。という部分です。いままでデータベースはC言語で実装されているものばかり使っていたのですがJVMで動かせることを考えると良いかもしれません。

更新履歴

  • 2006年4月16日 - 加筆修正。
  • 2006年4月12日 - XHTML対応と加筆修正。
  • 2005年8月8日 - Apache Derby Java接続入門を記述。


イバラキングへのリンク Get Firefox Valid XHTML 1.1 Apple Darwinへのリンク