SQL 数组

5次阅读

SQL 数组

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 灵活)
  • 更新单个元素较麻烦(常需整体替换或用下标赋值)
  • 跨数据库迁移时,数组语法完全不兼容,会成为技术债
  • 业务逻辑复杂时(如权限校验、状态流转),用关系模型更易维护和扩展
text=ZqhQzanResources