Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Design de banco de dados para configurações do usuário


Outras respostas descreveram habilmente os prós e contras de suas várias opções.

Acredito que sua Opção 1 (saco de propriedade) seja o melhor design geral para a maioria das aplicações, especialmente se você incluir algumas proteções contra os pontos fracos dos sacos de propriedade.

Veja o seguinte ERD:



No ERD acima, o USER_SETTING tabela é muito semelhante ao OP. A diferença é que em vez de varchar Code e Value colunas, este design tem um FK para um SETTING tabela que define as configurações permitidas (Códigos) e duas colunas mutuamente exclusivas para o valor. Uma opção é um campo varchar que pode receber qualquer tipo de entrada do usuário, a outra é um FK para uma tabela de valores legais.

A SETTING table também tem um sinalizador que indica se as configurações do usuário devem ser definidas pelo FK ou pela entrada varchar irrestrita. Você também pode adicionar um data_type para a SETTING para informar ao sistema como codificar e interpretar o USER_SETTING.unconstrained_value . Se desejar, você também pode adicionar o SETTING_GROUP tabela para ajudar a organizar as várias configurações para manutenção do usuário.

Esse design permite que você direcione as regras em torno de quais são suas configurações. Isso é conveniente, flexível e fácil de manter, evitando um vale-tudo.

EDITAR: Mais alguns detalhes, incluindo alguns exemplos...

Observe que o ERD, acima, foi aumentado com mais detalhes de coluna (valores de intervalo em SETTING e colunas em ALLOWED_SETTING_VALUE).

Aqui estão alguns registros de exemplo para ilustração.
SETTING:
+----+------------------+-------------+--------------+-----------+-----------+
| id | description      | constrained | data_type    | min_value | max_value |
+----+------------------+-------------+--------------+-----------+-----------+
| 10 | Favourite Colour | true        | alphanumeric | {null}    | {null}    |
| 11 | Item Max Limit   | false       | integer      | 0         | 9001      |
| 12 | Item Min Limit   | false       | integer      | 0         | 9000      |
+----+------------------+-------------+--------------+-----------+-----------+

ALLOWED_SETTING_VALUE:
+-----+------------+--------------+-----------+
| id  | setting_id | item_value   | caption   |
+-----+------------+--------------+-----------+
| 123 | 10         | #0000FF      | Blue      |
| 124 | 10         | #FFFF00      | Yellow    |
| 125 | 10         | #FF00FF      | Pink      |
+-----+------------+--------------+-----------+

USER_SETTING:
+------+---------+------------+--------------------------+---------------------+
| id   | user_id | setting_id | allowed_setting_value_id | unconstrained_value |
+------+---------+------------+--------------------------+---------------------+
| 5678 | 234     | 10         | 124                      | {null}              |
| 7890 | 234     | 11         | {null}                   | 100                 |
| 8901 | 234     | 12         | {null}                   | 1                   |
+------+---------+------------+--------------------------+---------------------+

A partir dessas tabelas, podemos ver que algumas das configurações do usuário que podem ser determinadas são Cor favorita, Limite máximo do item e Limite mínimo do item. Cor favorita é uma lista de seleção de alfanuméricos. Os limites mínimo e máximo do item são numéricos com valores de intervalo permitidos definidos. O SETTING.constrained A coluna determina se os usuários estão escolhendo a partir do ALLOWED_SETTING_VALUE relacionado s ou se eles precisam inserir um USER_SETTING.unconstrained_value . A GUI que permite que os usuários trabalhem com suas configurações precisa entender qual opção oferecer e como aplicar o SETTING.data_type e o min_value e max_value limites, se existirem.

Usando esse design, você pode definir as configurações permitidas, incluindo metadados suficientes para impor algumas restrições/verificações de sanidade rudimentares nos valores selecionados (ou inseridos) pelos usuários.

EDIT:consulta de exemplo

Aqui está um exemplo de SQL usando os dados acima para listar os valores de configuração para um determinado ID de usuário:
-- DDL and sample data population...
CREATE TABLE SETTING
    (`id` int, `description` varchar(16)
     , `constrained` varchar(5), `data_type` varchar(12)
     , `min_value` varchar(6) NULL , `max_value` varchar(6) NULL)
;

INSERT INTO SETTING
    (`id`, `description`, `constrained`, `data_type`, `min_value`, `max_value`)
VALUES
    (10, 'Favourite Colour', 'true', 'alphanumeric', NULL, NULL),
    (11, 'Item Max Limit', 'false', 'integer', '0', '9001'),
    (12, 'Item Min Limit', 'false', 'integer', '0', '9000')
;

CREATE TABLE ALLOWED_SETTING_VALUE
    (`id` int, `setting_id` int, `item_value` varchar(7)
     , `caption` varchar(6))
;

INSERT INTO ALLOWED_SETTING_VALUE
    (`id`, `setting_id`, `item_value`, `caption`)
VALUES
    (123, 10, '#0000FF', 'Blue'),
    (124, 10, '#FFFF00', 'Yellow'),
    (125, 10, '#FF00FF', 'Pink')
;

CREATE TABLE USER_SETTING
    (`id` int, `user_id` int, `setting_id` int
     , `allowed_setting_value_id` varchar(6) NULL
     , `unconstrained_value` varchar(6) NULL)
;

INSERT INTO USER_SETTING
    (`id`, `user_id`, `setting_id`, `allowed_setting_value_id`, `unconstrained_value`)
VALUES
    (5678, 234, 10, '124', NULL),
    (7890, 234, 11, NULL, '100'),
    (8901, 234, 12, NULL, '1')
;

E agora o DML para extrair as configurações de um usuário:
-- Show settings for a given user
select
  US.user_id 
, S1.description 
, S1.data_type 
, case when S1.constrained = 'true'
  then AV.item_value
  else US.unconstrained_value
  end value
, AV.caption
from USER_SETTING US
  inner join SETTING S1
    on US.setting_id = S1.id 
  left outer join ALLOWED_SETTING_VALUE AV
    on US.allowed_setting_value_id = AV.id
where US.user_id = 234

Veja isso no SQL Fiddle.