使用 API 创建单例表
表是用于存储用户数据的基本结构。可以使用 SQL 命令(CREATE TABLE 语句)或 TableRequest API 命令创建新表。
您还可以使用 Oracle NoSQL Cloud Infrastructure (OCI) 控制台或 OCI 命令行界面 (OCI-cli) 在 NDCS 中创建表。
创建表的指导原则:
-
表定义必须至少包含一个字段定义和一个主键定义。有关主键定义的更多信息,请参阅创建表。
-
字段定义指定列的名称、列的数据类型、列是否可为空、可选默认值、列是否为 IDENTITY 列和可选注释。默认情况下,所有字段(PRIMARY KEY 除外)都可为空。
-
主键规范 (key_definition) 的语法将表的主键列指定为字段名的有序列表。
-
生存时间 (Time-To-Live,TTL) 值用于计算行的到期时间。过期的行不包括在查询结果中,最终会被 Oracle NoSQL Database 自动从表中删除。如果在创建表时指定 TTL 值,则该值将作为插入到此表中的每一行的默认 TTL。
创建表:
使用 SQL 命令
可以在 SQL 中使用 CREATE TABLE 命令创建 NoSQL 表。
下节重点介绍使用 CREATE TABLE DDL 语句创建表时可以使用的不同选项。
示例 1:创建一个航空公司行李跟踪应用程序表,用于在航空公司系统中存储乘客的行李信息。
CREATE TABLE BaggageInfo (
ticketNo LONG,
fullName STRING,
gender STRING,
contactPhone STRING,
confNo STRING,
bagInfo JSON,
PRIMARY KEY (ticketNo)
)
在上面的方案中,可以使用 CREATE TABLE 语句定义 BaggageInfo 表。乘客的票号 ticketNo 是表的主键。fullName、gender、contactPhone 和 confNo(保留号)字段存储乘客的信息,这是固定模式的一部分。bagInfo 列是一个无模式的 JSON 数组,它表示乘客托运行李的跟踪信息。
有关航空行李跟踪应用的更多详细信息,请参阅航空行李跟踪应用。
示例 2:创建包含 JSON 字段的流媒体服务表,以跟踪订户的当前活动。
CREATE TABLE stream_acct(
acct_id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(9),
acct_data JSON,
PRIMARY KEY(acct_id)
)USING TTL 5 DAYS
在上面的方案中使用 CREATE TABLE 语句创建 stream_acct 表。订户的帐户 ID acct_id 字段是此表中的主键。字段 profile_name 和 account_expiry 存储查看权限详细信息,这是固定模式的一部分。acct_data 列是无模式的 JSON 字段,用于存储用户查看的显示的详细信息。
有关流媒体服务应用程序的更多详细信息,请参见 Streaming Media Service - Persistent user profile store
还要指定一个 TTL 值,之后行将自动失效且不再可用。TTL 值必须为“小时”或“天”。在此方案中,表中的行将在 5 天后失效。
示例 3:创建具有各种固定模式定义的流媒体服务表。
CREATE TABLE IF NOT EXISTS stream_acct(
acct_id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(9),
acct_data RECORD (
firstName STRING,
lastName STRING,
country STRING,
shows JSON
),
PRIMARY KEY(acct_id)
)
在上面的方案中,通过将 acct_data 字段作为 RECORD 数据类型来定义固定模式的变体。
记录是一个或多个键项对的有序集合。记录中的关键字必须是字符串,关联的项可以是不同数据类型。记录中的字段是固定模式的一部分,您将无法添加或删除它们。在上面的示例中,字段 firstName、lastName、country 和 shows 是 acct_data 记录的关键字。当您希望将数据存储为更大的数据集的一部分时,定义记录很有帮助。您可以使用字段步骤表达式在记录中插入/更新/提取整个子集。
还可以按如下方式嵌套记录:
CREATE TABLE IF NOT EXISTS stream_acct(
acct_id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(9),
acct_data RECORD (
firstName STRING,
lastName STRING,
country STRING,
shows RECORD (
showName STRING,
showId INTEGER,
type JSON,
numSeasons INTEGER,
seriesInfo ARRAY(JSON)
)
),
PRIMARY KEY(acct_id)
)
shows 字段是一种嵌套的 RECORD 类型,用于跟踪查看的显示内容的详细信息。
示例 4:创建流媒体服务表作为分层表结构。
在以下方案中,将 stream_acct 表创建为父表,将 acct_data 表创建为子表:
CREATE TABLE IF NOT EXISTS stream_acct(
acct_id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(9),
PRIMARY KEY(acct_id))
CREATE TABLE IF NOT EXISTS stream_acct.acct_data(
profile_id INTEGER,
user_name STRING,
firstName STRING,
lastName STRING,
country STRING,
shows JSON,
PRIMARY KEY(profile_id))
通过上面的父子表定义,流媒体服务可以在单个订阅下支持多个用户配置文件。
将 acct_data 表定义为主键为 profile_id 的子表,用于标识用户的配置文件。除了为表定义主键外,acct_data 表还隐式继承其父 stream_acct 表的 acct_id 主键列。
可以在同一个 stream_acct 父表下定义多个子表。可以进一步定义 acct_data 表的子表。层次结构中的所有表都具有相同的分片键列,该列在层次结构中最高父表的 create 表语句中指定。在此示例中,父表的主键 acct_id 也是 stream_acct 和 acct_data 表的分片键。
示例 5:创建主键为 IDENTITY 列的流媒体服务表。
CREATE TABLE IF NOT EXISTS stream_acct(
acct_id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 4 INCREMENT BY 1 NO CYCLE),
profile_name STRING,
account_expiry TIMESTAMP(9),
acct_data JSON,
PRIMARY KEY(acct_id)
)
在此示例中,使用在示例 2 中定义的相同字段创建 stream_acct 表。但是,方案将主键 acct_id 定义为 IDENTITY 列。将 IDENTITY 列定义为 GENERATED BY DEFAULT AS IDENTITY 时,如果不提供 IDENTITY 列值,系统将自动生成 IDENTITY 列值。系统开始从 4 开始生成 acct_id 值,以 1 递增。因此,acct_id 列的值将为 4、5、6 …,依此类推,直到 LONG 数据类型的最大值。当模式定义 NO CYCLE 选项时,系统会在最大值之后引发异常,因为它已到达序列生成器的末尾。
示例 6:创建主键为 UUID 数据类型的流媒体服务表。
CREATE TABLE IF NOT EXISTS stream_acct(
acct_id STRING AS UUID GENERATED BY DEFAULT,
profile_name STRING,
account_expiry TIMESTAMP(9),
acct_data JSON,
PRIMARY KEY(acct_id)
)
在此示例中,使用在示例 2 中定义的相同字段创建 stream_acct 表。但是,方案将主键 acct_id 定义为 UUID 数据类型 GENERATED BY DEFAULT。如果不提供 UUID 列,系统将自动为 UUID 列生成值。将主键定义为 UUID 数据类型的潜在优点是,虽然系统仅保证某个区域中的 NoSQL 数据存储中的 IDENTITY 列的唯一性,但 UUID 数据类型会为跨多个区域的表中的记录生成全局唯一标识符。
JSON 收集表
示例 7:将流媒体服务表创建为 JSON 集合表。
在下面的 CREATE TABLE 语句中,您将 stream_acct 表创建为 JSON 集合表:
CREATE TABLE IF NOT EXISTS stream_acct(
acct_id INTEGER,
PRIMARY KEY(acct_id)) AS JSON COLLECTION
此 JSON 集合表将 acct_id 作为主键字段。除了 DDL 命令中的主键字段外,无需提供任何其他字段。
向此表中插入数据时,JSON 集合表会自动将 acct_id 字段以外的已插入字段视为 JSON 字段。您可以使用此 JSON 集合表来存储和检索纯粹作为文档的电视流数据。
示例 8:将购物应用程序表创建为 JSON 集合表。
以下 CREATE TABLE 语句定义了 storeAcct 表,这是为购物应用程序创建的 JSON 集合表。此表将 contactPhone 作为字符串类型的主键字段。
CREATE TABLE storeAcct(
contactPhone string,
primary key(contactPhone)) AS JSON COLLECTION
使用 TableRequest API
可以使用 TableRequest API 创建 NoSQL 表。
TableRequest 类用于创建表。此请求指定的操作的执行是异步的。这些操作可能是长时间运行的操作。TableResult 是从 TableRequest 操作返回的,它将封装表的状态。有关 TableRequest 类及其方法的更多详细信息,请参阅 Oracle NoSQL Java SDK API Reference 。
Download the full code CreateTable.java from the examples here.
private static void createTab(NoSQLHandle handle) throws Exception {
String createTableDDL =
"CREATE TABLE IF NOT EXISTS " + tableName +
"(acct_Id INTEGER," +
"profile_name STRING," +
"account_expiry TIMESTAMP(1) ," +
"acct_data JSON, " +
"PRIMARY KEY(acct_Id))";
TableLimits limits = new TableLimits(20, 20, 1);
TableRequest treq = new TableRequest()
.setStatement(createTableDDL)
.setTableLimits(limits);
TableResult tres = handle.tableRequest(treq);
/* The request is async,
* so wait for the table to become active.
*/
tres.waitForCompletion(handle, 60000,1000);
System.out.println("Created Table: " + tableName);
}
注:表限制仅适用于 Oracle NoSQL Database Cloud Service。如果为内部部署 NoSQL 数据库设置了限制,则会忽略这些限制。
创建子表:使用相同的 TableRequest 类和方法执行 DDL 语句来创建子表。
创建子表时:
-
您需要指定表的全名 (name_parent_table.name_child_table)
-
不需要显式设置表限制,因为子表会继承父表的限制。
从示例下载完整的代码 TableJoins.java,以了解如何在此处创建父子表。
创建 JSON 集合表:
JSON 集合表包括具有一个或多个主键字段和 JSON 字段的文档。以下示例将 stream_acct 表创建为 JSON 集合表:
/* Create a JSON collection table with an integer primary key */
private static void createTable(NoSQLHandle handle) throws Exception {
String createTableDDL =
"CREATE TABLE IF NOT EXISTS " + tableName +
"(acct_Id INTEGER, PRIMARY KEY(acct_Id)) AS JSON COLLECTION";
TableRequest treq = new TableRequest().setStatement(createTableDDL);
System.out.println("Creating table");
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, 1000);
}
borneo.TableRequest 类用于创建表。对 borneo.NoSQLHandle.table_request() 的所有调用都是异步的,因此需要检查结果并调用 borneo.TableResult.wait_for_completion() 以等待操作完成。有关 table_request 及其方法的更多详细信息,请参阅 Oracle NoSQL Python SDK API Reference 。
Download the full code CreateTable.py from the examples here.
def create_table(handle):
statement = '''create table if not exists
stream_acct (acct_Id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(1),
acct_data JSON,
primary key(acct_Id))'''
request = TableRequest().set_statement(statement)
.set_table_limits(TableLimits(20, 10, 1))
table_result = handle.do_table_request(request, 40000, 3000)
table_result.wait_for_completion(handle, 40000, 3000)
if (table_result.get_state() == State.ACTIVE):
print('Created table: stream_acct')
else:
raise NameError('Table stream_acct is in an unexpected state ' +
str(table_result.get_state()))
注:表限制仅适用于 Oracle NoSQL Database Cloud Service。如果为内部部署 NoSQL 数据库设置了限制,则会忽略这些限制。
创建子表:使用相同的 TableRequest 类和方法执行 DDL 语句来创建子表。
创建子表时:
-
您需要指定表的全名 (name_parent_table.name_child_table)。
-
不需要显式设置表限制,因为子表会继承父表的限制。
Download the full code TableJoins.py from the examples here.
创建 JSON 集合表:
JSON 集合表包括具有一个或多个主键字段和 JSON 字段的文档。以下示例将 stream_acct 表创建为 JSON 集合表:
# Create a JSON collection table with an integer primary key
statement = '''CREATE TABLE IF NOT EXISTS stream_acct
(acct_Id INTEGER, PRIMARY KEY(acct_Id))
AS JSON COLLECTION'''
print('Creating table: ' + statement)
request = TableRequest().set_statement(statement)
# Wait for 60 seconds, polling every 1 second
result = handle.do_table_request(request, 60000, 1000)
result.wait_for_completion(handle, 60000, 1000)
print('Created table: stream_acct')
TableRequest 类用于创建表。TableRequest 指定的操作的执行是异步的。这些操作可能是长时间运行的操作。此请求用作 Client.DoTableRequest() 操作的输入,该操作将返回可用于轮询的 TableResult,直到表达到所需状态。有关 TableRequest 类的各种方法的更多详细信息,请参阅 Oracle NoSQL Go SDK API Reference 。
Download the full code CreateTable.go from the examples here.
func createTable(client *nosqldb.Client, err error, tableName string)(){
// Creates a table
stmt := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s ("+
"acct_Id INTEGER," +
"profile_name STRING," +
"account_expiry TIMESTAMP(1) ," +
"acct_data JSON, " +
"PRIMARY KEY(acct_Id))",tableName)
tableReq := &nosqldb.TableRequest{
Statement: stmt,
TableLimits: &nosqldb.TableLimits{
ReadUnits: 20,
WriteUnits: 20,
StorageGB: 1,
},
}
tableRes, err := client.DoTableRequest(tableReq)
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 = 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)
return
}
注:表限制仅适用于 Oracle NoSQL Database Cloud Service。如果为内部部署 NoSQL 数据库设置了限制,则会忽略这些限制。
创建子表:使用相同的 TableRequest 类和方法执行 DDL 语句来创建子表。
创建子表时:
-
您需要指定表的全名 (name_parent_table.name_child_table)。
-
不需要显式设置表限制,因为子表会继承父表的限制。
Download the full code TableJoins.go from the examples here.
创建 JSON 集合表:
JSON 集合表包括具有一个或多个主键字段和 JSON 字段的文档。以下示例将 stream_acct 表创建为 JSON 集合表:
/* Create a JSON collection table with an integer primary key */
func createTable(client *nosqldb.Client) error {
tableName := "stream_acct"
stmt := fmt.Sprintf(
"CREATE TABLE IF NOT EXISTS %s "+
"(acct_Id INTEGER, PRIMARY KEY(acct_Id)) "+
"AS JSON COLLECTION",
tableName,
)
fmt.Println("Creating table:", stmt)
tableReq := &nosqldb.TableRequest{
Statement: stmt,
}
tableRes, err := client.DoTableRequest(tableReq)
if err != nil {
return err
}
// Wait for 60 seconds, polling every 1 second.
_, err = tableRes.WaitForCompletion(
client,
60*time.Second,
time.Second,
)
if err != nil {
return err
}
fmt.Println("Created table:", tableName)
return nil
}
可以使用 tableDDL 方法创建表。此方法为异步方法,返回 Promise of TableResult。TableResult 是一个普通的 JavaScript 对象,其中包含 DDL 操作的状态,例如 TableState、name、schema 和 TableLimits。有关方法详细信息,请参见 NoSQLClient 类。
tableDDL 方法将 TableDDLOpt 对象作为第二个可选参数。创建表时,必须将其 TableLimits 指定为 opt 参数的一部分。TableLimits 将表的最大吞吐量和存储容量指定为读取单位数、写入单位数和存储 GB 数。
Download the full JavaScript code CreateTable.js from the examples here and the full TypeScript code CreateTable.ts from the examples here.
import {NoSQLClient, TableState } from 'oracle-nosqldb';
const client = new NoSQLClient('config.json');
const TABLE_NAME = 'stream_acct;
async function createTable(handle) {
const createDDL = `CREATE TABLE IF NOT EXISTS
${TABLE_NAME} (acct_Id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(1),
acct_data JSON,
primary key(acct_Id))`;
/* For Provisioned Capacity specify read units, write units, and storage limit as shown below*/
/* For On-demand Capacity - set only the storage limit and specify the mode as shown here.
* { storageGB: 25, mode: CapacityMode.ON_DEMAND };
*/
let res = await handle.tableDDL(createDDL, {
complete: true,
tableLimits: {
readUnits: 20,
writeUnits: 20,
storageGB: 1
}
});
console.log('Created table: ' + TABLE_NAME);
}
在上述调用返回后,结果将反映操作的最终状态。或者,要使用完整选项,请使用以下代码示例替换上面的 try-catch 块中的代码。
const createDDL = `CREATE TABLE IF NOT EXISTS
${TABLE_NAME} (acct_Id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(1),
acct_data JSON,
primary key(acct_Id))`;
let res = await client.tableDDL(createDDL, {complete: true,});
console.log('Created table: ' + TABLE_NAME);
创建子表:使用相同的 TableRequest 类和方法执行 DDL 语句来创建子表。
创建子表时:
-
您需要指定表的全名 (name_parent_table.name_child_table)
-
不需要显式设置表限制,因为子表会继承父表的限制。
Download the full JavaScript code TableJoins.js from the examples here and the full TypeScript code TableJoins.ts from the examples here.
创建 JSON 集合表:
JSON 集合表包括具有一个或多个主键字段和 JSON 字段的文档。以下示例将 stream_acct 表创建为 JSON 集合表:
/* Create a JSON collection table with an integer primary key */
const client = new NoSQLClient('config.json');
const TABLE_NAME = 'stream_acct';
async function createTable() {
const createDDL =
`CREATE TABLE IF NOT EXISTS ${TABLE_NAME} ` +
`(acct_Id INTEGER, PRIMARY KEY(acct_Id)) ` +
`AS JSON COLLECTION`;
console.log('Create table: ' + createDDL);
try {
await client.tableDDL(createDDL, {
complete: true
});
console.log('Created table: ' + TABLE_NAME);
} catch (error) {
console.error('Table creation failed:', error);
throw error;
}
}
要创建表,请使用方法 ExecuteTableDDLAsync 或 ExecuteTableDDLWithCompletionAsync。这两种方法都返回 Task<TableResult>。TableResult 实例包含 DDL 操作的状态,例如 TableState 和表方案。有关这些方法的更多详细信息,请参阅 Oracle NoSQL Dotnet SDK API Reference 。
Download the full code CreateTable.cs from the examples here.
private static async Task createTable(NoSQLClient client){
// Create a table
var sql =
$@"CREATE TABLE IF NOT EXISTS
{TableName}(acct_Id INTEGER,
profile_name STRING,
account_expiry TIMESTAMP(1),
acct_data JSON,
primary key(acct_Id))";
var tableResult = await client.ExecuteTableDDLAsync(sql,
new TableDDLOptions{TableLimits = new TableLimits(20, 20, 1)});
// Wait for the operation completion
await tableResult.WaitForCompletionAsync();
Console.WriteLine(" Created table: ",tableResult.TableName);
}
注:表限制仅适用于 Oracle NoSQL Database Cloud Service。如果为内部部署 NoSQL 数据库设置了限制,则会忽略这些限制。
创建子表:使用相同的 TableRequest 类和方法执行 DDL 语句来创建子表。
创建子表时:
-
您需要指定表的全名 (name_parent_table.name_child_table)
-
不需要显式设置表限制,因为子表会继承父表的限制。
Download the full code TableJoins.cs from the examples here.
创建 JSON 集合表:
JSON 集合表包括具有一个或多个主键字段和 JSON 字段的文档。以下示例将 stream_acct 表创建为 JSON 集合表:
/* Create a JSON collection table with an integer primary key */
private static async Task CreateTableAsync(NoSQLClient client)
{
const string tableName = "stream_acct";
var statement =
$"CREATE TABLE IF NOT EXISTS {tableName} " +
"(acct_Id INTEGER, PRIMARY KEY(acct_Id)) " +
"AS JSON COLLECTION";
Console.WriteLine($"Creating table: {statement}");
var result = await client.ExecuteTableDDLAsync(statement);
await result.WaitForCompletionAsync();
Console.WriteLine($"Table {tableName} created.");
}