ZetCode

PostgreSQL CREATE TABLE 语句

最后修改时间:2025年3月1日

PostgreSQL 的 CREATE TABLE 语句用于在数据库中创建新表。它定义了表的结构,包括列名、数据类型和约束。本教程将通过实际示例介绍如何使用 CREATE TABLE 语句。

CREATE TABLE 语句是最重要的 SQL 命令之一,因为它为在数据库中存储和组织数据奠定了基础。

基本 CREATE TABLE 语句

此示例演示了如何创建具有基本列的简单表

basic_create_table.sql
CREATE TABLE books (
    book_id INTEGER PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    publication_year INTEGER NOT NULL
);

创建了 books 表,包含 book_idtitleauthorgenrepricepublication_year 列。

NOT NULL 约束用于确保某些列必须始终包含值,不能留空或设置为 NULL。通过为 titleauthorgenrepricepublication_year 等列指定 NOT NULL,数据库强制要求表中的每条记录都必须具有这些字段的有效值。

这有助于通过防止插入不完整的记录来维护数据完整性和一致性。例如,没有指定标题、作者、类型、价格和出版年份的书籍记录就无法创建。作为主键的 book_id 列也隐式为 NOT NULL,确保每本书都有一个唯一的标识符。

带 CHECK 约束的 CREATE TABLE

此示例演示了如何添加 CHECK 约束以强制执行数据验证

create_table_with_check.sql
CREATE TABLE books (
    book_id INTEGER PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL CHECK (price >= 0),
    publication_year INTEGER NOT NULL CHECK (publication_year BETWEEN 1900 AND 2025)
);

CHECK 约束确保 price 为非负数,publication_year 在有效范围内。

带 UNIQUE 约束的 CREATE TABLE

此示例演示了如何添加 UNIQUE 约束以确保列值唯一

create_table_with_unique.sql
CREATE TABLE books (
    book_id INTEGER PRIMARY KEY,
    title VARCHAR(100) NOT NULL UNIQUE,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    publication_year INTEGER NOT NULL
);

UNIQUE 约束确保没有两本书的标题相同。

带 DEFAULT 值的 CREATE TABLE

此示例演示了如何为列设置默认值

create_table_with_default.sql
CREATE TABLE books (
    book_id INTEGER PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL DEFAULT 'Unknown',
    price NUMERIC(5,2) NOT NULL DEFAULT 0.00,
    publication_year INTEGER NOT NULL DEFAULT 2023
);

DEFAULT 关键字为 genrepricepublication_year 列分配默认值。

带 FOREIGN KEY 的 CREATE TABLE

此示例演示了如何创建带外键的表

create_table_with_foreign_key.sql
CREATE TABLE authors (
    author_id INTEGER PRIMARY KEY,
    name VARCHAR(100) NOT NULL
);

CREATE TABLE books (
    book_id INTEGER PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author_id INTEGER REFERENCES authors(author_id),
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    publication_year INTEGER NOT NULL
);

books 表中的 author_id 列引用 authors 表中的 author_id 列。

带复合主键的 CREATE TABLE

此示例演示了如何创建带复合主键的表

create_table_with_composite_key.sql
CREATE TABLE orders (
    order_id INTEGER,
    product_id INTEGER,
    quantity INTEGER NOT NULL,
    PRIMARY KEY (order_id, product_id)
);

PRIMARY KEY 约束确保 order_idproduct_id 的组合是唯一的。

带 SERIAL 主键的 CREATE TABLE

此示例演示了如何创建带自动递增主键的表

create_table_with_serial.sql
CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    publication_year INTEGER NOT NULL
);

SERIAL 数据类型为 book_id 列自动生成唯一值。

带 TIMESTAMP 的 CREATE TABLE

此示例演示了如何创建带 TIMESTAMP 列的表

create_table_with_timestamp.sql
CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    product_id INTEGER NOT NULL,
    quantity INTEGER NOT NULL,
    order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

插入行时,order_date 列会自动填充当前时间戳。

带 JSONB 的 CREATE TABLE

此示例演示了如何创建带 JSONB 列的表

create_table_with_jsonb.sql
CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    metadata JSONB
);

metadata 列存储 JSON 数据,可以使用 PostgreSQL 的 JSON 函数对其进行查询和操作。

带 ENUM 的 CREATE TABLE

此示例演示了如何创建带 ENUM 列的表

create_table_with_enum.sql
CREATE TYPE genre_type AS ENUM ('Fiction', 'Non-Fiction', 'Sci-Fi', 'Mystery');

CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre genre_type NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    publication_year INTEGER NOT NULL
);

genre 列仅限于 genre_type 枚举中定义的值。

带 ARRAY 的 CREATE TABLE

此示例演示了如何创建带 ARRAY 列的表

create_table_with_array.sql
CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    tags TEXT[]
);

tags 列存储文本值的数组。

带 ARRAY 上 CHECK 的 CREATE TABLE

此示例演示了如何为 ARRAY 列添加 CHECK 约束

create_table_with_array_check.sql
CREATE TABLE books (
    book_id SERIAL PRIMARY KEY,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL,
    price NUMERIC(5,2) NOT NULL,
    tags TEXT[] CHECK (array_length(tags, 1) <= 5)
);

CHECK 约束确保 tags 数组的元素不超过 5 个。

带 PARTITIONING 的 CREATE TABLE

此示例演示了如何创建分区表

create_table_with_partitioning.sql
CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    product_id INTEGER NOT NULL,
    quantity INTEGER NOT NULL,
    order_date DATE NOT NULL
) PARTITION BY RANGE (order_date);

CREATE TABLE orders_2023 PARTITION OF orders
    FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');

CREATE TABLE orders_2024 PARTITION OF orders
    FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

orders 表按 order_date 列进行分区,并为每一年创建单独的分区。

带 INHERITANCE 的 CREATE TABLE

此示例演示了如何创建继承自另一个表的表

create_table_with_inheritance.sql
CREATE TABLE products (
    product_id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    price NUMERIC(5,2) NOT NULL
);

CREATE TABLE books (
    author VARCHAR(100) NOT NULL,
    genre VARCHAR(50) NOT NULL
) INHERITS (products);

books 表继承了 products 表的所有列,并添加了额外的列。

带 EXCLUDE 约束的 CREATE TABLE

此示例演示了如何创建带 EXCLUDE 约束的表

create_table_with_exclude.sql
CREATE TABLE reservations (
    reservation_id SERIAL PRIMARY KEY,
    room_id INTEGER NOT NULL,
    start_date DATE NOT NULL,
    end_date DATE NOT NULL,
    EXCLUDE USING GIST (
        room_id WITH =,
        daterange(start_date, end_date) WITH &&
    )
);

EXCLUDE 约束确保同一房间的两个预订在日期范围上不重叠。

使用 CREATE TABLE 的最佳实践

来源

PostgreSQL 文档

在本文中,我们通过实际示例和最佳实践,探讨了如何使用 PostgreSQL CREATE TABLE 语句来创建表。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Python 教程