ScalarDB Cluster Java API ガイド
このページは英語版のページが機械翻訳されたものです。英語版との間に矛盾または不一致がある場合は、英語版を正としてください。
ScalarDB Cluster Java API は、ScalarDB Core の一部である Administrative API と Transaction API に加えて、ScalarDB Cluster に固有の追加 API で構成されています。このガイドでは、どのような種類の API が存在するのか、それらの使用方法、例外の処理方法などの関連トピックについて説明します。
Administrative API
このセクションでは、ScalarDB の Administrative API を使用してプログラムで管理操作を実行する方法について説明します。
Administrative API の呼び出しが基盤となるデータベースに書き込みを行う場合、複数の書き込み操作がトリガーされます。ただし、これらの操作はアトミックに実行されないため、呼び出しが途中で失敗した場合、一貫性のない状態が発生する可能性があります。この非一貫性の問題を解決するには、名前空間またはテーブルを修復してください。詳細については、以下のページを参照してください:
- Java API を使用した 名前空間の修復とテーブルの修復
- ScalarDB Schema Loader を使用した名前空間とテーブルの修復
管理操作を実行する別の方法は、Schema Loader を使用することです。
DistributedTransactionAdmin インスタンスを取得する
管理操作を実行するには、まず DistributedTransactionAdmin インスタンスを取得する必要があります。
DistributedTransactionAdmin インスタンスを取得するには、次のように TransactionFactory を使用します。
TransactionFactory transactionFactory = TransactionFactory.create("<CONFIGURATION_FILE_PATH>");
DistributedTransactionAdmin admin = transactionFactory.getTransactionAdmin();
設定の詳細については、ScalarDB 設定を参照してください。
すべての管理操作を実行したら、次のように DistributedTransactionAdmin インスタンスを閉じる必要があります。
admin.close();
名前空間を作成する
テーブルは1つの名前空間に属するため、テーブルを作成する前に名前空間を作成する必要があります。
名前空間は次のように作成できます。
// Create the namespace "ns". If the namespace already exists, an exception will be thrown.
admin.createNamespace("ns");
// Create the namespace only if it does not already exist.
boolean ifNotExists = true;
admin.createNamespace("ns", ifNotExists);
// Create the namespace with options.
Map<String, String> options = ...;
admin.createNamespace("ns", options);
作成オプション
名前空間の作成操作では、オプション名と値のマップであるオプション (Map<String, String>) を指定できます。オプションを使用すると、ストレージアダプタ固有の設定ができます。
データベースを選択して、使用可能なオプションを確認します。
- JDBC データベース
- DynamoDB
- Cosmos DB for NoSQL
- Cassandra
- Object Storage
使用可能なオプションはありません。
使用可能なオプションはありません。
| 名前 | 説明 | デフォルト |
|---|---|---|
| ru | 基本リソース単位。 | 400 |
| no-scaling | Cosmos DB for NoSQL の自動スケーリングを無効にします。 | false |
| 名前 | 説明 | デフォルト |
|---|---|---|
| replication-strategy | Cassandra レプリケーション戦略。SimpleStrategy または NetworkTopologyStrategy である必要があります。 | SimpleStrategy |
| replication-factor | Cassandra の複製係数。 | 3 |
使用可能なオプションはありません。
テーブルを作成する
テーブルを作成するときは、テーブルメタデータを定義してからテーブルを作成する必要があります。
テーブルメタデータを定義するには、TableMetadata を使用できます。次の図は、テーブルの列、パーティションキー、クラスタリングキー (クラスタリング順序を含む)、およびセカンダリインデックスを定義する方法を示しています。
// Define the table metadata.
TableMetadata tableMetadata =
TableMetadata.newBuilder()
.addColumn("c1", DataType.INT)
.addColumn("c2", DataType.TEXT)
.addColumn("c3", DataType.BIGINT)
.addColumn("c4", DataType.FLOAT)
.addColumn("c5", DataType.DOUBLE)
.addPartitionKey("c1")
.addClusteringKey("c2", Scan.Ordering.Order.DESC)
.addClusteringKey("c3", Scan.Ordering.Order.ASC)
.addSecondaryIndex("c4")
.build();
ScalarDB のデータモデルの詳細については、データをモデル化するを参照してください。
次に、次のようにテーブルを作成します。
// Create the table "ns.tbl". If the table already exists, an exception will be thrown.
admin.createTable("ns", "tbl", tableMetadata);
// Create the table only if it does not already exist.
boolean ifNotExists = true;
admin.createTable("ns", "tbl", tableMetadata, ifNotExists);
// Create the table with options.
Map<String, String> options = ...;
admin.createTable("ns", "tbl", tableMetadata, options);
作成オプション
テーブルの作成操作では、オプション名と 値のマップであるオプション (Map<String, String>) を指定できます。オプションを使用すると、ストレージアダプタ固有の設定ができます。
データベースを選択して、使用可能なオプションを確認します。
- JDBC データベース
- DynamoDB
- Cosmos DB for NoSQL
- Cassandra
- Object Storage
使用可能なオプションはありません。
| 名前 | 説明 | デフォルト |
|---|---|---|
| no-scaling | DynamoDB の自動スケーリングを無効にします。 | false |
| no-backup | DynamoDB の継続的なバックアップを無効にします。 | false |
| ru | 基本リソース単位。 | 10 |
使用可能なオプションはありません。
| 名前 | 説明 | デフォルト |
|---|---|---|
| compaction-strategy | Cassandra の圧縮戦略。LCS、STCS、または TWCS である必要があります。 | STCS |
使用可能なオプションはありません。
セカンダリインデックスを作成する
セカンダリインデックスは次のように作成できます。
// Create a secondary index on column "c5" for table "ns.tbl". If a secondary index already exists, an exception will be thrown.
admin.createIndex("ns", "tbl", "c5");
// Create the secondary index only if it does not already exist.
boolean ifNotExists = true;
admin.createIndex("ns", "tbl", "c5", ifNotExists);
// Create the secondary index with options.
Map<String, String> options = ...;
admin.createIndex("ns", "tbl", "c5", options);
Consensus Commit を使用している場合、非プライマリキー列で createIndex() を使用すると、コンパニオン before-image セカンダリインデックスも作成されます。詳細については、インデックスベース読み取りの正確性を参照してください。
作成オプション
セカンダリインデックスの作成操作では、オプション名と値のマップであるオプション (Map<String, String>) を指定できます。オプションを使用すると、ストレージアダプタ固有の設定ができます。
データベースを選択して、使用可能なオプションを確認します。
- JDBC データベース
- DynamoDB
- Cosmos DB for NoSQL
- Cassandra
- Object Storage
使用可能なオプションはありません。
| 名前 | 説明 | デフォルト |
|---|---|---|
| no-scaling | DynamoDB の自動スケーリングを無効にします。 | false |
| ru | 基本リソース単位。 | 10 |
使用可能なオプションはありません。
使用可能なオプションはありません。
使用可能なオプションはありません。
テーブルに新しい列を追加する
次のように、テーブルに新しい非パーティションキー列を追加できます。
// Add a new column "c6" with the INT data type to the table "ns.tbl".
admin.addNewColumnToTable("ns", "tbl", "c6", DataType.INT);
// Add the new column only if it does not already exist.
boolean ifNotExists = true;
admin.addNewColumnToTable("ns", "tbl", "c6", DataType.INT, false, ifNotExists);
テーブル に新しい列を追加する場合は、基盤となるストレージによって実行時間が大きく異なる可能性があるため、慎重に検討する必要があります。特にデータベースが本番環境で実行されている場合は、以下の点を考慮して適切に計画を立ててください。
- Cosmos DB for NoSQL および DynamoDB の場合: テーブルスキーマは変更されないため、列の追加はほぼ瞬時に行われます。別のテーブルに格納されているテーブルメタデータのみが更新されます。
- Cassandra の場合: 列を追加すると、スキーマメタデータのみが更新され、既存のスキーマレコードは変更されません。クラスタートポロジが実行時間の主な要因です。スキーマメタデータの変更は、ゴシッププロトコルを介して各クラスターノードに共有されます。このため、クラスターが大きいほど、すべてのノードが更新されるまでの時間が長くなります。
- リレーショナルデータベース (MySQL、Oracle など) の場合: 列の追加は、データベースエンジンによってはテーブルの再構築を引き起こす可能性があります。そのような場合、実行に長時間かかることがあります。
テーブルから列を削除する
次のようにテーブルから列を削除できます。
// Drop the column "c6" from the table "ns.tbl".
admin.dropColumnFromTable("ns", "tbl", "c6");
// Drop the column only if it exists.
boolean ifExists = true;
admin.dropColumnFromTable("ns", "tbl", "c6", ifExists);
次の場合、テーブルから列を削除することはできません。
- 列がパーティションキーまたはクラスタリングキーの一部である場合。
- テーブルが Cassandra を除く 非 JDBC データベース上にある場合。
テーブルから列を削除する場合は、基盤となるストレージによって実行時間が大きく異なる可能性があるため、慎重に検討する必要があります。特にデータベースが本番環境で実行されている場合は、以下の点を考慮して適切に計画を立ててください。
- Cassandra の場合: 列を削除すると、スキーマメタデータのみが更新され、実際のデータは次のコンパクション時に削除されます。クラスタートポロジが実行時間の主な要因です。スキーマメタデータの変更は、ゴシッププロトコルを介して各クラスターノードに共有されます。このため、クラスターが大きいほど、すべてのノードが更新されるまでの時間が長くなります。
- リレーショナルデータベース (MySQL、Oracle など) の場合: 列の削除は、基盤となるリレーショナルデータベースに
ALTER TABLE ... DROP COLUMNを発行し、データベースによってはテーブルの再構築を引き起こす可能性があります。そのような場合、実行に長時間かかることがあります。
テーブルの列の名 前を変更する
次のようにテーブルの列の名前を変更できます。
// Rename the column "c6" to "c66" in the table "ns.tbl".
admin.renameColumnInTable("ns", "tbl", "c6", "c66");
次の場合、テーブルの列の名前を変更することはできません。
- テーブルが Cassandra を除く非 JDBC データベース上にある場合。
- Cassandra の場合、列がパーティションキーまたはクラスタリングキーの一部でない場合。
- Db2 の場合、列がパーティションキー、クラスタリングキー、またはセカンダリインデックスキーの一部である場合。
テーブルの名前を変更する
次のようにテーブルの名前を変更できます。
// Rename the table "ns.tbl" to "ns.new_tbl".
admin.renameTable("ns", "tbl", "new_tbl");
非 JDBC データベースではテーブルの名前を変更することはできません。
テーブルの列のデ ータ型を変更する
次のようにテーブルの列のデータ型を変更できます。
// Alter the data type of the column "c6" to BIGINT in the table "ns.tbl".
admin.alterColumnDataType("ns", "tbl", "c6", DataType.BIGINT);
次の場合、テーブルの列のデータ型を変更することはできません。
- 列がパーティションキー、クラスタリングキー、またはセカンダリインデックスキーの一部である場合。
- テーブルが非 JDBC データベース上または SQLite 上にある場合。
- INT から BIGINT、FLOAT から DOUBLE、および任意のデータから TEXT への変換以外の変換が指定されている場合。
- Oracle の場合、INT から BIGINT 以外の変換が指定されている場合。
- Db2 の場合、BLOB から TEXT への変換が指定されている場合。
列の型を変更する場合は、基盤となるストレージによって実行時間が大きく異なる可能性があるため、慎重に検討する必要があります。特にデータベースが本番環境で実行されている場合は、以下の点を考慮して適切に計画を立ててください。
- リレーショナルデータベース (MySQL、Oracle など) の場合: 列の変更は、基盤となるリレーショナルデータベースに
ALTER TABLE ... ALTER COLUMNまたはALTER TABLE ... MODIFYを発行し、データベースによってはテーブルの再構築を引き起こす可能性があります。そのような場合、実行に長時間かかることがあります。
テーブルを切り捨てる
テーブルを切り捨てるには、次のようにします。
// Truncate the table "ns.tbl".
admin.truncateTable("ns", "tbl");
セカンダリインデックスを削除する
セカンダリインデックスは次のように削除できます。
// Drop the secondary index on column "c5" from table "ns.tbl". If the secondary index does not exist, an exception will be thrown.
admin.dropIndex("ns", "tbl", "c5");
// Drop the secondary index only if it exists.
boolean ifExists = true;
admin.dropIndex("ns", "tbl", "c5", ifExists);
Consensus Commit を使用している場合、dropIndex() はコンパニオン before-image セカンダリインデックスも削除します。詳細については、インデックスベース読み取りの正確性を参照してください。
テーブルを削除する
テーブルを削除するには、次のようにします。
// Drop the table "ns.tbl". If the table does not exist, an exception will be thrown.
admin.dropTable("ns", "tbl");
// Drop the table only if it exists.
boolean ifExists = true;
admin.dropTable("ns", "tbl", ifExists);
名前空間を削除する
名前空間を削除するには、次のようにします。
// Drop the namespace "ns". If the namespace does not exist, an exception will be thrown.
admin.dropNamespace("ns");
// Drop the namespace only if it exists.
boolean ifExists = true;
admin.dropNamespace("ns", ifExists);
既存の名前空間を取得する
既存の名前空間は次のように取得できます。
Set<String> namespaces = admin.getNamespaceNames();
名前空間のテーブルを取得する
名前空間のテーブルは次のように取得できます。
// Get the tables of the namespace "ns".
Set<String> tables = admin.getNamespaceTableNames("ns");
テーブルメタデータを取得する
テーブルメタデータは次のように取得できます。
// Get the table metadata for "ns.tbl".
TableMetadata tableMetadata = admin.getTableMetadata("ns", "tbl");
名前空間を修復する
名前空間が不明な状態の場合 (たとえば、名前空間が基盤となるストレージに存在するが ScalarDB メタデータが存在しない、またはその逆)、このメソッドは必要に応じて名前空間とそのメタデータを再作成します。
名前空間は次のように修復できます。
// Repair the namespace "ns" with options.
Map<String, String> options = ...;
admin.repairNamespace("ns", options);
テーブルを修復する
テーブルが不明な状態の場合 (テーブルは基盤となるストレージに存在するが ScalarDB メタデータは存在しない、またはその逆)、このメソッドは必要に応じてテーブル、そのセカンダリインデックス、およびそのメタデータを再作成します。
テーブルは次のように修復できます。
// Repair the table "ns.tbl" with options.
TableMetadata tableMetadata =
TableMetadata.newBuilder()
...
.build();
Map<String, String> options = ...;
admin.repairTable("ns", "tbl", tableMetadata, options);
Consensus Commit を使用して いる場合、以前のバージョンから ScalarDB 3.16.5、3.17.3、または 3.18.0 にアップグレードした後、インデックスベース読み取りに必要なコンパニオン before-image セカンダリインデックスを作成するために、既存の各テーブルで repairTable() を実行する必要があります。詳細については、インデックスベース読み取りの正確性を参照してください。
最新の ScalarDB API をサポートするように環境をアップグレードする
ScalarDB API の最新バージョンをサポートするように ScalarDB 環境をアップグレードできます。通常、リリースノートに記載されているように、アプリケーション環境が使用する ScalarDB バージョンを更新した後、このメソッドを実行する必要があります。
// Upgrade the ScalarDB environment.
Map<String, String> options = ...;
admin.upgrade(options);
Coordinator テーブルの操作を指定する
Coordinator テーブルは、Transaction API に よってトランザクションのステータスを追跡するために使用されます。
トランザクションマネージャーを使用する場合は、トランザクションを実行するために Coordinator テーブルを作成する必要があります。テーブルの作成に加えて、Coordinator テーブルを切り捨てたり削除したりすることもできます。
Coordinator テーブルを作成する
Coordinator テーブルは次のように作成できます。
// Create the Coordinator table.
admin.createCoordinatorTables();
// Create the Coordinator table only if one does not already exist.
boolean ifNotExist = true;
admin.createCoordinatorTables(ifNotExist);
// Create the Coordinator table with options.
Map<String, String> options = ...;
admin.createCoordinatorTables(options);
Coordinator テーブルを切り捨てる
Coordinator テーブルは次のように切り捨てることができます。
// Truncate the Coordinator table.
admin.truncateCoordinatorTables();
Coordinator テーブルを削除する
Coordinator テーブルは次のように削除できます。
// Drop the Coordinator table.
admin.dropCoordinatorTables();
// Drop the Coordinator table if one exist.
boolean ifExist = true;
admin.dropCoordinatorTables(ifExist);
テーブルをインポートする
既存のテーブルを ScalarDB にインポートするには、次のようにします。
// Import the table "ns.tbl". If the table is already managed by ScalarDB, the target table does not
// exist, or the table does not meet the requirements of the ScalarDB table, an exception will be thrown.
admin.importTable("ns", "tbl", options, overrideColumnsType);
Consensus Commitを使用している場合に、運用環境で ScalarDB にテーブルをインポートする場合は、データベーステーブルと ScalarDB メタデータテーブルにトランザクションメタデータ列が追加されるため、慎重に計画する必要があります。この場合、データベースと ScalarDB の間にはいくつかの違いがあり、いくつかの制限もあります。詳細については、ScalarDB Schema Loader を使用して既存のテーブルを ScalarDB にインポートするを参照してください。
認証と認可 API
ScalarDB Cluster は認証と認可をサポートしています。ユーザー、ロール、権限を Java を通じてプログラムで管理するには、ClusterClientTransactionAdmin を使用します。これは AuthAdmin を実装しています。
ユーザー、ロール、権限などの認証と認可の概念については、ユーザーの認証と認可を参照してください。
ユーザーを管理する
次の操作により、ユーザーの作成、変更、取得ができます。
ユーザーを作成または変更する際、UserOption 列挙型を使用して次のオプションを指定できます:
| オプション | 説明 |
|---|---|
SUPERUSER | ユーザーをスーパーユーザーとして作成または設定します。 |
NO_SUPERUSER | ユーザーを非スーパーユーザーとして作成または設定します。オプションを指定しない場合のデフォルトです。 |
ユーザーを作成する
ユーザーは次のように作成できます。
// Create a regular (non-superuser) user with a password.
admin.createUser("username", "password");
// Create a superuser.
admin.createUser("username", "password", AuthAdmin.UserOption.SUPERUSER);
ユーザーを変更する
既存のユーザーは次のように変更 (修正) できます。
// Change the password of an existing user.
admin.alterUser("username", "newpassword");
// Remove the password of an existing user (pass an empty string to delete the password).
admin.alterUser("username", "");
// Promote an existing user to superuser.
admin.alterUser("username", null, AuthAdmin.UserOption.SUPERUSER);
alterUser にパスワードとして null を渡した場合、パスワードは変更されません。空の文字列を渡した場合、パスワードは削除されます。
ユーザーを削除する
ユーザーは次のように削除できます。
admin.dropUser("username");
ユーザーを取得する
既存のユーザーは次のように取得できます。
Optional<AuthAdmin.User> user = admin.getUser("username");
user.ifPresent(u -> {
System.out.println("Name: " + u.getName());
System.out.println("Superuser: " + u.isSuperuser());
});
すべてのユーザーを取得する
すべてのユーザーは次のように取得できます。
List<AuthAdmin.User> users = admin.getUsers();
for (AuthAdmin.User user : users) {
System.out.println("Name: " + user.getName());
System.out.println("Superuser: " + user.isSuperuser());
}
現在のユーザーを取得する
現在ログインしているユーザーは次のように取得できます。
AuthAdmin.User currentUser = admin.getCurrentUser();
System.out.println("Current user: " + currentUser.getName());
System.out.println("Superuser: " + currentUser.isSuperuser());
ユーザーの権限を管理する
次の操作により、ユーザーへの権限の付与、取り消し、確認ができます。
Privilege 列挙型は、次の値を定義しています:
| 権限 | 説明 |
|---|---|
READ | 読み取り操作 (Get および Scan) |
WRITE | 書き込み操作 (Put、Insert、Upsert、Update) |
DELETE | 削除操作 (Delete) |
CREATE | テーブルおよびインデックスの作成 |
DROP | テーブルおよびインデックスの削除 |
TRUNCATE | テーブルの切り捨て |
ALTER | テーブルの変更 |
GRANT | テーブルに対する権限の付与および取り消し |
これらの権限名は、ScalarDB SQL の DCL で使用される SQL レベルの権限名 (SELECT、INSERT、UPDATE など) とは異なります。Java API を直接使用する場合は、上記の Privilege 列挙型の値を使用してください。
ユーザーに権限を付与する
名前空間内のすべてのテーブル、または特定のテーブルに対して、ユーザーに次のように権限を付与できます。
// Grant READ and WRITE privileges to a user for all tables in a namespace.
admin.grant("username", "namespace", AuthAdmin.Privilege.READ, AuthAdmin.Privilege.WRITE);
// Grant READ and WRITE privileges to a user for a specific table.
admin.grant("username", "namespace", "table", AuthAdmin.Privilege.READ, AuthAdmin.Privilege.WRITE);
ユーザーから権限を取り消す
名前空間内のすべてのテーブル、または特定のテーブルについて、ユーザーから次のように権限を取り消すことができます。
// Revoke READ privilege from a user for all tables in a namespace.
admin.revoke("username", "namespace", AuthAdmin.Privilege.READ);
// Revoke READ privilege from a user for a specific table.
admin.revoke("username", "namespace", "table", AuthAdmin.Privilege.READ);
権限は、付与されたスコープでのみ取り消すことができます。権限が付与されていないスコープで取り消しを行っても、エラーにはならず、単に何も起こりません (別のスコープで付与された権限が削除されることはありません)。
たとえば、名前空間レベルで付与された READ 権限を特定のテーブルに対して取り消しても、効果はありません。ユーザーが権限を持っているかどうかを確認する で説明されているように、テーブルレベルの権限チェックでは名前空間レベルの権限も考慮されるため、テーブルスコープでの取り消しが行われた後も、名前空間全体への付与によってそのテーブルへのアクセスは引き続き許可されます。
ユーザーの権限を取得する
名前空間内のすべてのテーブル、または特定のテーブルについて、ユーザーが持つ権限を次のように取得できます。
// Get privileges for a user for all tables in a namespace.
Set<AuthAdmin.Privilege> nsPrivileges = admin.getPrivileges("username", "namespace");
// Get privileges for a user for a specific table.
Set<AuthAdmin.Privilege> tablePrivileges = admin.getPrivileges("username", "namespace", "table");
getPrivileges() は、直接付与された権限のみを返します。ロールから継承された権限、テーブルに適用される名前空間レベルの権限、スーパーユーザーのアクセス権は含まれません。ユーザーの実効的なアクセス権を確認するには、hasPrivilege() を使用してください。
ユーザーが権限を持っているかどうかを確認する
名前空間または特定のテーブルについて、ユーザーが特定の権限を持っているかどうかを次のように確認できます。
// Check if a user has READ privilege on the namespace.
boolean hasNsPrivilege = admin.hasPrivilege("username", "namespace", AuthAdmin.Privilege.READ);
// Check if a user has READ privilege for a specific table.
boolean hasTablePrivilege = admin.hasPrivilege("username", "namespace", "table", AuthAdmin.Privilege.READ);
特定のテーブルに対する権限を確認する場合、テーブルレベルと名前空間レベルの両方の権限 (ロールを介して推移的に付与された権限を含む) が考慮されます。名前空間に対する権限を確認する場合は、名前空間レベルの権限 (ロールを介して推移的に付与された権限を含む) のみが考慮されます。スーパーユーザーの場合、どの権限チェックでも常に true が返されます。
ロールと権限を管理する
次の操作により、ロールの作成、変更、取得、およびユーザーや他のロールへのロールの付与と取り消しができます。