关系数据库中的表就像纸上的表格一样:它由行和列组成。列的数量和顺序是固定的,并且每列都有一个名称。行的数量是可变的——它反映了在给定时刻存储了多少数据。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.7 节。
通过迄今为止讨论的工具,您可以创建功能齐全的表。本章的其余部分将关注向表定义添加功能,以确保数据完整性、安全性或便利性。如果您急于立即填充表,可以跳到第 6 章,稍后再阅读本章的其余部分。
如果您在文档中发现任何不正确、与您在该功能上的体验不符或需要进一步澄清的内容,请使用此表单来报告文档问题。