5.1. 表基础知识#
关系数据库中的表非常像纸上的表格:它由行和列组成。列的数量和顺序是固定的,并且每列都有一个名称。行数是可变的——它反映了在给定时刻存储的数据量。SQL 不会对表中行的顺序做出任何保证。读取表时,除非明确请求排序,否则行将按未指定顺序显示。这在第 7 章中进行了介绍。此外,SQL 不会为行分配唯一标识符,因此表中可能有多个完全相同行。这是 SQL 底层数学模型的结果,但通常不可取。在本章后面,我们将了解如何处理此问题。
每列都有一个数据类型。数据类型限制了可以分配给一列的可能值集,并为存储在列中的数据分配语义,以便可用于计算。例如,声明为数字类型的列不会接受任意文本字符串,并且存储在该列中的数据可用于数学计算。相比之下,声明为字符类型的一列将接受几乎任何类型的数据,但它不适用于数学计算,尽管可以使用其他操作(例如字符串连接)。
PostgreSQL包含一组适合许多应用程序的内置数据类型。用户还可以定义自己的数据类型。大多数内置数据类型都有显而易见的名字和语义,因此我们推迟详细解释到第 8 章。一些常用的数据类型包括用于整数的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
。表和列名称遵循第 4.1.1 节中解释的标识符语法。类型名称通常也是标识符,但有一些例外。请注意,列列表用逗号分隔并用括号括起来。
当然,前面的示例非常牵强。通常,您会为您的表和列提供表示它们存储哪种类型数据的名称。因此,让我们看一个更实际的示例
CREATE TABLE products (
product_no integer,
name text,
price numeric
);
(numeric
类型可以存储小数部分,这通常是货币金额的典型特征。)
提示
当您创建许多相互关联的表时,明智的做法是为表和列选择一致的命名模式。例如,可以选择使用表名的单数或复数名词,而这两种形式都受到一些理论家的青睐。
对于一个表可以包含的列数目有一个限制。根据列类型,它在 250 到 1600 之间。但是,定义一个具有接近这么多列的表是非常不寻常的,并且通常是一个有问题的设计。
如果你不再需要一个表,你可以使用DROP TABLE命令来删除它。例如
DROP TABLE my_first_table;
DROP TABLE products;
尝试删除一个不存在的表是一个错误。然而,在 SQL 脚本文件中,在创建表之前无条件地尝试删除每个表,忽略任何错误消息是很常见的,这样无论表是否存在,脚本都可以正常工作。(如果你愿意,你可以使用DROP TABLE IF EXISTS
变体来避免错误消息,但这并不是标准 SQL。)
如果你需要修改一个已经存在的表,请参阅本章后面的第 5.6 节。
使用到目前为止讨论的工具,你可以创建功能齐全的表。本章的其余部分涉及向表定义中添加特性,以确保数据完整性、安全性或便利性。如果你现在急于用数据填充你的表,你可以跳到第 6 章,稍后再阅读本章的其余部分。