Pergunta

Já fiz muitas aplicações web onde a primeira coisa a fazer é fazer uma tabela de usuário com nomes de usuário, senhas, nomes, e-mails e todos os outros destroços habitual. Meu projeto atual apresenta uma situação em que os registros não-usuários precisam função semelhante para os usuários, mas não precisa a capacidade de ser um usuário de primeira ordem.

É razoável para criar uma tabela segundo, people_tb, que é a principal mesa e armazenar dados relacional, e só usar o users_tb para autenticação? Será que separa user_tb de people_tb presente quaisquer problemas? Se este é comumente feito, quais são algumas estratégias e soluções, bem como desvantagens?

Foi útil?

Solução

Esta é certamente uma boa idéia, como você está normalizar o banco de dados. Eu fiz um projeto similar em um aplicativo que estou escrevendo, onde tenho uma tabela de funcionários e uma tabela de usuário. Os usuários podem a partir de uma empresa externa ou um empregado, então eu tenho mesas separadas, porque um empregado é sempre um usuário, mas um usuário pode não ser um empregado.

As questões que você vai correr em é que sempre que você usar a tabela de usuário, você quase sempre quer tabela pessoa para obter o nome ou outro comum atributos que você gostaria de aparecer.

Do ponto de vista de codificação, se você estiver usando SQL reta, vai demorar um pouco mais de esforço para mentalmente analisar a instrução select. Pode ser um pouco mais complicado se você estiver usando uma biblioteca ORM. Eu não tenho experiência suficiente com aqueles.

Na minha aplicação, eu estou escrevendo isso em Ruby on Rails, por isso estou constantemente fazendo coisas como employee.user.name, onde se manteve juntos, seria apenas employee.name ou user.name.

Do ponto de vista do desempenho, você está batendo duas tabelas em vez de um, mas dada índices adequados, deve ser insignificante. Se você tivesse um índice que continha a chave primária e o nome da pessoa, por exemplo, o banco de dados teria atingido a tabela do usuário, então o índice para a tabela de pessoa (com um golpe quase direto), de modo que o desempenho seria quase o mesmo que ter uma tabela.

Você também pode criar uma exibição no banco de dados para manter ambas as tabelas unidas para dar-lhe melhorias de desempenho adicionais. Eu sei que nas versões posteriores do Oracle você pode até mesmo colocar um índice em uma vista, se necessário para aumentar o desempenho.

Outras dicas

Eu rotineiramente fazer isso porque para mim o conceito de "user" (nome de usuário, senha, data de criação, última data de login) é diferente da "pessoa" (nome, endereço, telefone, e-mail). Uma das desvantagens que você pode encontrar é que suas consultas, muitas vezes, requerem mais junta-se para obter a informação que você está procurando. Se tudo que você tem é um nome de login, você vai precisar para se juntar ao "povo" tabela para obter o primeiro e último nome, por exemplo. Se tudo base em torno da chave primária ID de usuário, isso é mitigado um pouco, mas ainda aparece.

Se user_tb tem auth informação, eu gostaria muito mantê-lo separado de people_tb. No entanto, gostaria manter um relacionamento entre os dois, e na maioria das informações dos usuários seria armazenado em people_tb exceto todas as informações necessárias para autenticação (que eu acho que não vai ser usado para muito mais) Seu uma troca agradável entre design e i eficiência pensa.

Eu sempre tento evitar ao máximo a repetição de dados possível. Se nem todas as pessoas precisam de login, você pode ter uma mesa people genérico com a informação que se aplica a ambos os povos e os usuários (por exemplo. Nome, sobrenome, etc).

Em seguida, para as pessoas que login, você pode ter uma mesa users que tem uma relação de 1 ~ 1 com people. Esta tabela pode armazenar o nome de usuário e senha.

Eu diria que ir para a concepção normalizada (duas mesas) e apenas denormalize (descer para um usuário / table pessoa) se ele vai realmente fazer a sua vida mais fácil para baixo da linha. Se, no entanto, praticamente todas as pessoas são também usuários pode ser mais simples para desnormalizar na frente. Você decide; Eu tenho usado a abordagem normalizada, sem problemas.

Muito razoável.

Como um exemplo, dê uma olhada no aspnet_ * tabelas de serviços aqui .

A construído em esquema tem um aspnet_Users e aspnet_Membership com a mesa posterior tendo informação mais prolongado sobre um determinado utilizador (senhas hash, etc), mas o aspnet_User.UserID é usado nas outras porções do esquema para a integridade referencial etc.

A linha inferior, é muito comum, e um bom design, ter atributos em uma tabela separada, se eles são entidades diferentes, como no seu caso.

Isso é definitivamente o que fazemos como nós temos milhões de registros de pessoas e apenas milhares de usuários. Também separados de endereços, telefones e e-mails em tabelas relacionais, como muitas pessoas têm mais de um de cada uma dessas coisas. Critial é não confiar no nome como o identificador de nome não é único. Certifique-se que as tabelas estão unidas através de algum tipo de chave substituta (um inteiro ou uma GUID é preferível) não nomear.

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