PostgreSQL 是一个功能强大的开源关系型数据库管理系统 (RDBMS),支持标准的 SQL 语法,并扩展了许多功能强大的操作语法.
数据类型
数值类型
数据类型 | 描述 | 存储大小 | 示例值 |
---|---|---|---|
SMALLINT |
小范围整数,范围:-32,768 到 32,767 | 2 字节 | -123 |
INTEGER 或 INT |
中范围整数,范围:-2,147,483,648 到 2,147,483,647 | 4 字节 | 12345 |
BIGINT |
大范围整数,范围:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 8 字节 | 12345678901234 |
NUMERIC(p, s) 或 DECIMAL(p, s) |
精确的数字,p 是总位数,s 是小数点后位数 |
可变长 | 1234.56 |
REAL 或 FLOAT4 |
单精度浮点数,范围:6 位小数精度 | 4 字节 | 1.23 |
DOUBLE PRECISION 或 FLOAT8 |
双精度浮点数,范围:15 位小数精度 | 8 字节 | 123.45678 |
SERIAL |
自动递增整数,等同于 INTEGER + 自增 |
4 字节 | 1, 2, 3... |
BIGSERIAL |
自动递增整数,等同于 BIGINT + 自增 |
8 字节 | 1, 2, 3... |
字符类型
数据类型 | 描述 | 存储大小 | 示例值 |
---|---|---|---|
CHAR(n) 或 CHARACTER(n) |
固定长度字符串,不足位数会用空格补齐 | n 字节 | 'abc ' |
VARCHAR(n) 或 CHARACTER VARYING(n) |
可变长度字符串,最多 n 个字符 |
实际长度 + 1 字节 | 'abc' |
TEXT |
不限长度的字符串 | 可变长 | 'Hello, world!' |
说明:
<1>:CHAR(n)
固定长度,适合存储固定格式的字符串。
<2>:VARCHAR(n)
是常用的可变长度类型。
<3>:TEXT
用于存储长文本。
3.
布尔类型
数据类型 | 描述 | 存储大小 | 示例值 |
---|---|---|---|
BOOLEAN | 布尔值,TRUE 、FALSE 或 NULL |
1 字节 | TRUE |
日期和时间类型
数据类型 | 描述 | 存储大小 | 示例值 |
---|---|---|---|
DATE |
日期(不包含时间) | 4 字节 | '2025-01-06' |
TIME [WITHOUT TIME ZONE] |
时间(不包含日期) | 8 字节 | '12:30:00' |
TIMESTAMP [WITHOUT TIME ZONE] |
日期和时间 | 8 字节 | '2025-01-06 12:30:00' |
TIMESTAMP WITH TIME ZONE |
带时区的日期和时间 | 8 字节 | '2025-01-06 12:30:00+08' |
INTERVAL |
时间间隔 | 16 字节 | '1 year 2 months' |
几何类型
数据类型 | 描述 | 示例值 |
---|---|---|
POINT |
平面中的一个点 | '(1.5, 2.5)' |
LINE |
无限长的直线 | '{1, -1, 0}' |
LSEG |
有限线段 | '(1.5, 2.5), (3.5, 4.5)' |
BOX |
矩形框 | '((1, 2), (3, 4))' |
PATH |
路径(开或闭) | '((1, 1), (2, 2), (3, 3))' |
POLYGON |
多边形 | '((1, 1), (2, 2), (3, 3))' |
CIRCLE |
圆形 | '<(1, 1), 5>' |
几何类型用于存储点、线、圆等几何信息
6.
数组类型
数据类型 | 描述 | 示例值 |
---|---|---|
INTEGER[] |
整数数组 | {1, 2, 3} |
TEXT[] |
文本数组 | {'hello', 'world'} |
JSON和JSONB类型
数据类型 | 描述 | 示例值 |
---|---|---|
JSON |
原始 JSON 格式,保留格式 | '{"key": "value"}' |
JSONB |
二进制存储的 JSON,查询更快 | '{"key": "value"}' |
UUID类型
数据类型 | 描述 | 示例值 |
---|---|---|
UUID |
通用唯一标识符 (128 位) | 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11' |
XML类型
数据类型 | 描述 | 示例值 |
---|---|---|
XML |
XML 数据 | '<note><to>Tove</to></note>' |
##### 枚举类型
枚举类型允许定义一组固定值。
```bash
CREATE TYPE mood AS ENUM ('happy', 'sad', 'neutral');
```
使用:
```bash
CREATE TABLE person (
name TEXT,
current_mood mood
);
```
##### 范围类型
| 数据类型 | 描述 | 示例值 |
|-------------|-----------|--------------------------------------------------------|
| `INT4RANGE` | 整数范围 | `[1,10)` |
| `NUMRANGE` | 数字范围 | `[1.5,2.5)` |
| `TSRANGE` | 不带时区的时间范围 | `['2023-01-01', '2023-12-31')` |
| `TSTZRANGE` | 带时区的时间范围 | `['2023-01-01 00:00:00+00', '2023-12-31 23:59:59+00')` |
数据操作
创建数据库和用户
bash
// 创建数据库
CREATE DATABASE database_name;
// 删除数据库
DROP DATABASE database_name;
// 创建用户
CREATE USER user_name WITH PASSWORD 'password';
// 为用户授予权限
GRANT ALL PRIVILEGES ON DATABASE database_name TO user_name;
数据定义语言 (DDL)
bash
// 创建表
CREATE TABLE table_name (
column_name1 data_type [constraints],
column_name2 data_type [constraints],
...
);
// 添加列
ALTER TABLE table_name ADD COLUMN column_name data_type;
// 修改列
ALTER TABLE table_name ALTER COLUMN column_name TYPE new_data_type;
// 删除列
ALTER TABLE table_name DROP COLUMN column_name;
// 删除表
DROP TABLE table_name;
数据操作语言 (DML)
基本查询:
bash
// 插入数据
INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);
// 查询数据
SELECT column1, column2 FROM table_name WHERE condition;
SELECT * FROM table_name;
// 更新数据
UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;
// 删除数据
DELETE FROM table_name WHERE condition;
扩展查询:
bash
// 分组查询
SELECT column1, COUNT(*) FROM table_name GROUP BY column1 HAVING COUNT(*) > 1;
// 连接查询(JOIN)
内连接:
SELECT a.column1, b.column2
FROM table1 a
INNER JOIN table2 b
ON a.common_column = b.common_column;
左连接:
SELECT a.column1, b.column2
FROM table1 a
LEFT JOIN table2 b
ON a.common_column = b.common_column;
右连接:
SELECT a.column1, b.column2
FROM table1 a
RIGHT JOIN table2 b
ON a.common_column = b.common_column;
// 子查询
SELECT column1
FROM table_name
WHERE column2 IN (
SELECT column2
FROM another_table
WHERE condition
);
PostgreSQL特性
PostgreSQL提供了几种丰富的数据类型,有一些特定的用法。
数组
在 PostgreSQL 中,数组是一种非常强大的数据类型,它可以存储一组同类型的值(例如整数、文本等),以下是关于数组的详细用法。
创建数组字段:
bash
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT,
favorite_numbers INTEGER[], -- 整数数组字段
favorite_colors TEXT[] -- 文本数组字段
);
插入数组数据:
bash
INSERT INTO users (name, favorite_numbers, favorite_colors)
VALUES ('Alice', '{1, 2, 3}', '{"red", "blue", "green"}');
查询数组数据:
bash
// 查询 favorite_numbers 包含 2 的用户
SELECT name FROM users WHERE 2 = ANY (favorite_numbers);
// 查询数组是否包含所有指定值
-- 查询 favorite_numbers 包含所有值 {1, 2} 的用户
SELECT name FROM users WHERE favorite_numbers @> '{1, 2, 4}';
// 查询数组是否为另一个数组的子集
-- 查询 favorite_numbers 是 {1, 2, 3} 的子集的用户
SELECT name FROM users WHERE favorite_numbers <@ '{1, 2, 3}';
更新数组:
bash
// 向 Alice 的 favorite_numbers 中追加一个新值 40
UPDATE users SET favorite_numbers = favorite_numbers || 40 WHERE name = 'Alice';
// 将 Alice 的 favorite_numbers 的第 1 个元素更新为 100
UPDATE users SET favorite_numbers[1] = 100 WHERE name = 'Alice';
删除数据中元素:
bash
UPDATE users SET favorite_numbers = array_remove(favorite_numbers, '40') WHERE name = 'Alice';
PostgreSQL 提供了许多用于数组操作的内置函数和操作符:
操作符/函数 | 描述 | 示例 |
---|---|---|
ARRAY[...] |
创建数组 | SELECT ARRAY[1, 2, 3]; |
ANY (array) |
判断值是否在数组中 | SELECT 2 = ANY('{1, 2, 3}'); |
@> |
数组包含另一个数组 | SELECT '{1, 2, 3}'::int[] @> '{1, 2}'; |
<@ |
数组是另一个数组的子集 | SELECT '{1, 2}'::int[] <@ '{1, 2, 3}'; |
array_length(array, n) |
获取数组的长度 | SELECT array_length('{1, 2, 3}', 1); |
unnest(array) |
将数组展开为行 | SELECT unnest('{1, 2, 3}'::int[]); |
array_remove | 删除数组中某个值 | UPDATE users SET favorite_numbers = array_remove(favorite_numbers, '40') |
JSON和JSONB
在 PostgreSQL 中,JSON
和 JSONB
是两种用于存储 JSON 数据的列类型。它们功能强大,广泛用于现代应用中。
JSON 与 JSONB 的主要区别
-
存储方式:
JSON
:以文本格式存储数据,存储和检索时保持输入顺序。JSONB
:以二进制格式存储,经过解析和去重处理(键的顺序不保存)。
-
性能:
JSON
:适合读取为原始 JSON 字符串,查询效率较低。JSONB
:支持索引,查询和操作效率更高。
-
使用场景:
JSON
:需要保持原始 JSON 数据格式(如调试或日志记录)。JSONB
:需要高效查询、过滤或处理 JSON 数据。
创建表:
bash
CREATE TABLE example (
id SERIAL PRIMARY KEY,
data JSON, -- 存储为 JSON 格式
data_b JSONB -- 存储为 JSONB 格式
);
插入数据:
bash
INSERT INTO example (data, data_b) VALUES
('{"name": "Alice", "age": 25, "tags": ["developer", "gamer"]}',
'{"name": "Alice", "age": 25, "tags": ["developer", "gamer"]}');
查询数据:
- 访问 JSON 数据的字段
使用 ->
和 ->>
操作符:
->
:提取字段为 JSON 类型。->>
:提取字段为文本类型。
bash
-- 提取 JSON 对象的字段
SELECT data->'name' AS name_json, data_b->'name' AS name_jsonb FROM example;
-- 提取字段值为文本
SELECT data->>'name' AS name_text, data_b->>'name' AS name_text FROM example;
2、查询嵌套数据
bash
-- 提取嵌套 JSON 对象中的字段值
SELECT data->'tags'->>0 AS first_tag, data_b->'tags'->>0 AS first_tag FROM example;
3、JSONB函数和操作符
-
检查字段是否存
bash-- 检查 JSONB 中是否包含某个字段 SELECT data_b ? 'name' AS has_name FROM example; -- 检查多个字段是否存在 SELECT data_b ?& array['name', 'age'] AS has_all FROM example;
-
数组操作
bash-- 查询 JSONB 数组是否包含某个值 SELECT data_b->'tags' ? 'developer' AS contains_tag FROM example;
-
删除字段
bashSELECT data_b - 'age' AS without_age FROM example;
数据更新:
bash
// 更新json数据中age字段值为30
UPDATE example SET data_b = jsonb_set(data_b, '{age}', '30')
WHERE data_b->>'name' = 'Alice';