Manter usuário e perfil de usuário em tabelas diferentes?

26

Eu já vi em alguns projetos que os desenvolvedores preferem manter as informações essenciais do usuário em uma tabela (email / login, hash de senha, nome de tela) e o restante do perfil de usuário não essencial em outra (data de criação, país etc.). Por não essencial, quero dizer que esses dados são necessários apenas ocasionalmente. O benefício óbvio é que, se você estiver usando ORM, a consulta a menos campos é obviamente boa. Mas então você pode ter duas entidades mapeadas para a mesma tabela e isso evitará que você pergunte coisas que você não precisa (enquanto é mais conveniente). Alguém conhece outra vantagem de manter essas coisas em duas tabelas?

Andrey
fonte
1
@MichaelT thanks! Interessante que não haja consenso em todas as questões vinculadas.
Andrey
Foi por isso que fui com a lista de perguntas vinculadas, em vez de tentar respondê-la. Ele realmente se resume a uma base caso a caso e como um aplicativo específico está sendo arquitetado. Lembre-se, você sempre pode usar uma exibição para juntar os dois bits, se necessário. Considere também a possibilidade de desvincular uma (excluir a conta), mas mantendo a outra por perto (as perguntas precisam estar vinculadas a uma conta, mas a conta nem sempre tem um perfil ...). Pode ser uma pergunta interessante para entrar no bate - papo de engenharia de software ou acessar o DBA.SE e perguntar no bate-papo.
1
@ MichaelT Estou pensando em criar um tipo de estrutura generalizada que fornecerá o modelo do usuário.
Andrey
Em alguns projetos anteriores, movi propositalmente colunas que deveriam ser gravadas com muita frequência em suas próprias tabelas separadas com o objetivo de proteger a tabela principal, caso o arquivo do banco de dados fosse corrompido ou danificado.
GrandmasterB

Respostas:

11

Depende do tamanho e dos requisitos do seu projeto.

Eu posso ver uma maneira pela qual os dados sobre usuários podem ser divididos em dois conjuntos, com finalidades diferentes e, portanto, requisitos:

  • Dados de identidade: nome de usuário, hash da senha, endereço de e-mail, hora do último login, etc.
  • Dados do perfil do usuário, que incluem preferências do usuário, atividade mais recente, atualizações de status etc.

Observe que existem alguns atributos sobre o usuário que podem se enquadrar em qualquer categoria (por exemplo, data de nascimento do usuário). A diferença entre esses dois conjuntos é que o primeiro é rigidamente controlado e somente através de certos fluxos de trabalho ele pode ser modificado. Por exemplo, alterar uma senha pode exigir o fornecimento de uma senha existente, alterar o email pode exigir a verificação do email e seria usado no caso de o usuário esquecer a senha.

As preferências não exigem essas ACLs e podem teoricamente ser modificadas pelo usuário ou por outro aplicativo, desde que o usuário consente. As apostas são baixas se um aplicativo maliciosamente ou devido a um bug corromper os dados ou tentar modificá-los (supondo que outras medidas de segurança sejam tomadas.) No entanto, normalmente seria desastroso se algum nome de usuário, senha ou email pudesse ser modificado pois eles podem ser usados ​​para assumir a identidade do usuário ou negar serviço ou causar custos de suporte etc. para o administrador.

Assim, geralmente os dados são armazenados em dois tipos de sistemas:

  • Os dados de identidade normalmente entram em um diretório ou em uma solução IAM.
  • Os dados de preferência terminarão em um banco de dados.

Dito isto, na prática, as pessoas violarão essas regras e usarão uma ou outra (por exemplo, servidor SQL por trás do provedor de associação do ASP.NET).

À medida que os dados de identidade se tornam maiores ou a organização que os utiliza se torna maior, surgem diferentes tipos de problemas. Por exemplo, no caso de diretório, ele tenta replicar as alterações de senha imediatamente para todos os servidores em um ambiente com vários servidores. No entanto, a preferência do usuário exige apenas consistência eventual. (FYI: Ambas são otimizações diferentes do teorema do CAPS.)

Por fim, os diretórios (especialmente os diretórios on-line / nuvem) também emitem tokens de acesso para outros recursos usando protocolos como OAUTH (por exemplo, considere Facebook, Google, Microsoft Account, ADFS), enquanto um banco de dados não tem essa necessidade. Um banco de dados suportará junções e estruturas de consulta bastante complexas, cujo diretório não precisa.

Para mais detalhes, algumas pesquisas no diretório de identidade versus banco de dados ajudariam.

Eventualmente, tudo se resume ao que seus cenários são e espera-se que sejam no futuro, incluindo a integração com terceiros (e com o que eles estão usando). Se for um projeto bem contido e você tiver certeza de que pode proteger os dados de identidade do usuário e se autenticar corretamente, poderá procurar o banco de dados. Caso contrário, pode valer a pena investigar um diretório de identidade.

Se você optar pelo DB, IMO, o uso de um banco de dados vs dois acabaria descendo para o controle de acesso, tanto para usuários quanto para aplicativos.

Omer Iqbal
fonte
3

Há pelo menos três casos em que é desejável ter uma tabela de pessoa para atributos básicos e uma segunda tabela para outros atributos com um relacionamento um para um:

  • BLOB dados como uma imagem. Uma tabela separada permite que os dados sejam armazenados separadamente por motivos de desempenho, por exemplo, em um espaço de tabela separado.
  • Dados que não se aplicam a todos ou que se aplicam apenas a uma pessoa que desempenha um determinado papel. Pense nisso como colunas que seriam nulas em muitas linhas se fizessem parte da tabela principal. No banco de dados de uma clínica, você pode ter uma tabela de pessoas, uma tabela de pacientes e uma tabela de médicos; no primeiro, você teria atributos básicos; no segundo, somente atributos pertinentes quando a pessoa é um paciente, como cobertura de seguro; Na terceira tabela (quando a pessoa é um médico), você pode ter a especialidade médica e outros dados que se aplicam apenas ao pessoal médico. Obviamente, um médico pode ser um paciente.
  • Uma tabela que materializa um relacionamento com uma entidade em um sistema remoto. Nesse caso, a tabela estabelece uma equivalência entre identificadores exclusivos em um banco de dados separado por motivos de interoperabilidade.

Eu acho que o caso que você expõe se encaixa no segundo caso.

Tulains Córdova
fonte
1

Meu principal motivo para mantê-los separados é tentar evitar o que é conhecido na programação orientada a objetos como uma "classe divina". Os ORM relacionam tabelas e campos a classes e atributos, para que também se torne relevante como o nível SQL (mesmo sem um ORM, geralmente há um princípio semelhante em jogo).

A classe User (e por associação a tabela user) é frequentemente a tabela que se torna a classe god com centenas de atributos / campos, dezenas ou centenas de métodos e uma definição de classe (para os métodos) de mais de 1000 linhas. Eu vi tudo. Mais de uma vez.

Portanto, a separação do usuário tenta resolver isso. Pode haver pessoa, usuário, conta e a separação de preocupações pode parecer um pouco artificial, mas é para tentar evitar a complexidade e garantir que cada objeto esteja preocupado apenas com um aspecto dos dados.

Michael Durrant
fonte
2
Mesmo a classe de usuários inchada ainda não é necessariamente uma classe de Deus. Pode ficar inchado com a lógica relacionada ao usuário (o que pode ser complicado em grandes projetos), mas se não incorporar lógica não relacionada, não vejo grande problema. Não tenho certeza de como dividir uma classe em duas resolverá o referido problema de classe divina.
187 Andrey