创建表

本文档提供有关创建表的最佳指导,以及一些简单示例。

开始前的准备

在阅读本页之前,请执行以下操作:

  • 创建Hubble集群
  • 查看数据库架构对象
  • 创建数据库
  • 创建用户定义的架构

创建表

表是集群中的逻辑对象,用于存储从应用程序写入的数据,表中以行和列的形式进行数据记录。

要创建表,使用CREATE TABLE语句,并且遵循以下步骤:

  • 命名一个表
  • 定义列
  • 选择主键列
  • 添加约束
  • 执行CREATE TABLE创建语句

请参阅以下提供的示例。

命名表

命名表是创建表的第一步。

CREATE TABLE语句通常采用以下形式:


CREATE TABLE {schema_name}.{table_name} (
  {elements}
  );
  
范围描述
{schema_name}用户定义模式的名称。
{table_name}表的名称。
{elements}以逗号分隔的表元素列表,例如列定义。

表命名最佳建议

以下是命名表时要遵循的一些最佳实践:

  • 使用完全限定名称(CREATE TABLE database_name.schema_name.table_name)。如果不指定数据库名称,Hubble将使用SQL会话的当前数据库(defaultdb默认情况下)。如果没有在表名中指定用户定义的模式,Hubble将在预加载的public模式中创建表。
  • 使用反映表内容的表名。例如,对于客户信息的表,可以使用名称cust_info

表命名示例

在数据库testdb中,为表cust_info添加一个CREATE TABLE语句:


CREATE TABLE testdb.public.cust_info (
);

定义列

列定义通过将每行中的值分隔为单一数据类型的列来为表提供结构。

表中列的定义通常采用以下形式:

{column_name} {data_type} {column_qualification}
范围描述
column_name列的名称。
data_type列的数据类型。
column_qualification某些列限定条件,例如列级约束或计算列子句。

列定义最佳建议

以下是定义表列时要遵循的一些要求:

  • 根据支持的列数据类型,为计划存储在列中的数据选择适当的类型。
  • 使用具有固定大小限制的列数据类型,或为可变大小的列数据类型设置最大大小限制(例如,VARCHAR(n))。
  • 根据业务的实际情况,决定是否需要定义主键列。
  • 根据业务的实际情况,并决定是否需要向列添加约束。

列定义

cust_info表中加入列


CREATE TABLE testdb.public.cust_info (
 cust_name     STRING,
 cust_card_no  STRING,  
 cust_phoneno  decimal(15)
);

上面显示的cust_namecust_card_no列都使用STRING数据类型,这意味着任何列中的任何值都必须是数据类型STRING。而cust_phoneno列中必须为数字。

当然,Hubble支持许多其他列数据类型,包括DECIMALINTTIMESTAMPUUID和枚举数据类型以及空间数据类型。

要创建用户定义的类型,使用CREATE TYPE语句

create type vtype as ENUM ('football', 'basketball', 'Rugby football');

然后您可以vtype用作type列的数据类型:

CREATE TABLE game (
  id UUID,
  type vtype,
  begin_time TIMESTAMPTZ
  );

type列中只允许vtype中定义的值

选择主键列

主键是一列或一组列,其值唯一标识数据行。每个表都需要一个主键。

主键在带有列约束CREATE TABLE的语句中定义。该约束要求所有受约束的列仅包含唯一值。

主键最佳实践

以下是选择主键列时要遵循的推荐的做法:

  • 避免在单列顺序数据上定义主键。

使用单个顺序列(例如,自动递增列)上的主键查询表可能会导致对性能产生负面影响。

如果正在使用必须在顺序键上建立索引的表,请使用散列分片索引。

  • 为每个表定义一个主键。

如果你创建一个没有定义主键的表,Hubble会自动创建rowid。 默认情况下,rowid为列中的每一行生成顺序的唯一标识符。值的顺序性质使rowid可能导致数据在集群中分布不均,这会对性能产生负面影响。此外,因为不能有意义地使用rowid列来过滤表数据,所以主键索引rowid不提供任何性能优化。这将要求用户始终通过为表根据业务自定义主键来提高性能。

  • 如果可能,在多个列上定义主键约束

在定义复合主键时,请确保主键前缀第一列中的数据在集群中的节点之间均匀分布。

  • 对于单列主键,使用UUID随机生成的默认值的类型化列

随机生成UUID值可确保主键值是唯一的并且在集群中分布良好。

主键示例

表和表中的CREATE TABLE语句需要显式定义主键。

create table cust_info (
    first_name string,
    last_name  string,
    phone_no   int,
    CONSTRAINT "primary" primary key (first_name, last_name)
  );

此主键将唯一标识用户数据行。

主键列也可以是单列,它们的值也应该在集群中均匀分布。

create table gameball (
      id uuid DEFAULT gen_random_uuid() primary key,
      begin_time TIMESTAMPTZ,
      is_null BOOL,
      end_time TIMESTAMPTZ
  );

除了PRIMARY KEY约束之外,该id列还有一个DEFAULT约束。此约束将列的默认值设置为gen_random_uuid()函数生成的值。此函数生成的值保证是唯一的,并且在集群中分布良好。

添加约束

除了PRIMARY KEY约束之外,Hubble还支持许多其他列级约束,包括CHECKDEFAULTFOREIGN KEYUNIQUENOT NULL。使用约束可以简化表查询,提高查询性能,并确保数据在语义上保持有效。

要约束单个列,请将约束关键字添加到列的定义中。要约束多列,在CREATE TABLE语句中的列列表之后添加整个约束的定义。

使用默认值

要在列上设置默认值,使用DEFAULT约束。默认值无需为每一列指定值即可编写查询。

举例如下:

create table trans (
   id uuid DEFAULT gen_random_uuid() primary key,
   trnas_time TIMESTAMPTZ
  );

当向表中插入一行数据时,hubble会为表生成一个随机默认值id。

唯一约束

要防止列中出现重复值,使用UNIQUE约束。

示例如下:

create table users_info (
    first_name string,
    last_name  string,
    card_no    string UNIQUE
);

尝试插入表users_info中已存在的card_no值将返回错误。

非空值

要防止列中出现空值,使用NOT NULL约束。如果指定了一个NOT NULL约束,则所有针对具有该约束的表的查询都必须为该列指定一个值。

create table users_info (
    first_name string,
    last_name  string,
    card_no    string not null
);

执行CREATE TABLE语句

为表定义CREATE TABLE语句后,可以执行这些语句。

CREATE TABLE执行事项

以下是执行CREATE TABLE语句时给予的建议:

  • 不要以root用户身份创建表。

  • 使用数据库架构迁移工具或客户端来执行数据库架构更改。

  • 了解联机模式更改的限制。

建议在显式事务之外执行架构更改。