本文档讲述了如何创建用来保存数据的数据库结构。在一个关系型数据库中,原始数据被存储在表中,因此 本章的主要工作就是解释如何创建和修改表,以及控制各种数据存储在表中的特性。讨论表如何被组织成模式,以及如何将权限分配给表。并简要介绍其他一些影响数据存储的特性,例如继承、视图、函数和触发器。
1
表基础
关系型数据库中的表与文本上的表非常类似:由行和列组成。列的数量和顺序是固定的,并且每一列拥有
一个名字。行的数目是变化的,它反映了在一个给定时刻表中存储的数据量。
SQL
并不保证表中行的顺序。
当一个表被读取时,表中的行将以非特定顺序出现,除非明确地指定需要排序。这些将在
查询
介绍。此外,
SQL
不会为行分配唯一的标识符,因此在一个表中可能会存在一些完全相同的行。这是
SQL
之下的数学模
型导致的结果,但并不是所期望的。
每一列都有一个数据类型。数据类型约束着一组可以分配给列的可能值,并且它为列中存储的数据赋予了语
义,这样它可以用于计算。例如,一个被声明为数字类型的列将不会接受任何文本串,而存储在这样一列中
的数据可以用来进行数学计算。反过来,一个被声明为字符串类型的列将接受几乎任何一种的数据,它可以
进行如字符串连接的操作但不允许进行数学计算。
KingbaseES
包括了相当多的内建数据类型,可以适用于很多应用。用户也可以定义他们自己的数据类型。大
部分内建数据类型有着显而易见的名称和语义,所以我们将它们的详细解释放在
数据类型
中。一些常用的数
据类型是:用于整数的
integer
;可以用于分数的
numeric
;用于字符串的
text
,用于日期的
date
,
用于一天内时间的
time
以及可以同时包含日期和时间的类型
timestamp
。
创建一个表,使用
CREATE TABLE
命令。在此命令中,用户需要为新表至少指定一个名字、列的名字及数据
类型。例如:
CREATE TABLE my_first_table (
first_column text,
second_column integer
);
上述命令创建了一个名为
my_first_table
的表,它拥有两个列。第一个列名为
first_column
且数据
类型为
text
;第二个列名为
second_column
且数据类型为
integer
。表和列的名字遵循
:ref:
‘
标识符
和关键词
‘
中解释的标识符语法。类型名称通常也是标识符,但是也有些例外。注意列的列表由逗号分隔并
被圆括号包围。
当然,前面的例子是非常规的。通常,为表和列赋予的名称都会表明它们存储着什么类别的数据:
CREATE TABLE products (
product_no integer,
name text,
price numeric
);
(
numeric
类型能够存储小数部分,典型的例子是金额。)
Tip:
当我们创建很多相关的表时,最好为表和列选择一致的命名模式。例如,一种选择是用单数或复数名
词作为表名,每一种都受到一些理论家支持。
一个表能够拥有的列的数据是有限的,根据列的类型,这个限制介于
250
和
1600
之间。但是,极少会定义
一个接近这个限制的表,即便有也是一个值的商榷的设计。
如果不再需要一个表,可以通过使用
DROP TABLE
命令来移除。例如:
DROP TABLE my_first_table;
DROP TABLE products;
尝试移除一个不存在的表会引起错误。然而,在
SQL
脚本中在创建每个表之前无条件地尝试移除它的做法
是很常见的,即使发生错误也会忽略之,因此这样的脚本可以在表存在和不存在时都工作得很好(如果你喜
欢,可以使用
DROP TABLE IF EXISTS
变体来防止出现错误消息,但这并非标准
SQL
)。
2
默认值
一个列可以被分配一个默认值。当一个新行被创建且没有为某些列指定值时,这些列将会被它们相应的默认
值填充。一个数据操纵命令也可以显式地要求一个列被置为它的默认值,而不需要知道这个值到底是什么
如果没有显式指定默认值,则默认值是空值。这是合理的,因为空值表示未知数据。
在一个表定义中,默认值被列在列的数据类型之后。例如:
CREATE TABLE products (
product_no integer,
name text,
price numeric DEFAULT
9.99
);
默认值可以是一个表达式,它将在任何需要插入默认值的时候被实时计算(不是表创建时)。一个常见的例
子是为一个
timestamp
列指定默认值为
CURRENT_TIMESTAMP
,这样它将得到行被插入时的时间。另一
个常见的例子是为每一行生成一个“序列号”。这在
KingbaseES
可以按照如下方式实现:
CREATE TABLE products (
product_no integer DEFAULT nextval(
'products_product_no_seq'
),
...
);
这里
nextval()
函数从一个
序列对象
序列操作函数
)。还有一种特别的速写:
CREATE TABLE products (
product_no SERIAL,
...
);