02 如何创建数据表? | OushuDB 数据库使用入门

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02 如何创建数据表? | OushuDB 数据库使用入门相关的知识,希望对你有一定的参考价值。


基本概念

在关系型数据库中,表由行和列组成。

  • 其中表的列的数目和顺序是固定的,每个列都有一个名字,并且有指定的数据类型,即限制着这个列可以存储的范围。比如,声明为数值类型的列不可以存储字符串,否则该列不能用于数学计算,声明为字符串类型的列可以存储几乎任意类型的数据,但是却不能进行数学计算。常用的数据类型有:用于整数的integer类型、用于可能为分数的numeric类型、用于字符串的text类型、用于日期的date类型等等,在后面的课程中,我们会对OushuDB支持的这些数据类型进行详细的介绍。
  • 与表的列不同,表的行数目是变化的,它反映了在某个时刻表中存储的数据量。行是没有顺序的,除非在查询时对其进行要求,另外,行也没有唯一的标识符,不同行的数据完全相同的情况是被允许的,如果不希望这样,也可以通过一些限制来处理。

下面,我们来使用CREATE TABLE命令创建一个表。

在这个命令里,你需要为声明新表的名称、各列的名称及数据类型。比如:

CREATE TABLE my_first_table (
first_column text,
second_column integer
);

这样就创建了一个有两个列的名为my_first_table的默认格式表。第一个列的名字是first_column,数据类型为text;第二个列的名字是second_column,数据类型是integer。

OushuDB现在支持多种存储格式:AO、ORC和Magma。AO是按行存储的格式,而ORC、Magma是按行列存储的格式。 其中Magma 是在4.0.0.0发布的全新的存储格式。Magma和ORC都支持update/delete, 且Magma还支持index。

这三种存储格式的特性支持情况如图所示,大家可以根据自己的需求来选择。

02

这三种不同的存储格式下,创建表的命令也有所区别,下面给出几个例子以供参考。

# 默认创建的是AO表
CREATE TABLE rank1 (id int, rank int, year smallint,gender char(1), count int );

# 和上面的创建的表一样,显式指定存储格式类型
CREATE TABLE rank2 (id int, rank int, year smallint,gender char(1), count int ) with (appendonly =true, orientation =row);

# 创建一个snappy压缩的AO表
CREATE TABLE rank3 (id int, rank int, year smallint,gender char(1), count int ) with (appendonly =true, orientation =row, compresstype = snappy);

# 创建一个不压缩的ORC表,如果不指定压缩类型的话,默认不压缩。
CREATE TABLE rank3 (id int, rank int, year smallint,gender char(1), count int ) with (appendonly =true, orientation =orc);

# 创建一个带压缩的ORC表,需指定压缩类型。
CREATE TABLE rank3 (id int, rank int, year smallint,gender char(1), count int ) with (appendonly =true, orientation =orc, compresstype = lz4);

# 创建一个压缩的magma表, magma 内部自动实现了压缩。
CREATE TABLE rank3 (id int, rank int, year smallint,gender char(1), count int ) format Magma;

# 创建一个有primary key的magma表, magma 内部自动实现了压缩。
CREATE TABLE rank3 (id int, rank int, year smallint,gender char(1), count int,primary key(id) ) format Magma;

当我们不再需要一个表,那么可以用DROP TABLE命令删除它。如删除一个表名为my_first_table的表:

DROP TABLE my_first_table;

好的,学习以上内容,就可以完成一个表的创建了。

下面我们来说一下,在创建表时可以设置的缺省值和约束。

缺省值

我们可以给任何一个列赋予了缺省值,如果在创建数据行的时候不去给这些列指定值的时候,这些列将被填充为它们相应的缺省值。

如果没有明确声明缺省值,那么缺省值是 NULL, 表示”未知”。

在一个表定义里,缺省值是在列数据类型后面列出的。比如:

CREATE TABLE products (
product_no integer,
name text,
price numeric DEFAULT 9.99
);

在上面的例子中,如果在插入行数据时price字段没有被赋值,将会被填充缺省值9.99。

缺省值也可以是一个表达式,它会在插入缺省值的时候计算(不是在创建表的时候)。一个常见的例子是一个timestamp列可能有缺省值now(),它表示插入行的时刻。

比如,

CREATE TABLE purchaseHistory (
purchase_id integer,
product_no integer,
time timestamp DEFAULT now()
);

需要注意的是,MAGMA格式的表不支持为列设置缺省值。

约束

数据类型是一种限制能够存储在表中数据类别的方法。但是对于很多应用来说,它们提供的约束精度不够,比如我们需要某列只存储正数,却没有对应的数据类型来处理,又或者,我们新建一个员工表,希望他们的员工编号不可以重复。

这时我们就可以通过在列或者表上定义约束来进行控制。如果用户企图在列里存储不符合条件的数据就会抛出一个错误。

检查约束

检查约束是最常见的约束类型。它允许你声明在某个列里的数值必须使一个布尔表达式为真。比如,要强制一个正数的产品价格,你可以用:

CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0)
);

一个检查约束由一个关键字CHECK后面跟一个放在圆括弧里的表达式组成,表达式里应包含受约束的列,否则这个约束就没什么意义了。

约束的定义放在数据类型之后,可以和缺省值按任意顺序排列。我们还可以给这个约束取一个独立的名字,这样可以让错误消息更清晰,便于提示用户修改。

例如,我们给刚才的表达式前面增加关键字CONSTRAINT,以及约束的名称positive_price:

CREATE TABLE products (
product_no integer,
name text,
price numeric CONSTRAINT positive_price CHECK (price > 0)
);

约束也可以引用多个列,这样的话这个约束便不能跟在某行后面,而是需要在逗号分隔的列定义列表中以一个独立行的形式出现,我们称之为“表约束”。

假设在刚才的表中,我们需要存储一个正常价格和一个折扣价,并且保证折扣价比正常价低:

CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0),
discounted_price numeric CHECK (discounted_price > 0),
CHECK (price > discounted_price)
);

列约束也可以写成表约束,但反过来很可能不行,因为系统假设列约束只引用它所从属的列。

例如,我们将表中的行约束全都变为表约束,可以改写为:

CREATE TABLE products (
product_no integer,
name text,
price numeric,
CHECK (price > 0),
discounted_price numeric,
CHECK (discounted_price > 0),
CHECK (price > discounted_price)
);

或者是:

CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0),
discounted_price numeric,
CHECK (discounted_price > 0 AND price > discounted_price)
);

和列约束一样,我们也可以给表约束赋予名称,方法也相同:

CREATE TABLE products (
product_no integer,
name text,
price numeric,
CHECK (price > 0),
discounted_price numeric,
CHECK (discounted_price > 0),
CONSTRAINT valid_discount CHECK (price > discounted_price)
);

我们还要注意的是,当约束表达式计算结果为真或 NULL 的时候,检查约束会被认为是满足条件的。 因为大多数表达式在含有 NULL 操作数的时候结果都是 NULL ,所以这些约束不能阻止列值为 NULL 。要确保一个列值不为 NULL ,可以使用下面介绍的非空约束。

非空约束

非空约束只是简单地声明一列必须不能是 NULL。

比如表中的产品编号,不能为空:

CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric
);

一个非空约束总是写成一个列约束,它等效于创建一个检查约束 CHECK (column_name IS NOT NULL),但在OushuDB里,创建一个明确的非空约束效率更高。

当然,一个列可以有多个约束。只要一个接着一个写就可以了:

CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
price numeric NOT NULL CHECK (price > 0)
);

它们的顺序无所谓。顺序并不影响约束检查的顺序。

主键

一个主键约束表示可以用作表中行的唯一标识符的一个列或者一组列,它的值必须是是唯一的并且非空。

在OushuDB支持的表格式(AO,ORC,MAGMA)中,只有MAGMA表支持主键约束,而且在创建MAGMA表时,可以声明主键列,且主键约束的列里数据类型为非定长时需要将该列放置最后一列。比如:

CREATE TABLE products (
product_no integer,
name text,
price numeric,
PRIMARY KEY (product_no)
) FORMAT Magma;

主键约束也可以同时约束多个列,列名间用逗号分隔:

CREATE TABLE example (
a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
) FORMAT Magma;

最后我们强调一下,如果是MAGMA格式的表,是不支持列约束和非空约束的,但支持主键约束。

下一期我们来讲解在表创建完成后如果有修改的需求该如何操作。

以上是关于02 如何创建数据表? | OushuDB 数据库使用入门的主要内容,如果未能解决你的问题,请参考以下文章

03 如何修改数据表? | OushuDB 数据库使用入门

OushuDB 创建和管理表空间

OushuDB数据库基本用法(下)

OushuDB 产品基本介绍——表

oushudb 中 orc 格式的使用

oushudb 中 orc 格式的使用