はじめに
VoltDBの開発者向けの公式ドキュメントUsing VoltDBのまとめです。対象のバージョンはv8.3です。
正確に翻訳することや網羅することは目的ではないため、重要でない記述等は削除したり、不足部分は追記しています。
今回は7章です。
現時点でまとめたのは以下の章です。
・3. データベースの起動
・7. アプリケーション開発の簡略化
・9. クラスタでVoltDBを使用する
・13. VoltDBデータベースの保存と復元
なお、本投稿のまとめ元である「Using VoltDB」のライセンスはAGPLであり、これらのまとめ投稿はAGPLが適用されます。
7. アプリケーション開発の簡略化
・VoltDBには開発を容易にする以下の3つの機能がある。
- デフォルトプロシージャの利用
- 単純なストアドプロシージャを定義するためのショートカット
- 期待されるクエリ結果の確認
7.1. デフォルトプロシージャの利用
・キーに基づいてレコードをinsert、select、update、deleteする単純な操作を簡単に実行するために、VoltDBには各テーブルにデフォルトストアドプロシージャを自動で定義する。
・デフォルトのストアドプロシージャでは、「テーブル名.ステートメント」の名前がで定義される。たとえば、HELLOWORLDというテーブルでは、以下のデフォルトストアドプロシージャを自動で定義される。
・全てのテーブルでinsertを実行するデフォルトストアドプロシージャが作成される。
- HELLOWORLD.insert: パラメータはテーブルの列と同じ順序。
・テーブルに主キーがある場合は、update、upsert、deleteをデ実行するデフォルトストアドプロシージャが作成される。
- HELLOWORLD.update: パラメータはテーブルの列と同じ順序。その後に主キー値が続く。つまり、主キー値は2回指定される。
- HELLOWORLD.upsert: パラメータはテーブルの列と同じ順序。
- HELLOWORLD.delete: パラメータは主キー値。複合主キーの場合は定義の順序となる。
・テーブルに主キーがありパーティション化されている場合、selectを実行するデフォルトストアドプロシージャが作成される。
HELLOWORLD.select : パラメータは主キー値。複合主キーの場合は定義の順序となる。
sqlcmdコマンドのshow proceduresを使用して、使用可能なすべてのストアドプロシージャをリストし、必要なパラメータの数と種類を指定します。
[補足] show proceduresの実行例
# sqlcmd
1> show procedures
~省略~
--- User Procedures ------------------------------------------
KEISOKU_DATA.delete varchar, timestamp
KEISOKU_DATA.insert varchar, timestamp, smallint, smallint, smallint, smallint, smallint, timestamp, varchar
KEISOKU_DATA.select varchar, timestamp
・コード例
VoltTable[] results;
client.callProcedure("HELLOWORLD.insert",
"American","Howdy","Earth");
results = client.callProcedure("HELLOWORLD.select",
"American").getResults();
client.callProcedure("HELLOWORLD.update",
"American","Yo","Biosphere",
"American");
client.callProcedure("HELLOWORLD.delete",
"American");
7.2. 単純なストアドプロシージャを定義するためのショートカット
・1つのSQLクエリを実行して呼び出し元のアプリケーションに結果を返すだけでよい単純なケースでは、ストアドプロシージャのJavaコードを書くのは面倒な作業なので、VoltDBではショートカットを提供している。
・ショートカットでは、ストアドプロシージャをデータベーススキーマの一部として定義できる。
・通常、ストアドプロシージャはJavaのクラスから以下のように定義する。
CREATE PROCEDURE FROM CLASS MakeReservation;
CREATE PROCEDURE FROM CLASS CancelReservation;
・ショートカットでは、以下のようにAS句にSQLクエリを記述して定義できる。
CREATE PROCEDURE CountReservations AS
SELECT COUNT(*) FROM RESERVATION;
・単純なストアドプロシージャでは、以下のようにSQLクエリへ引数を渡すこともできる。
CREATE PROCEDURE MyReservationsByTrip AS
SELECT R.RESERVEID, F.FLIGHTID, F.DEPARTTIME
FROM RESERVATION AS R, FLIGHT AS F
WHERE R.CUSTOMERID = ?
AND R.FLIGHTID = F.FLIGHTID
AND F.ORIGIN=? AND F.DESTINATION=?;
・単純なプロシージャーをシングルパーティションにするかどうかを指定することもできる。
・デフォルトでは、ストアド・プロシージャはマルチパーティションと見なされる。
・シングルパーティションにする場合は、PARTITION ON句でそのパーティションを指定する。
CREATE PROCEDURE FetchReservations
PARTITION ON
TABLE Reservation COLUMN flightid
AS
SELECT * FROM RESERVATION WHERE FLIGHTID=?;
・単純なプロシージャ内で複数のSQL文を実行する場合は、SQLをBEGIN-END句に囲む。
CREATE PROCEDURE OpenOrders
AS BEGIN
SELECT fullname FROM CUSTOMER WHERE CUSTOMERID=?;
SELECT * FROM ORDER WHERE CUSTOMERID=?;
END;
・各ステートメントはセミコロン(;)で終了する。
・プロシージャは、プロシージャ内の各文に対するVoltTableの配列を返す。
・引数は再利用されないので、上の例ではCUSTOMERIDの値を2回引数に与えて実行する。
7.3. 期待されるクエリ結果の確認
・クエリによって返される結果の正確性を検証するためにコーディングが必要となる場合がある。例えば、正しい数のレコードを取得したか?クエリは正しい値を返したか?
・VoltDBはクエリの結果を手動で検証するコードを記述するのではなく、クエリ自体に検証を実行する方法を提供する。
・クエリが検証で期待値とならない場合、ストアドプロシージャは自動的にVoltAbortExceptionをスローしてロールバックされる。
・期待値を指定する場合、voltQueueSQLメソッドの2番目のパラメータに指定する。
・次のコードは、EXPECT_ONE_ROWの期待値を使用して1レコードだけが返ってくることを検証している。
import org.voltdb.Expectation;
.
.
.
public final SQLStmt GetSeats = new SQLStmt(
"SELECT numberofseats FROM Flight WHERE flightid=?;");
voltQueueSQL(GetSeats, EXPECT_ONE_ROW, flightid); -- EXPECT_ONE_ROWで検証
VoltTable[] recordset = voltExecuteSQL();
Long numofseats = recordset[0].asScalarLong();
・このように期待値を使用することにより、結果に1行しか存在しないことを検証するためのエラー・チェックを行う必要がなくなる。
・次の表は、ストアドプロシージャで使用できるすべての期待値を示す。
期待 | 説明 |
---|---|
EXPECT_EMPTY | クエリはレコードを返されない。 |
EXPECT_ONE_ROW | クエリは1レコードのみを返す必要があります。 |
EXPECT_ZERO_OR_ ONE_ROW | クエリは、0個以上のレコードを返す必要があります。 |
EXPECT_NON_EMPTY | クエリは少なくとも1レコードを返す必要があります。 |
EXPECT_SCALAR | クエリは単一の値(1列のみ)を返す必要があります。 |
EXPECT_SCALAR_LONG | クエリは、Long型のデータ型を持つ単一の値を返す必要があります。 |
EXPECT_SCALAR_MATCH(long) | クエリは、指定されたLong値に等しい単一の値を返す必要があります。 |