表および索引の作成
表および索引の作成方法について学習します。
DDL文の例を次に示します。
/* Create a new table called users */
CREATE TABLE IF NOT EXISTS users(id INTEGER,
name STRING,
PRIMARY KEY(id))
/* Create a new table called users and set the TTL value to 4 days */
CREATE TABLE IF NOT EXISTS users(id INTEGER,
name STRING,
PRIMARY KEY(id))
USING TTL 4 days
/* Create a new multi-region table called users with two regions, and set the TTL value to 4 days */
CREATE TABLE users(
id INTEGER,
name STRING,
team STRING,
primary key(id))
USING TTL 4 DAYS IN REGIONS fra, lnd
/* Create a new index called nameIdx on the name field in the users table */
CREATE INDEX IF NOT EXISTS nameIdx ON users(name)
TableRequest
とそのメソッドを使用して、表と索引を作成します。TableRequest
クラスを使用すると、DDL文をTableRequest.setStatement
メソッドに渡すことができます。
/* Create a simple table with an integer key and a single json data
* field and set your desired table capacity.
* Set the table TTL value to 3 days.
*/
String createTableDDL = "CREATE TABLE IF NOT EXISTS users " +
"(id INTEGER, name STRING, " +
"PRIMARY KEY(id)) USING TTL 3 days";
TableRequest treq = new TableRequest().setStatement(createTableDDL);
// start the asynchronous operation
TableResult tres = handle.tableRequest(treq);
// The table request is asynchronous, so wait for the table to become active.
TableResult.waitForState(handle, tres.getTableName(),
TableResult.State.ACTIVE,
60000, // wait for 60 sec
1000); // delay in ms for poll
// Create an index called nameIdx on the name field in the users table.
treq = new TableRequest().setStatement("CREATE INDEX
IF NOT EXISTS nameIdx ON users(name)
");
// start the asynchronous operation
handle.tableRequest(treq);
final static String tableName = "users";
final static String childtableName = "userDetails";
String createchildTableDDL = "CREATE TABLE IF NOT EXISTS " +
tableName + "."+ childtableName + "(address STRING, salary INTEGER, " +
"PRIMARY KEY(address))";
TableRequest treq = new TableRequest().setStatement(createchildTableDDL);
System.out.println("Creating child table " + tableName);
TableResult tres = handle.tableRequest(treq);
/* The request is async,
* so wait for the table to become active.
*/
System.out.println("Waiting for "+ childtableName + " to become active");
tres.waitForCompletion(handle, 60000, /* wait 60 sec */
1000); /* delay ms for poll */
System.out.println("Table " + childtableName + " is active");
表の一覧を検索します:
ListTablesRequest tablereq = new ListTablesRequest();
String [] tablelis = handle.listTables(tablereq).getTables();
if (tablelis.length == 0)
System.out.println("No tables avaiable");
else {
System.out.println("The tables available are");
for (int i=0;i< tablelis.length; i++) {
System.out.println(tablelis[i]);
}
}
GetTableRequest gettblreq = new GetTableRequest();
gettblreq.setTableName(tableName);
System.out.println("The schema details for the table is "
+ handle.getTable(gettblreq).getSchema());
borneo.TableRequest
クラスを使用して実行されます。borneo.NoSQLHandle.table_request()
へのすべてのコールは非同期であるため、結果を確認し、borneo.TableResult.wait_for_completion()
をコールして操作が完了するまで待機する必要があります。 #Create a simple table with an integer key and a single
#json data field and set your desired table capacity.
#Set the table TTL value to 3 days.
from borneo import TableLimits,
TableRequest statement = 'create table if not exists users(id integer,
name string,
' + 'primary key(id)
USING TTL 3 DAYS'
request = TableRequest().set_statement(statement)
# assume that a handle has been created, as handle, make the request
#wait for 60 seconds, polling every 1 seconds
result = handle.do_table_request(request, 60000, 1000)
# the above call to do_table_request is equivalent to
# result = handle.table_request(request)
result.wait_for_completion(handle, 60000, 1000)
#Create an index called nameIdx on the name field in the users table.
request = TableRequest().set_statement("CREATE INDEX IF NOT EXISTS nameIdx
ON users(name)")
# assume that a handle has been created, as handle, make the request
#wait for 60 seconds, polling every 1 seconds
result = handle.do_table_request(request, 60000, 1000)
# the above call to do_table_request is equivalent to
# result = handle.table_request(request)
result.wait_for_completion(handle, 60000, 1000)
statement = 'create table if not exists users.userDetails (address STRING,
salary integer, primary key(address))'
print('Creating table: ' + statement)
request = TableRequest().set_statement(statement)
# Ask the cloud service to create the table,
# waiting for a total of 40000 milliseconds and polling the service
# every 3000 milliseconds to see if the table is active
table_result = handle.do_table_request(request, 40000, 3000)
table_result.wait_for_completion(handle, 40000, 3000)
if (table_result.get_state() != State.ACTIVE):
raise NameError('Table userDetails is in an unexpected state ' +
str(table_result.get_state()))
表の一覧を検索します:
ltr = ListTablesRequest()
list(str)= handle.list_tables(ltr).getTables()
if list(str).len() = 0
print ("No tables available")
else
print('The tables available are: ' + list(str))
request = GetTableRequest().set_table_name(table_name)
result = handle.get_table(request)
print('The schema details for the table is: ' + result.get_schema())
// Create a simple table with an integer key and a single
// json data field and set your desired table capacity.
// Set the table TTL value to 3 days.
tableName := "users"
stmt := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s "+
"(id integer, name STRING, PRIMARY KEY(id) "+
"USING TTL 3 DAYS)", tableName)
tableReq := &nosqldb.TableRequest{
Statement: stmt, }
tableRes, err := client.DoTableRequest(tableReq)
if err != nil {
fmt.Printf("cannot initiate CREATE TABLE request: %v\n", err)
return
}
_, err = tableRes.WaitForCompletion(client, 60*time.Second, time.Second)
if err != nil {
fmt.Printf("Error finishing CREATE TABLE request: %v\n", err)
return
}
fmt.Println("Created table ", tableName)
//Create an index called nameIdx on the name field in the users table
stmt_ind := fmt.Sprintf("CREATE INDEX IF NOT EXISTS nameIdx ON users(name)")
tableReq := &nosqldb.TableRequest{Statement: stmt_ind}
tableRes, err := client.DoTableRequest(tableReq)
if err != nil {
fmt.Printf("cannot initiate CREATE INDEX request: %v\n", err)
return
}
_, err = tableRes.WaitForCompletion(client, 60*time.Second, time.Second)
if err != nil {
fmt.Printf("Error finishing CREATE INDEX request: %v\n", err)
return
}
fmt.Println("Created index nameIdx ")
// Creates a simple child table with a string key and a single integer field.
childtableName := "users.userDetails"
stmt1 := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s ("+
"address STRING, "+
"salary INTEGER, "+
"PRIMARY KEY(address))",
childtableName)
tableReq1 := &nosqldb.TableRequest{Statement: stmt1}
tableRes1, err := client.DoTableRequest(tableReq1)
if err != nil {
fmt.Printf("cannot initiate CREATE TABLE request: %v\n", err)
return
}
// The create table request is asynchronous, wait for table creation to complete.
_, err = tableRes1.WaitForCompletion(client, 60*time.Second, time.Second)
if err != nil {
fmt.Printf("Error finishing CREATE TABLE request: %v\n", err)
return
}
fmt.Println("Created table ", childtableName)
表の一覧を検索します:
req := &nosqldb.ListTablesRequest{Timeout: 3 * time.Second,}
res, err := client.ListTables(req)
if len(res.Tables)== 0{
fmt.Printf("No tables in the given compartment"
return
}
fmt.Printf("The tables in the given compartment are:\n" )
for i, table := range res.Tables {
fmt.Printf(table)
}
req := &nosqldb.GetTableRequest{
TableName: table_name, Timeout: 3 * time.Second, }
res, err := client.GetTable(req)
fmt.Printf("The schema details for the table is:state=%s,
limits=%v\n", res.State,res.Limits)
表DDL文は、tableDDL
メソッドによって実行されます。NoSQLClient
クラスの他のほとんどのメソッドと同様に、このメソッドは非同期で、TableResult
のPromiseを返します。TableResult
は、DDL操作のステータス(TableState、名前、スキーマ、TableLimitなど)を含むプレーンJavaScriptオブジェクトです。
tableDDL
メソッドは、指定されたDDL操作のみを基礎となるストアで起動し、完了を待機しないことに注意してください。結果のTableResult
は、通常、TableState.CREATING
、TableState.DROPPING
、TableState.UPDATING
などの中間表の状態の1つを持ちます(後者は、表がALTER TABLE文によって変更されるプロセス中であるか、表の制限が変更されているか、その索引のいずれかが作成または削除されている場合に発生します)。
TableState.ACTIVE
またはTableState.DROPPED
に変更されます(DDL操作がDROP TABLEだった場合は後者)。const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
const TableState = require('oracle-nosqldb').TableState;
const client = new NoSQLClient('config.json');
async function createUsersTable() {
try {
const statement = 'CREATE TABLE IF NOT EXISTS users(id INTEGER, ' +
'name STRING, PRIMARY KEY(id))';
let result = await client.tableDDL(statement);
result = await client.forCompletion(result);
console.log('Table users created');
} catch(error) {
//handle errors
}
}
const statement = 'CREATE TABLE IF NOT EXISTS users(id INTEGER, ' +
'name STRING, PRIMARY KEY(id))';
let result = await client.tableDDL(statement,
complete: true
});
console.log('Table users created');
// Create an index called nameIdx on the name field in the users table.
try {
const statement = 'CREATE INDEX IF NOT EXISTS nameIdx ON users(name))';
let result = await client.tableDDL(statement);
result = await client.forCompletion(result);
console.log('Index nameIdx created');
} catch(error){
//handle errors
}
/**
* This function will create the child table userDetails with two columns,
* one string column address which will be the primary key and one integer column
* which will be the salary.
* @param {NoSQLClient} handle An instance of NoSQLClient
*/
const TABLE_NAME = 'users';
const CHILDTABLE_NAME = 'userDetails';
async function createChildTable(handle) {
const createChildtblDDL = `CREATE TABLE IF NOT EXISTS ${TABLE_NAME}.${CHILDTABLE_NAME}
(address STRING, salary INTEGER, PRIMARY KEY(address))`;
console.log('Create table: ' + createChildtblDDL);
let res = await handle.tableDDL(createChildtblDDL, {complete: true});
}
表の一覧を検索します:
let varListTablesResult = await client.listTables();
console.log("The tables in the given compartment are:")
{res.send(varListTablesResult)}
let resExistingTab = await client.getTable(tablename);
{ await client.forCompletion(resExistingTab);}
console.log("The schema details for the table is:")
{ res.send(resExistingTab.schema)}
表を作成し、他のデータ定義言語(DDL)文(表の作成、変更および削除、索引の作成および削除など)を実行するには、ExecuteTableDDLAsync
およびExecuteTableDDLWithCompletionAsync
メソッドを使用します。メソッドExecuteTableDDLAsync
およびExecuteTableDDLWithCompletionAsync
は、Task<TableResult>
を返します。TableResultインスタンスには、TableStateや表スキーマなどのDDL操作のステータスが含まれます。これらの各メソッドには、複数のオーバーロードがあります。特に、DDL操作のオプションをTableDDLOptions
として渡すことができます。
ExecuteTableDDLAsync
は、サービスによって指定されたDDL操作のみを起動し、その完了を待機しません。返されるTableResultインスタンスでWaitForCompletionAsync
をコールすることで、表DDL操作の完了を非同期で待機できます。var client = new NoSQLClient("config.json");
try {
var statement = "CREATE TABLE IF NOT EXISTS users(id INTEGER,"
+ "name STRING, PRIMARY KEY(id))";
var result = await client.ExecuteTableDDLAsync(statement);
await result.WaitForCompletionAsync();
Console.WriteLine("Table users created.");
} catch(Exception ex) {
// handle exceptions
}
WaitForCompletionAsync
は、操作の完了を反映するようにコール元のTableResultインスタンスを変更することに注意してください。
ExecuteTableDDLWithCompletionAsync
を使用することもできます。try-catchブロックの文を次のように置き換えます。var statement = "CREATE TABLE IF NOT EXISTS users(id INTEGER,"
+ "name STRING, PRIMARY KEY(id))";
await client.ExecuteTableDDLWithCompletionAsync(statement);
Console.WriteLine("Table users created.");
private const string TableName = "users";
private const string ChildTableName = "userDetails";
// Create a child table
var childtblsql = $"CREATE TABLE IF NOT EXISTS {TableName}.{ChildTableName}
address STRING, salary INTEGER, PRIMARY KEY(address))";
Console.WriteLine("\nCreate table {0}", ChildTableName);
var tableResult = await client.ExecuteTableDDLAsync(childtblsql);
Console.WriteLine(" Creating table {0}", ChildTableName);
Console.WriteLine(" Table state: {0}", tableResult.TableState);
// Wait for the operation completion
await tableResult.WaitForCompletionAsync();
Console.WriteLine(" Table {0} is created",tableResult.TableName);
Console.WriteLine(" Table state: {0}", tableResult.TableState);
表の一覧を検索します:
varresult = await client.ListTablesAsync();
console.WriteLine("The tables in the given compartment are:")
foreach(var tableName inresult.TableNames){
Console.WriteLine(tableName);
}
Springデータ・アプリケーションでは、@NosqlTable.autoCreateTable
がfalse
に設定されていないかぎり、エンティティの初期化時に表がアプリケーションの開始時に自動的に作成されます。
永続化するUsers
エンティティ・クラスを作成します。このエンティティ・クラスはOracle NoSQL Databaseの表を表しています。また、このエンティティのインスタンスはその表の行に対応します。
IDフィールドを示す@NosqlId
注釈を指定します。generated=true
属性は、IDが自動生成されることを指定します。表レベルのTTLを設定するには、エンティティ・クラスの@NosqlTable
注釈にttl()
およびttlUnit()
パラメータを指定します。すべてのSpring Dataクラス、メソッド、インタフェースおよび例の詳細は、SDK for Spring Data APIリファレンスを参照してください。
import com.oracle.nosql.spring.data.core.mapping.NosqlId;
import com.oracle.nosql.spring.data.core.mapping.NosqlTable;
/* The @NosqlTable annotation specifies that this class will be mapped to an Oracle NoSQL Database table. */
/* Sets the table level TTL to 10 Days. */
@NosqlTable(ttl = 10, ttlUnit = NosqlTable.TtlUnit.DAYS)
public class Users {
@NosqlId(generated = true)
long id;
String firstName;
String lastName;
/* public or package-protected constructor is required when retrieving from the database. */
public Users() {
}
@Override
public String toString() {
return "Users{" +
"id=" + id + ", " +
"firstName=" + firstName + ", " +
"lastName=" + lastName +
'}';
}
}
UsersRepository
インタフェースを作成します。このインタフェースは、NosqlRepository
インタフェースを拡張して、そのクラスの主キーのエンティティ・クラスとデータ型をパラメータ化された型としてNosqlRepository
インタフェースに提供します。このNosqlRepository
インタフェースは、データベースのデータの格納または取得に使用されるメソッドを備えています。import com.oracle.nosql.spring.data.repository.NosqlRepository;
/* The Users is the entity class and Long is the data type of the primary key in the Users class.
This interface provides methods that return iterable instances of the Users class. */
public interface UsersRepository extends NosqlRepository<Users, Long> {
/* Search the Users table by the last name and return an iterable instance of the Users class.*/
Iterable<Users> findByLastName(String lastname);
}
CommandLineRunner
インタフェースを使用して、runメソッドを実装し、mainメソッドを持つアプリケーション・コードを表示できます。
ノート:
Spring Data Frameworkが提供する各種インタフェースのいずれかを実装することで、目的の要件に応じた機能をコーディングできます。Spring bootアプリケーションの設定の詳細は、「Spring Boot」を参照してください。import com.oracle.nosql.spring.data.core.NosqlTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/* The @SpringBootApplication annotation helps you to build an application using Spring Data Framework rapidly.*/
@SpringBootApplication
public class App implements CommandLineRunner {
/* The annotation enables Spring Data Framework to look up the configuration file for a matching bean.*/
@Autowired
private UsersRepository repo;
public static void main(String[] args) {
ConfigurableApplicationContext ctx =
SpringApplication.run(App.class, args);
SpringApplication.exit(ctx, () -> 0);
ctx.close();
System.exit(0);
}
@Override
public void run(String... args) throws Exception {
}
}
kv_json_
というJSON列という2つの列が含まれます。
ノート:
表がすでに存在する場合は、生成されたスキーマに準拠する必要があります。Users
表のフィールドに索引を作成するには、NosqlTemplate.runTableRequest()
を使用します。
Oracle NoSQL Databaseの接続詳細を指定するために、AbstractNosqlConfiguration
クラスを拡張するAppConfig
クラスを作成します。詳細は、「NoSQL接続の取得」を参照してください。
アプリケーションでは、AppConfig
クラスのインスタンスにNosqlTemplate
create (NosqlDbConfig nosqlDBConfig
)メソッドを指定して、NosqlTemplate
クラスをインスタンス化します。次に、NosqlTemplate.runTableRequest()
メソッドを使用して表を変更します。NosqlTemplate.runTableRequest()
メソッドで索引を作成するためのNoSQL文を指定します。
Users
表のlastName
フィールドに索引を作成します。import com.oracle.nosql.spring.data.core.NosqlTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
/* Create an Index on the lastName field of the Users Table. */
try {
AppConfig config = new AppConfig();
NosqlTemplate idx = NosqlTemplate.create(config.nosqlDbConfig());
idx.runTableRequest("CREATE INDEX IF NOT EXISTS nameIdx ON Users(kv_json_.lastName AS STRING)");
System.out.println("Index created successfully");
} catch (Exception e) {
System.out.println("Exception creating index" + e);
}
表の作成の詳細は、Spring Data SDK開発者ガイドの例: Spring Data Frameworkを使用したOracle NoSQL Databaseへのアクセスを参照してください。