当用户选择 "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

我应该如何设计架构以适应动态列数组?或者我根本不应该使用数组?

附加问题:

看来你的问题在这里没有得到太多关注。

你有几个选择。最好的选择是构建关系表来存储它,但是您将需要使用触发器或其他指示器列来表示每个 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 出现时,您可以在宿主语言端通过简单的循环或列表理解来创建位图值。