PostgreSQL学习笔记(二):PostgreSQL基本操作

PostgreSQL 是一个功能强大的开源关系型数据库管理系统 (RDBMS),支持标准的 SQL 语法,并扩展了许多功能强大的操作语法.

数据类型

数值类型
数据类型 描述 存储大小 示例值
SMALLINT 小范围整数,范围:-32,768 到 32,767 2 字节 -123
INTEGERINT 中范围整数,范围:-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
REALFLOAT4 单精度浮点数,范围:6 位小数精度 4 字节 1.23
DOUBLE PRECISIONFLOAT8 双精度浮点数,范围: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 布尔值,TRUEFALSENULL 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 中,JSONJSONB 是两种用于存储 JSON 数据的列类型。它们功能强大,广泛用于现代应用中。

JSON 与 JSONB 的主要区别

  1. 存储方式

    • JSON:以文本格式存储数据,存储和检索时保持输入顺序。
    • JSONB:以二进制格式存储,经过解析和去重处理(键的顺序不保存)。
  2. 性能

    • JSON:适合读取为原始 JSON 字符串,查询效率较低。
    • JSONB:支持索引,查询和操作效率更高。
  3. 使用场景

    • 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"]}');

查询数据:

  1. 访问 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;
  • 删除字段

    bash 复制代码
    SELECT 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';
相关推荐
背太阳的牧羊人5 分钟前
使用 SQLite3 的基本操作步骤
数据库·sqlite
从后端到QT10 分钟前
Android NDK开发入门2之适应idm环境
前端·javascript·数据库
背太阳的牧羊人11 分钟前
使用 SQL 和表格数据进行问答和 RAG(6)—将指定目录下的 CSV 或 Excel 文件导入 SQLite 数据库
数据库·sql·langchain·sqlite·excel
唐梓航-求职中31 分钟前
缓存-Redis-常见问题-缓存击穿-永不过期+逻辑过期(全面 易理解)
数据库·redis·缓存
潜洋41 分钟前
Spring Boot教程之五十二:CrudRepository 和 JpaRepository 之间的区别
java·大数据·数据库·spring boot
潘多编程1 小时前
Spring Boot微服务中进行数据库连接池的优化?
数据库·spring boot·微服务
阿里云云原生2 小时前
网络分析与监控:阿里云拨测方案解密
数据库·阿里云·memcached
HelloZheQ2 小时前
Java 项目中引入阿里云 OSS SDK
java·数据库·阿里云
利刃大大2 小时前
【MySQL基础篇】十二、视图的概念与操作
数据库·mysql
rr_R_rr2 小时前
MYSQL重置密码
数据库·mysql·adb