
SQL 本身没有原生的“数组”类型(像 Python 或 JavaScript 那样),但不同数据库系统提供了各自的数组支持方式,主要用于存储和操作一组同类型值。是否能用、怎么用,取决于你用的是哪种数据库。
PostgreSQL:真正支持数组类型
PostgreSQL 是最常用且功能最完整的支持数组的 SQL 数据库。它允许定义列类型为 integer[]、text[]、jsonb[] 等。
- 建表示例:
CREATE TABLE products (id serial, tags text[]); - 插入数组:
INSERT INTO products (tags) VALUES (ARRAY['sale', 'new', 'featured']);或简写VALUES ('{sale,new,featured}'); - 查询某个元素:
SELECT tags[1] FROM products;(下标从 1 开始) - 判断是否包含某值:
WHERE 'sale' = ANY(tags)或WHERE tags @> ARRAY['sale']
MySQL / SQL Server / SQLite:不支持原生数组,需替代方案
这些主流数据库不提供数组类型,常见做法是通过关系建模或字符串模拟来实现类似效果。
-
推荐方式:一对多关联表——比如用户-标签场景,建
users表和user_tags表,用外键连接,语义清晰、可索引、易查询 -
临时方案:JSON 字段——MySQL 5.7+、SQL Server 2016+、SQLite 3.38+ 支持 JSON 类型,可存
["a","b","c"],再用函数解析(如 MySQL 的JSON_CONTAINS()、JSON_EXTRACT()) -
不推荐:逗号分隔字符串——如
"a,b,c",难以准确查询、无法索引、容易出错(比如匹配到子串 "b" 而非独立项)
通用技巧:用 UNNEST 或 JOIN 拆开数组做行级操作
在支持数组的数据库中(如 PostgreSQL),常需把数组“展开”成多行,方便聚合或关联。
-
SELECT id, unnest(tags) AS tag FROM products;→ 把每个数组元素转成一行 - 结合
JOIN LATERAL可与其它表联动处理,例如统计每个标签出现次数
注意事项和陷阱
即使数据库支持数组,也不代表它适合所有场景。
- 数组字段通常难以高效索引(PostgreSQL 支持 GIN 索引加速
@>查询,但不如普通 B-tree 灵活) - 更新单个元素较麻烦(常需整体替换或用下标赋值)
- 跨数据库迁移时,数组语法完全不兼容,会成为技术债
- 业务逻辑复杂时(如权限校验、状态流转),用关系模型更易维护和扩展










