经典SQL不支持在单元格中存储多个值——关系模型要求进行规范化。然而,在现代任务中,常常会遇到"标签列表"、"评分尺度"等字段,其中在单独行的级别上操作多个值是很方便的。一些数据库(PostgreSQL、Oracle)提供了ARRAY数据类型或类似机制。
使用数组违反了规范化原则,给许多操作(过滤、更新、索引)带来了困难,并使得代码在数据库之间的移植性降低。但在某些情况下,这可能是方便或不可避免的——例如,用于缓存或快速查找小列表中的值。
CREATE TABLE products ( id SERIAL PRIMARY KEY, tags TEXT[] ); -- 插入: INSERT INTO products(tags) VALUES (ARRAY['eco','sale','hot']); -- 按数组查找: SELECT * FROM products WHERE 'eco' = ANY (tags);
关键特性:
可以对数组中的单个元素建立索引吗?
在PostgreSQL中——可以,使用GIN/GIST索引:
CREATE INDEX idx_tags ON products USING GIN (tags);
如何更快地检查值是否包含在通过分隔符划分的字符串列中的数组中?
SQL标准不支持,使用模式匹配来查找:
SELECT * FROM users WHERE ',admin,' LIKE concat('%,',role,',%');
但这种方法不可靠且较慢。
可以在数组中存储多少个值,以及有什么限制?
限制取决于数据库——例如,在PostgreSQL中,限制仅在行大小(1-2 MB)上。
在一个电子商务项目中,决定通过逗号在一个列中将产品标签存储为字符串。快速按标签查找产品变得非常困难,过滤错误频繁发生,由于解析错误,标签重复。
优点:
缺点:
在PostgreSQL中,对于小型的不变集合(用户角色),使用了ARRAY和GIN索引。对于较大的集合——单独的角色表。
优点:
缺点: