关系型数据库中的表非常类似于纸质表格:它由行和列组成。列的数量和排列顺序是固定的,并且每一列都拥有唯一的名称。行的数量则是动态可变的——它反映了在给定时间点所存储的数据量。 SQL 不对表中各行的物理存储顺序做任何硬性保证。当读取数据表时,各行数据将以未定义的随意次序返回,除非在查询时显式指定了排序规则(详见 Chapter 7)。 此外,SQL 默认不会为数据行自动分配全局唯一标识,因此表中可能存在多条内容完全相同的数据行。这是 SQL 底层数学关系模型的结果,但在实际业务中这通常是不希望看到的。本章稍后将介绍如何解决这一唯一性问题。
每一个字段列都拥有明确的数据类型。数据类型严格约束了可以存入该列的合法候选值集合,并赋予存储数据以特定的计算语义。例如,声明为数值类型的字段不会接受任意文本字符串,且存入其中的数值可直接用于数学运算。与此相反,声明为字符串类型的字段几乎可以接受任意形式的文本输入,但不能直接用于数学加减运算(尽管可以执行字符串拼接等操作)。
PostgreSQL 提供了大量开箱即用的系统内置数据类型,能够满足绝大多数业务场景。用户也可以按需注册自定义数据类型。大多数内置类型具有极其直观的命名与语义,我们在 Chapter 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。表名和列名遵循 Section 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 变体安全跳过报错提示。
如需对已存在的表结构进行动态调整,请参阅本章后续的 Section 5.7。
利用目前介绍的语法已能创建功能完整的数据表。本章其余部分将进一步探讨如何为表定义引入更多高级能力,以确保数据的完整性、安全性与易用性。如果你急于向表中填充数据,可以先跳过本章其余内容前往 Chapter 6 查阅数据操作,之后再行返回。