É melhor estruturar uma tabela SQL para corresponder ou não retornar nenhum resultado

StackOverflow https://stackoverflow.com/questions/23399

  •  09-06-2019
  •  | 
  •  

Pergunta

Eu tenho uma pergunta interessante sobre design.Estou projetando o lado de segurança do nosso projeto, para nos permitir ter diferentes versões do programa por diferentes custos e também para permitir que usuários do tipo Manager concedam ou neguem acesso a partes do programa a outros usuários.Será baseado na web e hospedado em nossos servidores.

Estou usando uma opção simples de Permitir ou Negar para cada 'Recurso' ou tela.

Teremos um grande número de recursos e o usuário poderá configurar muitos grupos diferentes para colocar usuários para controlar o acesso.Cada usuário só pode pertencer a um único grupo.

Tenho duas abordagens para isso em mente e estava curioso para saber qual seria melhor para o servidor SQL em termos de desempenho.

Opção AA presença de uma entrada na tabela de acesso significa que o acesso é permitido.Para isso não será necessária uma coluna no banco de dados para armazenar informações.Se nenhum resultado for retornado, o acesso será negado.

Acho que isso significará uma tabela menor, mas as consultas pesquisariam a tabela inteira para determinar se não há correspondência?

Opção BUma coluna de bits está incluída no banco de dados que controla Permitir/Negar.Isso significa que sempre há um resultado a ser encontrado e resulta em uma tabela maior.

Pensamentos?

Foi útil?

Solução

Se for apenas Permitir/Negar, uma simples tabela de vinculação entre Usuários e Recursos funcionaria bem.Se houver uma entrada codificada para o recurso do usuário na tabela de vinculação, permita o acesso.

UserResources
-------------
UserId FK->Users
ResourceId FK->Resources

e o sql seria algo como

if exists (select 1 from UserResources 
where UserId = @uid and ResourceId=@rid)
set @allow=1;

Com um índice clusterizado ativado (UserId e ResourceId), a consulta seria incrivelmente rápida, mesmo com milhões de registros.

Outras dicas

Eu votaria na opção B.Se você escolher a Opção A e presumir que, se um usuário existir, ele poderá entrar, eventualmente você se deparará com o problema de negar acesso a um usuário, sem remover o registro do usuário.

Haverá muitos casos em que você desejará bloquear o acesso de um usuário, mas não desejará destruir completamente sua conta.Um desses casos (não necessariamente vinculado ao seu caso de uso) é quando você deixa de pagar e eles cortam sua conta até que você comece a pagar novamente.Eles não querem excluir o registro, porque ainda querem habilitá-lo quando você pagar novamente, em vez de recriar a conta do zero e perder todo o histórico do usuário.

B.Ele permite verificações muito melhores se os dados estão completos (por exemplo, quando você adiciona um recurso permitido/negado).

Além disso, o tamanho da tabela deve ser levado em consideração apenas para tabelas que você sabe que conterão muitos registros (como em mais de 100.000).Mesmo que você reserve um tempo para digitar a consideração do tamanho da tabela nesta questão, já custa mais do que o espaço extra no disco rígido que seria necessário.

Abordagem A, mas eu também incluiria uma negação explícita além de sua negação implícita.Eu faria alguns casos de uso para ter certeza de que sua lógica final funciona, mas aqui estão alguns exemplos.

User1 is in group1 and group2.  
User2 is in group1  
User3 is in group2 

Folder1 allows group1 and deny group2.  
User1 is denied.  
User2 is allowed.  
User3 is denied. 

Acredito que sua abordagem users1 seria permitida.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top