你大概率已经听说过数组了。在各种编程语言里,数组基本都差不多,但还是有点小区别。
在PostgreSQL里,数组是一种数据类型,可以让你在一个表的列里存一堆同一种类型的值。就像你不是只往格子里放一个东西,而是直接塞进一整“箱”数据。可以是数字、字符串、日期,甚至更复杂的对象。
抽象点说,数组就像工具箱。你不用把每个扳手都拿在手里(每个扳手像单独的列/行),而是全都丢进一个方便的箱子里(一列存一个数组)。
两种创建数组的方式
在PostgreSQL里,主要有两种语法能创建数组。就像打包行李有两种方法——结果一样,方式不太一样:
- 用大括号
{}的语法
这种写法更简洁,也最常用:
-- 字符串数组
'{"苹果", "香蕉", "樱桃"}'
-- 数字数组
'{1, 2, 3, 4, 5}'
-- 日期数组
'{"2023-01-01", "2023-01-02", "2023-01-03"}'
- 用构造器
ARRAY[]的语法
这种写法更直观,也更好读:
-- 字符串数组
ARRAY['苹果', '香蕉', '樱桃']
-- 数字数组
ARRAY[1, 2, 3, 4, 5]
-- 日期数组
ARRAY['2023-01-01'::DATE, '2023-01-02'::DATE, '2023-01-03'::DATE]
这两种写法其实都一样!用哪个看你习惯和场景。就像别的编程语言里 for 和 while 循环——功能一样,但有时候一个更顺手。
啥时候用数组
数组是PostgreSQL的超能力,能帮你解决那些不想多建表或多加列的场景。特别适合:
- 存列表、标签或分类
比如你要做个电商数据库。每个商品可能有好几个标签,比如:
- 对T恤来说,标签可以是:
["服装", "男款", "运动"]。 - 耳机的标签:
["电子产品", "无线", "小玩意"]。
用数组,你可以把这些标签直接存在一列里,不用单独建个标签表,省事还省空间。
-- 带标签数组的商品表
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
tags TEXT[] -- 标签的字符串数组
);
-- 示例数据
INSERT INTO products (name, tags)
VALUES
('T恤', ARRAY['服装', '男款', '运动']),
('耳机', ARRAY['电子产品', '无线', '小玩意']);
- 存订单列表
比如你做订单系统,数组可以帮你把一个订单里的商品ID都放一起:
-- 带商品ID数组的订单表
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_name TEXT,
product_ids INTEGER[] -- 商品ID的数组
);
-- 示例数据
INSERT INTO orders (customer_name, product_ids)
VALUES
('安娜', ARRAY[1, 2, 3]),
('奥托', ARRAY[4, 5]);
这样每个订单都能直接看到买了哪些商品。是不是很方便?
简单配置和设置
比如你要存用户的偏好设置或简单的选项列表:
CREATE TABLE user_preferences ( user_id INTEGER PRIMARY KEY, notification_types TEXT[], allowed_days INTEGER[] -- 一周的天数:1-7 );
数组和其他数据类型的对比
这里要明白,数组只是PostgreSQL工具箱里的又一个工具,不是啥都适合。比如,数组的替代方案可以是关系表(多对多关系),或者用JSON/JSONB类型。
数组 vs JSONB
数组适合你确定只要存一堆同类型的值。它更简单、更快、占空间也小。
JSONB适合结构更灵活、复杂的对象。但JSONB用起来会麻烦点。
同一组数据,数组和JSONB的例子:
-- 数组
ARRAY['服装', '男款', '运动']
-- JSONB
'["服装", "男款", "运动"]'::JSONB
如果你经常要排序、筛选或建索引,数组会更合适。
数组在实际开发里的例子
比如你要做个大学考勤系统。每节课有一堆学生来上,但你又不想单独建个表来关联学生和课程。这时候就能用数组:
-- 带学生数组的课程表
CREATE TABLE lectures (
id SERIAL PRIMARY KEY,
topic TEXT NOT NULL,
students INTEGER[] -- 学生ID的数组
);
-- 示例数据
INSERT INTO lectures (topic, students)
VALUES
('数据库', ARRAY[101, 102, 103]),
('算法', ARRAY[104, 105]);
这样你可以很容易查到每节课的学生名单,还能随时加人或删人。
用PostgreSQL数组要注意的点
- 数组里的数据类型必须一致。 PostgreSQL不让你在一个数组里混着放字符串和数字。
-- 正确
ARRAY[1, 2, 3] -- 数字数组
-- 错误:混了字符串和数字
ARRAY['苹果', 42, '樱桃']
- 数组下标是从1开始的,不是0。别搞混了,尤其你习惯了Python、JavaScript、C++这些从0开始的语言。
- 支持NULL:数组里可以有NULL值
- 多维数组:PostgreSQL支持多维数组
GO TO FULL VERSION