青少年编程与数学 02-007 PostgreSQL数据库应用 07课题、表的操作
课题摘要:本课题详细介绍了PostgreSQL中表的操作,包括创建、数据类型、约束、插入、查询、更新、删除数据,以及修改表结构和索引。表是PostgreSQL中存储数据的基本结构,由行和列组成,每列都有特定的数据类型。创建表时可以定义列名、数据类型和约束条件,如主键、外键、唯一性、检查等。PostgreSQL支持多种数据类型,包括数值、字符串、日期时间、布尔、二进制、复合类型、枚举、网络地址、UUID、几何和JSON类型。选择合适的数据类型对数据库性能、存储效率和数据完整性至关重要。此外,还讨论了列的命名规则,包括标识符长度、字符、大小写敏感性和避免关键字。最后,提供了一个表定义示例,展示了如何在PostgreSQL中创建一个等效的表,包括数据类型和函数的对应关系。
一、数据库表(Table)
在PostgreSQL中,数据库表是存储数据的基本结构,它们由行(rows)和列(columns)组成,每列都有自己的数据类型。以下是关于PostgreSQL中数据库表的一些详细说明:
表的创建
创建表时,你需要定义列名和数据类型,还可以指定约束条件,如主键、外键、唯一性、检查等。
CREATE TABLE table_name (
column1 data_type PRIMARY KEY,
column2 data_type NOT NULL,
column3 data_type UNIQUE,
column4 data_type CHECK (column4 > 0),
column5 data_type REFERENCES other_table(other_column)
);
表的数据类型
PostgreSQL支持多种数据类型,包括:
- 数值类型:整型(如
INTEGER
、BIGINT
)、浮点型(如FLOAT
、REAL
)、小数型(如NUMERIC
、DECIMAL
)。 - 字符串类型:字符型(如
CHARACTER
、VARCHAR
)、文本型(如TEXT
)。 - 日期和时间类型:
DATE
、TIME
、TIMESTAMP
、TIMESTAMP WITH TIME ZONE
。 - 布尔类型:
BOOLEAN
。 - 二进制类型:
BYTEA
。 - 复合类型:数组(如
INTEGER[]
)、复合类型(如POINT
、LINE
、LSEG
)。 - 枚举类型:
ENUM
。 - 网络类型:
INET
、CIDR
。 - UUID类型:
UUID
。 - 几何类型:
GEOMETRY
。
表的约束
约束用于保证数据的完整性和准确性:
- 主键(PRIMARY KEY):表中每一行的唯一标识符。
- 外键(FOREIGN KEY):用于建立两个表之间的关系,保证引用的数据完整性。
- 唯一性(UNIQUE):确保列中的所有值都是唯一的。
- 检查(CHECK):确保列中的值满足特定的条件。
- 非空(NOT NULL):确保列不能存储空值。
表的操作
-
插入数据(INSERT):
INSERT INTO table_name (column1, column2) VALUES (value1, value2);
-
查询数据(SELECT):
SELECT * FROM table_name WHERE condition;
-
更新数据(UPDATE):
UPDATE table_name SET column1 = value1 WHERE condition;
-
删除数据(DELETE):
DELETE FROM table_name WHERE condition;
表的修改
-
添加列(ADD COLUMN):
ALTER TABLE table_name ADD COLUMN new_column data_type;
-
删除列(DROP COLUMN):
ALTER TABLE table_name DROP COLUMN column_name;
-
修改列(ALTER COLUMN):
ALTER TABLE table_name ALTER COLUMN column_name TYPE new_data_type;
表的索引和性能
-
创建索引(CREATE INDEX):
CREATE INDEX index_name ON table_name (column_name);
-
删除索引(DROP INDEX):
DROP INDEX index_name;
索引可以显著提高查询性能,尤其是在大型表中。
表的继承
PostgreSQL支持表继承,允许一个表继承另一个表的结构:
- 创建继承表:
CREATE TABLE child_table (additional_column data_type) INHERITS (parent_table);
表的分区
PostgreSQL支持表分区,可以将大型表的数据分散存储在不同的分区中:
- 创建分区表:
CREATE TABLE partitioned_table ( column1 data_type, column2 data_type ) PARTITION BY RANGE (column1);
这些是PostgreSQL中数据库表的基本组成和操作。通过这些功能,你可以有效地组织和管理数据,确保数据的完整性和安全性。
二、创建表
在PostgreSQL中创建表是一个直接的过程,涉及到定义表的结构,包括列名、数据类型以及约束条件。以下是创建表的基本步骤和示例:
1. 使用CREATE TABLE语句
最基本的创建表的SQL语句是CREATE TABLE
。你可以指定表名和列,以及每个列的数据类型。
CREATE TABLE table_name (
column1 data_type1,
column2 data_type2,
column3 data_type3,
...
);
2. 定义列的数据类型
为表中的每个列指定一个数据类型。PostgreSQL支持多种数据类型,包括数值型、字符串型、日期时间型等。
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
birth_date DATE,
hire_date DATE
);
在这个例子中,id
列被定义为自增的整数(SERIAL
),并且是表的主键。first_name
和last_name
列被定义为最大长度为50的字符串,并且不允许为空(NOT NULL
)。
3. 添加约束条件
在创建表时,可以定义各种约束条件来保证数据的完整性和准确性,如主键、外键、唯一性、检查等。
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id),
order_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
order_total NUMERIC(10, 2) CHECK (order_total >= 0)
);
在这个例子中,order_id
是主键,customer_id
是外键,它引用了customers
表的id
列。order_date
列默认值为当前时间戳,order_total
列必须大于或等于0。
4. 在psql中执行CREATE TABLE
如果你使用的是psql命令行工具,可以直接在psql会话中输入上述CREATE TABLE
语句。
5. 在pgAdmin中执行CREATE TABLE
如果你使用的是pgAdmin这样的图形界面工具,可以按照以下步骤创建表:
- 连接到你的PostgreSQL服务器。
- 在pgAdmin的浏览器面板中,找到你想要创建表的数据库。
- 右键点击数据库,选择“Create” -> “Table”。
- 在打开的表创建向导中,输入表名和列的详细信息,包括数据类型和约束条件。
- 完成向导,创建表。
注意事项
- 创建表之前,确保你有足够的权限在指定的数据库中创建表。
- 在创建表时仔细考虑数据类型和约束条件,这有助于保证数据的完整性和性能。
- 创建表后,你可以使用
\d
或\d+ table_name
命令在psql中查看表的结构。
通过这些步骤,你可以在PostgreSQL中创建表来存储和管理数据。
三、列(字段)的命名规则
在PostgreSQL中,列(字段)的命名遵循一定的规则和最佳实践,以确保数据库的一致性和可维护性。以下是列命名的主要规则和建议:
基本规则
-
标识符长度:
- PostgreSQL的标识符(包括列名)最长可以达到63个字符。超过这个长度的标识符会导致错误。
-
标识符字符:
- 标识符必须以字母(a-z、A-Z、非拉丁字母)或下划线(_)开头。
- 后续字符可以是字母、下划线、数字(0-9)或美元符号($)。
-
大小写敏感性:
- PostgreSQL中未加引号的标识符默认是大小写不敏感的,这意味着
column_name
和Column_Name
会被视为同一个标识符。 - 如果列名包含特殊字符或要使其大小写敏感,可以使用双引号括起来,如
"Column Name"
。
- PostgreSQL中未加引号的标识符默认是大小写不敏感的,这意味着
-
避免关键字:
- 尽管可以使用SQL关键字作为列名(如
select
、update
等),但最好避免这样做,因为它会使SQL语句更复杂,需要使用反引号(`)或双引号括起来。
- 尽管可以使用SQL关键字作为列名(如
最佳实践
-
简洁明了:
- 列名应该简洁且具有描述性,能够清楚地表明列所包含的数据类型或用途。
-
使用下划线分隔:
- 多个单词组成的列名应使用下划线(_)分隔,如
first_name
、order_date
。
- 多个单词组成的列名应使用下划线(_)分隔,如
-
避免使用保留字:
- 尽管可以使用保留字作为列名,但最好避免这样做,以免在编写SQL语句时产生混淆。
-
避免使用特殊字符:
- 避免在列名中使用特殊字符,如空格、连字符(-)、点(.)等,这些字符会使SQL语句更复杂。
-
避免使用数字开头:
- 不要以数字开头命名列,因为这可能会导致解析SQL语句时出现问题。
-
避免使用保留字和函数名:
- 避免使用SQL保留字和现有函数名作为列名,以免在编写查询时产生混淆。
-
统一命名风格:
- 在整个数据库中保持一致的命名风格,这有助于提高数据库的可读性和可维护性。
-
考虑国际化:
- 如果数据库将被多语言用户访问,考虑列名的国际化问题,避免使用特定语言的词汇。
-
避免过长的列名:
- 尽管PostgreSQL允许长达63个字符的列名,但过长的列名可能会使SQL语句难以阅读和维护。
通过遵循这些规则和最佳实践,你可以确保列名的一致性、可读性和可维护性,从而提高数据库的整体质量。
四、列的数据类型
PostgreSQL 提供了丰富的数据类型,允许你根据数据的特点和需求选择合适的类型。以下是一些常用的列数据类型及其详解:
数值类型
-
整数类型:
SMALLINT
:16位整数,范围从-32768到32767。INTEGER
:32位整数,范围从-2147483648到2147483647。BIGINT
:64位整数,范围从-9223372036854775808到9223372036854775807。
-
浮点数类型:
REAL
:单精度浮点数,通常有7位有效数字的精度。DOUBLE PRECISION
:双精度浮点数,通常有15位有效数字的精度。
-
小数类型:
NUMERIC
:精确的十进制数,可以指定精度(例如NUMERIC(10,2)
表示总共10位数字,其中2位是小数)。DECIMAL
:与NUMERIC
类似,但不允许指定精度。
-
序列类型:
SERIAL
:自动增长的整数,用于主键。BIGSERIAL
:自动增长的64位整数。
字符类型
-
字符串类型:
CHARACTER
或CHAR
:固定长度的字符串,长度可以指定(例如CHAR(5)
)。CHARACTER VARYING
或VARCHAR
:可变长度的字符串,长度可以指定(例如VARCHAR(255)
)。
-
文本类型:
TEXT
:用于存储大量文本,没有长度限制。
日期和时间类型
-
日期类型:
DATE
:存储日期,格式为YYYY-MM-DD
。
-
时间类型:
TIME
:存储时间,格式为HH:MM:SS
。TIME WITH TIME ZONE
或TIMETZ
:带时区的时间。
-
时间戳类型:
TIMESTAMP
:存储日期和时间,格式为YYYY-MM-DD HH:MM:SS
。TIMESTAMP WITH TIME ZONE
或TIMESTAMPTZ
:带时区的日期和时间。
布尔类型
BOOLEAN
:存储布尔值,TRUE
或FALSE
。
二进制类型
BYTEA
:用于存储二进制数据。
复合类型
-
数组类型:
- 任何基本类型都可以定义为数组类型,例如
INTEGER[]
。
- 任何基本类型都可以定义为数组类型,例如
-
枚举类型:
ENUM
:枚举类型,用于存储预定义的值列表。
几何类型
GEOMETRY
:几何数据类型,用于存储几何对象。
网络地址类型
INET
:存储IPv4或IPv6地址。CIDR
:存储IPv4或IPv6地址和子网掩码。
UUID类型
UUID
:存储通用唯一识别码。
JSON类型
JSON
:存储JSON对象。JSONB
:存储二进制JSON对象,支持索引和更有效的查询。
XML类型
XML
:存储XML数据。
选择合适的数据类型对于数据库性能、存储效率和数据完整性至关重要。在定义表结构时,应根据数据的特性和查询需求仔细选择最合适的数据类型。
五、选择合适的数据类型
在PostgreSQL中为数据选择合适的数据类型是一个重要的决策,它会影响到数据库的性能、存储效率和数据完整性。以下是一些指导性规则,帮助你为不同类型的数据选择合适的数据类型:
1. 了解数据的特性
-
数值数据:
- 如果数据是整数,选择
INTEGER
。如果数值非常大或非常小,选择BIGINT
。 - 如果数据是小数,根据精度需求选择
NUMERIC
或DECIMAL
,并指定小数点后的位数。 - 如果数据是浮点数,根据精度需求选择
REAL
或DOUBLE PRECISION
。
- 如果数据是整数,选择
-
字符串数据:
- 对于较短的、固定长度的字符串,使用
CHAR
。 - 对于长度可变的字符串,使用
VARCHAR
,并指定最大长度。 - 对于长文本,如文章或评论,使用
TEXT
。
- 对于较短的、固定长度的字符串,使用
-
日期和时间数据:
- 对于日期,使用
DATE
。 - 对于时间,使用
TIME
或TIME WITH TIME ZONE
。 - 对于日期和时间,使用
TIMESTAMP
或TIMESTAMP WITH TIME ZONE
。
- 对于日期,使用
-
布尔数据:
- 对于真/假值,使用
BOOLEAN
。
- 对于真/假值,使用
2. 考虑数据的范围和精度
-
范围:
- 确保选择的数据类型能够覆盖数据的值范围。例如,使用
SMALLINT
而不是INTEGER
,如果数据值不会超过SMALLINT
的范围。
- 确保选择的数据类型能够覆盖数据的值范围。例如,使用
-
精度:
- 对于需要精确计算的数值,使用
NUMERIC
或DECIMAL
。对于需要快速计算但不要求极端精度的数值,使用FLOAT
或DOUBLE PRECISION
。
- 对于需要精确计算的数值,使用
3. 存储需求
-
存储大小:
- 考虑存储空间的需求。例如,
VARCHAR
只存储必要的空间加上一个长度前缀,而CHAR
总是占用固定空间。
- 考虑存储空间的需求。例如,
-
稀疏数据:
- 对于大部分值为空的情况,考虑使用
NULL
或适当的默认值来减少存储需求。
- 对于大部分值为空的情况,考虑使用
4. 性能要求
-
索引和查询:
- 考虑是否需要在该列上创建索引。某些数据类型(如
TEXT
和JSONB
)在索引时可能需要特定的考虑。
- 考虑是否需要在该列上创建索引。某些数据类型(如
-
列的默认值:
- 如果列经常有一个默认值,考虑在创建表时指定默认值,以减少更新操作的开销。
5. 兼容性和可维护性
-
兼容性:
- 如果数据需要与其他系统交互,考虑数据类型的兼容性。
-
可维护性:
- 选择易于理解和维护的数据类型,避免过度复杂的数据类型,除非它们提供了显著的优势。
6. 特殊数据类型
-
数组:
- 如果需要存储多个值,考虑使用数组类型,如
INTEGER[]
。
- 如果需要存储多个值,考虑使用数组类型,如
-
几何和地理空间数据:
- 对于地理空间数据,使用
GEOMETRY
或专门的地理空间扩展。
- 对于地理空间数据,使用
-
JSON 和 XML:
- 对于半结构化数据,使用
JSON
或JSONB
(推荐JSONB
,因为它支持索引)。
- 对于半结构化数据,使用
通过综合考虑这些因素,你可以为PostgreSQL中的列选择最合适的数据类型,从而优化数据库的性能和存储效率。
六、表定义示例
在 PostgreSQL 中,数据类型和 SQL Server 有所不同,因此不能直接使用 T-SQL 中的数据类型,如 NVARCHAR
、BIT
、VARBINARY
和 DATETIME2
。下面是根据您提供的 SQL Server 表定义,转换为 PostgreSQL 的等效表定义:
CREATE TABLE ProductCatalog (
ProductID SERIAL PRIMARY KEY, -- 主键,自增长整数类型
ProductName VARCHAR(100) NOT NULL, -- 产品名称,可变长度的字符数据
ProductDescription TEXT, -- 产品描述,最大长度的文本数据
Price NUMERIC(10, 2) NOT NULL, -- 价格,十进制类型,最多8位数字,2位小数
StockQuantity INTEGER, -- 库存数量,整数类型
IsDiscontinued BOOLEAN, -- 是否已停产,布尔类型
ProductImage BYTEA, -- 产品图片,可变长度的二进制数据
CreatedDate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建日期,高精度日期和时间类型,默认为当前时间
ModifiedDate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 修改日期,高精度日期和时间类型,默认为当前时间
ShelfLife INTERVAL MONTH -- 保质期,以月为单位,时间间隔类型
);
以下是 PostgreSQL 中使用的等效数据类型和函数的解释:
-
SERIAL:PostgreSQL 中的自增长整数类型,类似于 SQL Server 中的
INT IDENTITY
。 -
VARCHAR(100):可变长度的字符数据,最大长度为 100。
-
TEXT:用于存储大量文本的数据类型,没有长度限制。
-
NUMERIC(10, 2):十进制类型,最多8位数字,2位小数。
-
INTEGER:整数类型。
-
BOOLEAN:布尔类型,存储
TRUE
或FALSE
。 -
BYTEA:用于存储二进制数据。
-
TIMESTAMP WITH TIME ZONE:高精度日期和时间类型,带时区。
-
INTERVAL:时间间隔类型,用于存储时间段,如
INTERVAL '1 month'
。
请注意,GETDATE()
在 SQL Server 中用于获取当前日期和时间,而在 PostgreSQL 中对应的函数是 CURRENT_TIMESTAMP
。此外,NVARCHAR(MAX)
在 PostgreSQL 中没有直接等效,但可以使用 TEXT
类型,因为它可以存储任意长度的 Unicode 文本。VARBINARY(MAX)
在 PostgreSQL 中被 BYTEA
类型替代。MONTH
类型在 PostgreSQL 中没有直接等效,因此使用 INTERVAL
类型来表示时间段。