当用户选择 "all" 时动态增加用户选择
Dynamically grow user selection when they have selected "all"
我的用户有多个电子邮件首选项,如果他们选择 'all' 作为首选项,我想在添加新的首选项时 增加 他们的首选项选择。
我可以通过每个偏好选项的触发器来做到这一点 table。在 INSERT
上,我还可以 UPDATE
用户首选项数组并附加新选项。当用户列表开始增长时,我担心性能,因为每个偏好选项可能会更新并且每个用户可以有多个偏好。
USER_1
PREFERENCE_1
OPTION_1 -> ALL
OPTION_2 -> [1, 2, 3]
OPTION_3 -> [1, 2]
PREFERENCE_2
OPTION_1 -> ALL
OPTION_2 -> ALL
OPTION_3 -> ALL
我应该如何设计架构以适应动态列数组?或者我根本不应该使用数组?
附加问题:
- 是否可以实现 All but x 选择?用户可能需要所有选项,但不需要部分选项。选择仍应动态增长。
看来你的问题在这里没有得到太多关注。
你有几个选择。最好的选择是构建关系表来存储它,但是您将需要使用触发器或其他指示器列来表示每个 option
.
都有一个 user
。
我多次使用的第二个选项是 bitstring
。这本质上是一个位掩码。我对使用它唯一的遗憾是不得不向刚从一些 shake-and-bake 函授课程毕业的开发人员解释它是如何工作的,他们喜欢自己“full-stack”。
create table preference (
bitmask bit(30) not null primary key, -- Adjust size to some overkill number
pref_name text
);
insert into preference
select ((2^n)::bigint)::bit(30) as bitmask,
'Option '||(n+1)::text as pref_name
from generate_series(0, 10, 1) as gs(n);
create table prefs_user (
id int primary key,
user_name text,
user_prefs bit(30)
);
insert into prefs_user values
(1, 'me', ~(0::bit(30))),
(2, 'you', 22::bit(30)),
(3, 'him', ~(8::bit(30))); -- all except Option 4
要加入以查看为 prefs_user
启用了哪些选项:
select *
from prefs_user u
join preference p
on (u.user_prefs & p.bitmask)::bigint > 0
order by u.id, p.bitmask;
id | user_name | user_prefs | bitmask | pref_name
----+-----------+--------------------------------+--------------------------------+-----------
1 | me | 111111111111111111111111111111 | 000000000000000000000000000001 | Option 1
1 | me | 111111111111111111111111111111 | 000000000000000000000000000010 | Option 2
1 | me | 111111111111111111111111111111 | 000000000000000000000000000100 | Option 3
1 | me | 111111111111111111111111111111 | 000000000000000000000000001000 | Option 4
1 | me | 111111111111111111111111111111 | 000000000000000000000000010000 | Option 5
1 | me | 111111111111111111111111111111 | 000000000000000000000000100000 | Option 6
1 | me | 111111111111111111111111111111 | 000000000000000000000001000000 | Option 7
1 | me | 111111111111111111111111111111 | 000000000000000000000010000000 | Option 8
1 | me | 111111111111111111111111111111 | 000000000000000000000100000000 | Option 9
1 | me | 111111111111111111111111111111 | 000000000000000000001000000000 | Option 10
1 | me | 111111111111111111111111111111 | 000000000000000000010000000000 | Option 11
2 | you | 000000000000000000000000010110 | 000000000000000000000000000010 | Option 2
2 | you | 000000000000000000000000010110 | 000000000000000000000000000100 | Option 3
2 | you | 000000000000000000000000010110 | 000000000000000000000000010000 | Option 5
3 | him | 111111111111111111111111110111 | 000000000000000000000000000001 | Option 1
3 | him | 111111111111111111111111110111 | 000000000000000000000000000010 | Option 2
3 | him | 111111111111111111111111110111 | 000000000000000000000000000100 | Option 3
3 | him | 111111111111111111111111110111 | 000000000000000000000000010000 | Option 5
3 | him | 111111111111111111111111110111 | 000000000000000000000000100000 | Option 6
3 | him | 111111111111111111111111110111 | 000000000000000000000001000000 | Option 7
3 | him | 111111111111111111111111110111 | 000000000000000000000010000000 | Option 8
3 | him | 111111111111111111111111110111 | 000000000000000000000100000000 | Option 9
3 | him | 111111111111111111111111110111 | 000000000000000000001000000000 | Option 10
3 | him | 111111111111111111111111110111 | 000000000000000000010000000000 | Option 11
用户 me
选择了所有选项,因此您添加到 30 的任何选项都将始终被选中。
用户you
只选择了三个选项。添加选项不会影响用户的选择。
用户 him
选择了除选项 4
之外的所有选项。将为该用户选择新选项。
bit
字符串很容易映射到复选框组中的数组,name
属性设置为 bitmask
:
的 log-base-2
select log(2, bitmask::bigint)::int, pref_name from preference;
log | pref_name
-----+-----------
0 | Option 1
1 | Option 2
2 | Option 3
3 | Option 4
4 | Option 5
5 | Option 6
6 | Option 7
7 | Option 8
8 | Option 9
9 | Option 10
10 | Option 11
(11 rows)
当 post
出现时,您可以在宿主语言端通过简单的循环或列表理解来创建位图值。
我的用户有多个电子邮件首选项,如果他们选择 'all' 作为首选项,我想在添加新的首选项时 增加 他们的首选项选择。
我可以通过每个偏好选项的触发器来做到这一点 table。在 INSERT
上,我还可以 UPDATE
用户首选项数组并附加新选项。当用户列表开始增长时,我担心性能,因为每个偏好选项可能会更新并且每个用户可以有多个偏好。
USER_1
PREFERENCE_1
OPTION_1 -> ALL
OPTION_2 -> [1, 2, 3]
OPTION_3 -> [1, 2]
PREFERENCE_2
OPTION_1 -> ALL
OPTION_2 -> ALL
OPTION_3 -> ALL
我应该如何设计架构以适应动态列数组?或者我根本不应该使用数组?
附加问题:
- 是否可以实现 All but x 选择?用户可能需要所有选项,但不需要部分选项。选择仍应动态增长。
看来你的问题在这里没有得到太多关注。
你有几个选择。最好的选择是构建关系表来存储它,但是您将需要使用触发器或其他指示器列来表示每个 option
.
user
。
我多次使用的第二个选项是 bitstring
。这本质上是一个位掩码。我对使用它唯一的遗憾是不得不向刚从一些 shake-and-bake 函授课程毕业的开发人员解释它是如何工作的,他们喜欢自己“full-stack”。
create table preference (
bitmask bit(30) not null primary key, -- Adjust size to some overkill number
pref_name text
);
insert into preference
select ((2^n)::bigint)::bit(30) as bitmask,
'Option '||(n+1)::text as pref_name
from generate_series(0, 10, 1) as gs(n);
create table prefs_user (
id int primary key,
user_name text,
user_prefs bit(30)
);
insert into prefs_user values
(1, 'me', ~(0::bit(30))),
(2, 'you', 22::bit(30)),
(3, 'him', ~(8::bit(30))); -- all except Option 4
要加入以查看为 prefs_user
启用了哪些选项:
select *
from prefs_user u
join preference p
on (u.user_prefs & p.bitmask)::bigint > 0
order by u.id, p.bitmask;
id | user_name | user_prefs | bitmask | pref_name
----+-----------+--------------------------------+--------------------------------+-----------
1 | me | 111111111111111111111111111111 | 000000000000000000000000000001 | Option 1
1 | me | 111111111111111111111111111111 | 000000000000000000000000000010 | Option 2
1 | me | 111111111111111111111111111111 | 000000000000000000000000000100 | Option 3
1 | me | 111111111111111111111111111111 | 000000000000000000000000001000 | Option 4
1 | me | 111111111111111111111111111111 | 000000000000000000000000010000 | Option 5
1 | me | 111111111111111111111111111111 | 000000000000000000000000100000 | Option 6
1 | me | 111111111111111111111111111111 | 000000000000000000000001000000 | Option 7
1 | me | 111111111111111111111111111111 | 000000000000000000000010000000 | Option 8
1 | me | 111111111111111111111111111111 | 000000000000000000000100000000 | Option 9
1 | me | 111111111111111111111111111111 | 000000000000000000001000000000 | Option 10
1 | me | 111111111111111111111111111111 | 000000000000000000010000000000 | Option 11
2 | you | 000000000000000000000000010110 | 000000000000000000000000000010 | Option 2
2 | you | 000000000000000000000000010110 | 000000000000000000000000000100 | Option 3
2 | you | 000000000000000000000000010110 | 000000000000000000000000010000 | Option 5
3 | him | 111111111111111111111111110111 | 000000000000000000000000000001 | Option 1
3 | him | 111111111111111111111111110111 | 000000000000000000000000000010 | Option 2
3 | him | 111111111111111111111111110111 | 000000000000000000000000000100 | Option 3
3 | him | 111111111111111111111111110111 | 000000000000000000000000010000 | Option 5
3 | him | 111111111111111111111111110111 | 000000000000000000000000100000 | Option 6
3 | him | 111111111111111111111111110111 | 000000000000000000000001000000 | Option 7
3 | him | 111111111111111111111111110111 | 000000000000000000000010000000 | Option 8
3 | him | 111111111111111111111111110111 | 000000000000000000000100000000 | Option 9
3 | him | 111111111111111111111111110111 | 000000000000000000001000000000 | Option 10
3 | him | 111111111111111111111111110111 | 000000000000000000010000000000 | Option 11
用户 me
选择了所有选项,因此您添加到 30 的任何选项都将始终被选中。
用户you
只选择了三个选项。添加选项不会影响用户的选择。
用户 him
选择了除选项 4
之外的所有选项。将为该用户选择新选项。
bit
字符串很容易映射到复选框组中的数组,name
属性设置为 bitmask
:
select log(2, bitmask::bigint)::int, pref_name from preference;
log | pref_name
-----+-----------
0 | Option 1
1 | Option 2
2 | Option 3
3 | Option 4
4 | Option 5
5 | Option 6
6 | Option 7
7 | Option 8
8 | Option 9
9 | Option 10
10 | Option 11
(11 rows)
当 post
出现时,您可以在宿主语言端通过简单的循环或列表理解来创建位图值。