我创建了简单的自定义类型:
CREATE TYPE skill_progress AS
(id uuid,
count smallint);
我的skills
类型users
中有skill_progress[]
列。我需要通过指定的元素id更新数组count
中的skill_progress[]
元素。我需要这样的东西:
UPDATE users SET skills['5a0574cc-66b7-4c89-9950-03a2eea0c701'].count = 10
WHERE nick = 'nick4123';
我已经创建了能够完成我需要的功能,但我想知道是否有更简单的方法。
CREATE OR REPLACE FUNCTION update_sp
(user_id uuid, skill_id uuid, count smallint) RETURNS integer AS $$
DECLARE
i integer;
up integer;
arr skill_progress[];
BEGIN
SELECT skills INTO arr FROM users WHERE id = user_id;
SELECT array_upper(arr, 1) INTO up;
FOR i IN 1..up
LOOP
IF arr[i].id = skill_id THEN
UPDATE users SET skills[i].count = count WHERE id = user_id;
RETURN 0;
END IF;
END LOOP;
RETURN 1;
END
$$
LANGUAGE plpgsql;
我认为如果我创建一个新表,那么它将是太多的数据重复。对于每个用户,该表应包含少量记录,其中重复用户ID。像这样:
row_num | user_id | skill_id | count
- - - - - - - - - - - - - - - - - - - - -
1 | 1000 | 100 | 2
1 | 1000 | 101 | 3
1 | 1000 | 102 | 5
. . .
自定义类型的目的是什么?
答案 0 :(得分:0)
您可以在没有功能的情况下更新表格:
update users u
set skills[rn].count = 10
from (
select skill, rn
from (
select skill, row_number() over () rn
from (
select unnest(skills) skill
from users
where nick = 'nick4123'
) sub
) sub
where (skill).id = '5a0574cc-66b7-4c89-9950-03a2eea0c701'
) sub
where u.nick = 'nick4123'
然而,这真的很难理解,为什么你必须让你的生活变得如此沉重。 Ids
应为integers
(或bigints
),user_skills
应为user_id
引用users
的表格。
更新
对于习惯于处理复杂内部数据结构的程序员来说,这种尝试是很自然的。 略有不同的逻辑适用于数据库世界, 在哪里获取数据的速度至关重要, 有时以牺牲冗余使用存储空间为代价。
您的表格可能如下所示:
create table users (
user_id int primary key,
nick text);
create table skills (
skill_id int primary key,
user_id int references users,
skill_count int);
这是一个标准化的数据模型。 表之间的关系称为一对多。 此模式通常用于数百万使用RDBMS的应用程序。 这不是详细讨论这个问题的好地方, 特别是因为你可以在互联网上找到数百个关于数据建模和规范化的好文章。