ScalarDB Java API Guide
The ScalarDB Java API is mainly composed of the Administrative API and Transactional API. This guide briefly explains what kinds of APIs exist, how to use them, and related topics like how to handle exceptions.
Administrative API​
This section explains how to execute administrative operations programmatically by using the Administrative API in ScalarDB.
When an Administrative API call writes to the underlying databases, it triggers several write operations. However, these operations are not executed atomically, meaning that if the call fails midway, you may encounter inconsistent states. To resolve this inconsistency issue, you can repair the table. For details, see the following pages:
- Repair a table by using the Java API
- Repair tables by using ScalarDB Schema Loader
Another method for executing administrative operations is to use Schema Loader.
Get a DistributedTransactionAdmin instance​
You first need to get a DistributedTransactionAdmin instance to execute administrative operations.
To get a DistributedTransactionAdmin instance, you can use TransactionFactory as follows:
TransactionFactory transactionFactory = TransactionFactory.create("<CONFIGURATION_FILE_PATH>");
DistributedTransactionAdmin admin = transactionFactory.getTransactionAdmin();
For details about configurations, see ScalarDB Configurations.
After you have executed all administrative operations, you should close the DistributedTransactionAdmin instance as follows:
admin.close();
Create a namespace​
Before creating tables, namespaces must be created since a table belongs to one namespace.
You can create a namespace as follows:
// 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);
Creation options​
In the namespace creation operations, you can specify options that are maps of option names and values (Map<String, String>). By using the options, you can set storage adapter–specific configurations.
Select your database to see the options available:
- JDBC databases
- DynamoDB
- Cosmos DB for NoSQL
- Cassandra
- Object Storage
No options are available.
No options are available.
| Name | Description | Default |
|---|---|---|
| ru | Base resource unit. | 400 |
| no-scaling | Disable auto-scaling for Cosmos DB for NoSQL. | false |
| Name | Description | Default |
|---|---|---|
| replication-strategy | Cassandra replication strategy. Must be SimpleStrategy or NetworkTopologyStrategy. | SimpleStrategy |
| replication-factor | Cassandra replication factor. | 1 |
No options are available.
Create a table​
When creating a table, you should define the table metadata and then create the table.
To define the table metadata, you can use TableMetadata. The following shows how to define the columns, partition key, clustering key including clustering orders, and secondary indexes of a table:
// 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();
For details about the data model of ScalarDB, see Data Model.
Then, create a table as follows:
// 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);
Creation options​
In the table creation operations, you can specify options that are maps of option names and values (Map<String, String>). By using the options, you can set storage adapter–specific configurations.
Select your database to see the options available:
- JDBC databases
- DynamoDB
- Cosmos DB for NoSQL
- Cassandra
- Object Storage
| Name | Description | Default |
|---|---|---|
| transaction-metadata-decoupling | Enable transaction metadata decoupling when using Consensus Commit, which manages the transaction metadata in a separate table from application data. | false |
| Name | Description | Default |
|---|---|---|
| no-scaling | Disable auto-scaling for DynamoDB. | false |
| no-backup | Disable continuous backup for DynamoDB. | false |
| ru | Base resource unit. | 10 |
No options are available.
| Name | Description | Default |
|---|---|---|
| compaction-strategy | Cassandra compaction strategy, Must be LCS, STCS, or TWCS. | STCS |
No options are available.
Create a secondary index​
You can create a secondary index as follows:
// 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);
When using Consensus Commit, createIndex() on a non-primary-key column also creates a companion before-image secondary index. For details, see Correctness of index-based reads.
Creation options​
In the secondary index creation operations, you can specify options that are maps of option names and values (Map<String, String>). By using the options, you can set storage adapter–specific configurations.
Select your database to see the options available:
- JDBC databases
- DynamoDB
- Cosmos DB for NoSQL
- Cassandra
- Object Storage
No options are available for JDBC databases.
| Name | Description | Default |
|---|---|---|
| no-scaling | Disable auto-scaling for DynamoDB. | false |
| ru | Base resource unit. | 10 |
No options are available.
No options are available.
No options are available.
Add a new column to a table​
You can add a new, non-partition key column to a table as follows:
// 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);
You should carefully consider adding a new column to a table because the execution time may vary greatly depending on the underlying storage. Please plan accordingly and consider the following, especially if the database runs in production:
- For Cosmos DB for NoSQL and DynamoDB: Adding a column is almost instantaneous as the table schema is not modified. Only the table metadata stored in a separate table is updated.
- For Cassandra: Adding a column will only update the schema metadata and will not modify the existing schema records. The cluster topology is the main factor for the execution time. Changes to the schema metadata are shared to each cluster node via a gossip protocol. Because of this, the larger the cluster, the longer it will take for all nodes to be updated.
- For relational databases (MySQL, Oracle, etc.): Adding a column can cause a table rebuild depending on the database engine. In such cases, it can take a long time to execute.
Drop a column from a table​
You can drop a column from a table as follows:
// 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);
You cannot drop a column from a table in the following cases:
- The column is part of the partition key or clustering key.
- The table is on a non-JDBC database except for Cassandra.
You should carefully consider dropping a column from a table because the execution time may vary greatly depending on the underlying storage. Please plan accordingly and consider the following, especially if the database runs in production:
- For Cassandra: Dropping a column will only update the schema metadata and the actual data will be removed during the next compaction. The cluster topology is the main factor for the execution time. Changes to the schema metadata are shared to each cluster node via a gossip protocol. Because of this, the larger the cluster, the longer it will take for all nodes to be updated.
- For relational databases (MySQL, Oracle, etc.): Dropping a column issues
ALTER TABLE ... DROP COLUMNto the underlying relational databases and could trigger a table rebuild depending on the database. In such cases, it can take a long time to execute.
Rename a column of a table​
You can rename a column of a table as follows:
// Rename the column "c6" to "c66" in the table "ns.tbl".
admin.renameColumnInTable("ns", "tbl", "c6", "c66");
You cannot rename a column of a table in the following cases:
- The table is on a non-JDBC database except for Cassandra.
- For Cassandra, the column is not part of the partition key or clustering key.
- For Db2, the column is part of the partition key, clustering key, or secondary index key.
Rename a table​
You can rename a table as follows:
// Rename the table "ns.tbl" to "ns.new_tbl".
admin.renameTable("ns", "tbl", "new_tbl");
You cannot rename a table on non-JDBC databases.
Alter a column data type of a table​
You can alter a column data type of a table as follows:
// Alter the data type of the column "c6" to BIGINT in the table "ns.tbl".
admin.alterColumnDataType("ns", "tbl", "c6", DataType.BIGINT);
You cannot alter a column data type of a table in the following cases:
- The column is part of the partition key, clustering key, or secondary index key.
- The table is on a non-JDBC database or on SQLite.
- The conversions other than from INT to BIGINT, FLOAT to DOUBLE, and from any data to TEXT are specified.
- For Oracle, the conversions except for from INT to BIGINT are specified.
- For Db2 and TiDB, the conversion from BLOB to TEXT is specified.
You should carefully consider altering a column type because the execution time may vary greatly depending on the underlying storage. Please plan accordingly and consider the following, especially if the database runs in production:
- For relational databases (MySQL, Oracle, etc.): Altering a column issues
ALTER TABLE ... ALTER COLUMNorALTER TABLE ... MODIFYto the underlying relational databases and could trigger a table rebuild depending on the database. In such cases, it can take a long time to execute.
Truncate a table​
You can truncate a table as follows:
// Truncate the table "ns.tbl".
admin.truncateTable("ns", "tbl");
Drop a secondary index​
You can drop a secondary index as follows:
// 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);
When using Consensus Commit, dropIndex() also drops the companion before-image secondary index. For details, see Correctness of index-based reads.
Drop a table​
You can drop a table as follows:
// 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 a namespace​
You can drop a namespace as follows:
// 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);
Get existing namespaces​
You can get the existing namespaces as follows:
Set<String> namespaces = admin.getNamespaceNames();
This method extracts the namespace names of user tables dynamically. As a result, only namespaces that contain tables are returned. Starting from ScalarDB 4.0, we plan to improve the design to remove this limitation.