CodeGym /课程 /SQL SELF /使用数组时的常见错误及其预防方法

使用数组时的常见错误及其预防方法

SQL SELF
第 36 级, 课程 4
可用

今天我们要结束在PostgreSQL数组世界的有趣旅程。今天的主题——你可能会遇到的典型错误,以及最重要的,怎么避免它们。如果你曾经想过“这个数组又在搞怪了”,那这节课就是为你准备的。来,一起搞明白吧。

创建数组时的错误:数组内数据类型问题

在PostgreSQL里创建数组时,记住所有元素必须是同一种类型。比如:

SELECT ARRAY[1, 2, '三'];
-- 错误:数组里的元素必须是同一种类型

PostgreSQL不允许你把数字和字符串混在一个数组里。如果你真的需要这样,记得做类型转换:

SELECT ARRAY[1::TEXT, 2::TEXT, '三'];
-- 现在数组全是字符串了

用ARRAY[]时数据类型不一致的错误

默认情况下,PostgreSQL会根据数组内容猜类型。如果你给了它模棱两可的数据,准备好报错吧:

SELECT ARRAY[1, NULL];
-- 错误:PostgreSQL不知道怎么解释NULL

解决方法是,明确指定数据类型:

SELECT ARRAY[1, NULL]::INTEGER[];
-- 现在一切正常

取数据时的错误:数组索引问题

如果你习惯了Python或JavaScript那种从0开始的数组索引,PostgreSQL会让你小吃一惊。这里数组索引是从1开始的。

SELECT ARRAY[10, 20, 30][0];
-- 错误:索引必须从1开始

正确的写法:

SELECT ARRAY[10, 20, 30][1];
-- 结果:10

用函数取数组时的错误

像unnest()这样的函数,如果你没注意,它会把数组“拆开”成多行,容易搞混:

CREATE TEMP TABLE example (
    id SERIAL PRIMARY KEY,
    tags TEXT[]
);

INSERT INTO example (tags) VALUES (ARRAY['标签1', '标签2']), (ARRAY['标签3']);

SELECT unnest(tags) FROM example;
-- 结果:
-- 标签1
-- 标签2
-- 标签3

如果你想保留行的上下文(比如id),要把它加上:

SELECT id, unnest(tags) AS tag FROM example;
-- 结果:
-- id | tag
--  1 | 标签1
--  1 | 标签2
--  2 | 标签3

数组过滤和比较时的错误

  1. 错误使用@>、<@、&&操作符

这些操作符有各自的用途:

  • @> 检查一个数组是否包含另一个数组。
  • <@ 检查一个数组是否被包含在另一个数组里。
  • && 检查两个数组是否有交集。

如果用错了,就会报错:

SELECT ARRAY[1, 2, 3] @> 2;
-- 错误:@>操作符只能用于数组

正确写法:

SELECT ARRAY[1, 2, 3] @> ARRAY[2];
-- 结果:true
  1. 没有索引导致性能问题

如果你经常用数组操作符,发现查询慢,很可能是忘了建索引。比如这样给数组建索引:

CREATE INDEX idx_tags ON example USING GIN (tags);

现在用@>和&&的查询会快很多。

修改数组时的错误

  1. 删除和添加值

array_remove()和array_append()这些函数不会“原地”改数组,而是返回新数组。如果你以为原数组会变,那就错了:

UPDATE example
SET tags = array_remove(tags, '标签1');
-- 现在数组被更新了

如果你忘了写SET tags =,SQL会执行,但数组不会变。

  1. 用array_append()时数据重复

array_append()不会检查元素是否已存在,可能会导致重复:

SELECT array_append(ARRAY['标签1', '标签2'], '标签1');
-- 结果:{标签1, 标签2, 标签1}

如果你想避免重复,可以先过滤:

SELECT array_remove(array_append(ARRAY['标签1', '标签2'], '标签1'), '标签1') || '标签1';
-- 结果:{标签1, 标签2}

防止错误的小建议

想避免上面这些数组相关的坑:

  1. 检查数据类型。如果有歧义,记得明确指定数组类型。
  2. 注意索引。PostgreSQL数组索引是从1开始的。
  3. 优化数组查询。用索引让比较和过滤更快。
  4. 先用小数据测试。如果数组查询慢,先用小数据集找瓶颈。
  5. 防止重复。加元素时多做一步检查,避免重复。

PostgreSQL里的数组就像一把利器,用得好很强大,但也要小心。照着这些建议来,你的数组再也不会让你熬夜(嗯,基本不会)。祝你数据库设计和优化顺利!

2
任务
SQL SELF, 第 36 级, 课程 4
已锁定
修改和过滤数组
修改和过滤数组
1
调查/小测验
数组的比较和过滤第 36 级,课程 4
不可用
数组的比较和过滤
数组的比较和过滤
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION