16 CREATE TABLE
创建表、检查其列,并了解临时表和不记录 WAL 的表。
PostgreSQL 通过表存储数据。CREATE TABLE 通过列出列及其数据类型来定义新表。默认值、约束、索引和外键都可以在创建时添加,但最小的表只需要一个名称和列清单。本课保持简洁;约束会在专门的课程中介绍。
本章要点
- 使用
CREATE TABLE定义表 - 为每列选择数据类型(
integer、text等) - 使用
DROP TABLE IF EXISTS使建表脚本幂等 - 检查
public模式中的表 TEMP TABLE、普通表和UNLOGGED TABLE的区别
示例
fruits 有两列:id(32 位有符号整数)和 name(变长文本)。CREATE TABLE 中列的顺序,就是行的物理存储顺序——为了提高宽表的存储效率,应将定长列放在一起。对于小表,这并不重要。
DROP TABLE IF EXISTS 只在表存在时删除表;如果没有 IF EXISTS,该语句在全新的数据库中就会报错。将它与 CREATE TABLE 结合后,在迭代数据库模式的过程中可以安全地反复运行脚本。当然,在生产环境中不要盲目删除表——请使用迁移。
有几种 CREATE TABLE 的变体值得了解:
CREATE TEMP TABLE(或CREATE TEMPORARY TABLE)创建的表只在当前会话中存在,并会自动删除。CREATE UNLOGGED TABLE不写入预写式日志——写入更快,但服务器崩溃时内容会被清空。适合存放可重建的派生数据或暂存数据。CREATE TABLE ... (LIKE other_table INCLUDING ALL)会复制另一个表的模式。CREATE TABLE ... AS SELECT ...会根据查询创建并填充一个表(称为 CTAS)。
运行示例
运行方式:
常见陷阱
- 不要因为在 MySQL 中学到
varchar(255)就选择它:在 PostgreSQL 中,text和varchar(n)的性能相同。除非你明确需要长度上限,否则使用text。 - 忘记在本不应为空的列上添加
NOT NULL——以后可以再加,但从一开始就正确设置更容易。 - 将列命名为
user、order、select——这些都是保留字。可以改名(user_id、placed_at),也可以加引号("user"),但这样会一直带来麻烦。
提示
值得记住的标准列类型:integer(32 位)、bigint(64 位)、text、boolean、date、timestamp with time zone(几乎总是优先于 timestamp)、用于精确小数的 numeric(p,s),以及用于不透明 ID 的 uuid。每种类型都有专门的课程。
动手练习
添加第三列,例如 price numeric(10,2),然后再次运行脚本。接着将 integer 改为 bigint,再运行一次。在交互式 psql 会话中使用 \d fruits 检查。
下载
SQL 文件:create-table.sql · 全部示例文件 · 准备工作