Eu armazeno vários detalhes do usuário em meu banco de dados MySQL. Originalmente, ele foi configurado em várias tabelas, o que significa que os dados são vinculados a UserIds e emitidos por meio de chamadas às vezes complicadas para exibir e manipular os dados conforme necessário. Configurando um novo sistema, quase faz sentido combinar todas essas tabelas em uma grande tabela de conteúdo relacionado.
- Isso vai ser uma ajuda ou um obstáculo?
- Considerações de velocidade na chamada, atualização ou pesquisa / manipulação?
Aqui está um exemplo de algumas das minhas estruturas de tabela:
- usuários - UserId, nome de usuário, e-mail, senha criptografada, data de registro, ip
- user_details - dados de cookies, nome, endereço, detalhes de contato, afiliação, dados demográficos
- user_activity - contribuições, última online, última visualização
- user_settings - configurações de exibição de perfil
- user_interests - variáveis segmentáveis de publicidade
- user_levels - direitos de acesso
- user_stats - hits, contagens
Edit: Eu votei todas as respostas até agora, todas elas têm elementos que essencialmente respondem à minha pergunta.
A maioria das tabelas tem uma relação de 1: 1 que foi o principal motivo para desnormalizá-las.
Haverá problemas se a tabela abranger mais de 100 colunas quando uma grande parte dessas células provavelmente permanecerá vazia?
fonte
Respostas:
Múltiplas tabelas ajudam nas seguintes formas / casos:
(a) se pessoas diferentes irão desenvolver aplicativos envolvendo tabelas diferentes, faz sentido dividi-las.
(b) Se você quiser dar diferentes tipos de autoridades a diferentes pessoas para diferentes partes da coleta de dados, pode ser mais conveniente dividi-las. (Obviamente, você pode examinar a definição de visualizações e dar autorização apropriada para elas).
(c) Para mover dados para locais diferentes, especialmente durante o desenvolvimento, pode fazer sentido usar tabelas que resultem em tamanhos de arquivo menores.
(d) Uma pegada menor pode proporcionar conforto enquanto você desenvolve aplicativos na coleta de dados específicos de uma única entidade.
(e) É uma possibilidade: o que você pensava como um dado de valor único pode acabar sendo, no futuro, realmente valores múltiplos. por exemplo, o limite de crédito é um campo de valor único a partir de agora. Mas amanhã, você pode decidir alterar os valores como (data de, data até, valor de crédito). As tabelas divididas podem ser úteis agora.
Meu voto seria para várias tabelas - com os dados devidamente divididos.
Boa sorte.
fonte
A combinação das tabelas é chamada de desnormalização.
Pode (ou não) ajudar a fazer algumas consultas (que
JOIN
geram muitas s) para serem executadas mais rapidamente ao custo de criar um inferno de manutenção.MySQL
é capaz de usar apenas umJOIN
método, a saberNESTED LOOPS
.Isso significa que, para cada registro na tabela de
MySQL
controle , localiza um registro correspondente na tabela de controle em um loop.Localizar um registro é uma operação bastante cara, que pode demorar dezenas de vezes mais do que a digitalização de um registro puro.
Mover todos os seus registros para uma tabela ajudará você a se livrar dessa operação, mas a própria tabela fica maior e a varredura da tabela leva mais tempo.
Se você tiver muitos registros em outras tabelas, o aumento na varredura da tabela pode sobrecarregar os benefícios dos registros que estão sendo varridos sequencialmente.
O inferno de manutenção, por outro lado, é garantido.
fonte
Todos eles são relacionamentos 1: 1? Quer dizer, se um usuário pudesse pertencer a, digamos, níveis de usuário diferentes, ou se os interesses do usuário fossem representados como vários registros na tabela de interesses do usuário, então mesclar essas tabelas estaria fora de questão imediatamente.
Com relação às respostas anteriores sobre normalização, deve-se dizer que as regras de normalização do banco de dados desconsideraram completamente o desempenho e estão apenas olhando para o que é um design de banco de dados legal. Freqüentemente, é isso que você deseja alcançar, mas há momentos em que faz sentido desnormalizar ativamente em busca de desempenho.
Resumindo, eu diria que a questão se resume a quantos campos existem nas tabelas e com que frequência eles são acessados. Se a atividade do usuário geralmente não é muito interessante, pode ser um incômodo tê-la sempre no mesmo registro, por motivos de desempenho e manutenção. Se alguns dados, como configurações, digamos, são acessados com frequência, mas simplesmente contêm muitos campos, também pode não ser conveniente mesclar as tabelas. Se você está interessado apenas no ganho de desempenho, pode considerar outras abordagens, como manter as configurações separadas, mas salvá-las em uma variável de sessão própria para que não seja necessário consultá-las no banco de dados com frequência.
fonte
3NF
normalização, então se beneficie de uma segunda tabela para resolver isso, mas não parece ser a isso que OP está se referindo com relação às outras tabelas.)Fazer tudo dessas tabelas ter um
1-to-1
relacionamento? Por exemplo, cada linha do usuário terá apenas uma linha correspondente emuser_stats
ouuser_levels
? Nesse caso, pode fazer sentido combiná-los em uma mesa. Se o relacionamento não for1 to 1
, provavelmente não faria sentido combiná-los (desnormalizá-los).Tê-los em tabelas separadas em comparação com uma tabela provavelmente terá pouco efeito no desempenho, a menos que você tenha centenas de milhares ou milhões de registros de usuário. O único ganho real que você obterá é simplificar suas consultas combinando-as.
ETA:
Se sua preocupação é sobre ter muitas colunas , então pense nas coisas que você normalmente usa juntas e combine-as , deixando o resto em uma tabela separada (ou várias tabelas separadas se necessário).
Se você observar a maneira como usa os dados, meu palpite é que você descobrirá que algo como 80% de suas consultas usam 20% desses dados, com os 80% restantes sendo usados apenas ocasionalmente. Combine os 20% usados com frequência em uma tabela e deixe os 80% que você não usa com frequência em tabelas separadas e você provavelmente terá um bom compromisso.
fonte
A criação de uma tabela massiva vai contra os principais do banco de dados relacional. Eu não combinaria todos eles em uma mesa. Você obterá várias instâncias de dados repetidos. Se o seu usuário tem três interesses, por exemplo, você terá 3 linhas, com os mesmos dados do usuário apenas para armazenar os três interesses diferentes. Definitivamente, opte pela abordagem de múltiplas tabelas "normalizadas". Veja esta página do Wiki para normalização do banco de dados.
Edit: Eu atualizei minha resposta, assim como você atualizou sua pergunta ... Concordo com minha resposta inicial ainda mais desde ...
Se por exemplo, um usuário não tinha nenhum interesse, se você normalizar, então você simplesmente não terá uma linha na tabela de interesses para esse usuário. Se você tiver tudo em uma tabela massiva, terá colunas (e aparentemente muitas delas) que contêm apenas NULLs.
Eu trabalhei para uma empresa de telefonia onde havia toneladas de tabelas, a obtenção de dados pode exigir muitas associações. Quando o desempenho da leitura dessas tabelas era crítico, foram criados procedimentos que poderiam gerar uma tabela plana (ou seja, uma tabela desnormalizada) que não exigiria junções, cálculos etc. para os quais os relatórios pudessem apontar. Estes foram usados em conjunto com um agente de servidor SQL para executar o trabalho em determinados intervalos (ou seja, uma exibição semanal de algumas estatísticas seria executada uma vez por semana e assim por diante).
fonte
Por que não usar a mesma abordagem que o Wordpress faz, tendo uma tabela de usuários com informações básicas do usuário que todos possuem e, em seguida, adicionando uma tabela "user_meta" que pode ser basicamente qualquer par de chave e valor associado ao id do usuário. Portanto, se você precisar encontrar todas as meta informações do usuário, basta adicioná-las à sua consulta. Você também não teria sempre que adicionar a consulta extra se não fosse necessário para coisas como fazer login. O benefício dessa abordagem também deixa sua mesa aberta para adicionar novos recursos aos seus usuários, como armazenar o identificador do Twitter ou cada interesse individual. Você também não terá que lidar com um labirinto de IDs associados porque você tem uma tabela que rege todos os metadados e irá limitá-la a apenas uma associação em vez de 50.
O Wordpress faz isso especificamente para permitir que recursos sejam adicionados por meio de plug-ins, portanto, permitindo que seu projeto seja mais escalonável e não exigirá uma revisão completa do banco de dados se você precisar adicionar um novo recurso.
fonte
wp_usermeta
mesa do Wordpress cresce geometricamente. Cada usuário adiciona X linhas àwp_usermeta
tabela, uma linha para cada informação meta que queremos manter para aquele usuário. Se você mantiver 8 campos personalizados para cada usuário, significa que wp_usermeta teráusers * 8
linhas longas. Isso parece estar causando problemas de desempenho, mas não tenho certeza se esse é o problema ou não ...get_users()
) apenas para calcular a paginação. Depois que corrigimos o código para usar umaSELECT COUNT(…)
consulta para a paginação, o tempo de carregamento da página foi de 28 segundos para cerca de 400 ms. Ainda me pergunto como o desempenho se compara a tabelas unidas ou uma única mesa plana ... Tive problemas para encontrar qualquer métrica de desempenho na web.Eu acho que esta é uma daquelas situações "depende". Ter várias tabelas é mais limpo e provavelmente teoricamente melhor. Mas quando você precisa juntar 6 a 7 tabelas para obter informações sobre um único usuário, você pode começar a repensar essa abordagem.
fonte
Eu diria que depende do que as outras tabelas realmente significam. Um user_details contém mais de 1 mais / usuários e assim por diante. O nível de normalização mais adequado para suas necessidades depende de suas demandas.
Se você tiver uma tabela com um bom índice, provavelmente será mais rápido. Mas, por outro lado, provavelmente é mais difícil de manter.
Para mim, parece que você pode pular User_Details, pois provavelmente é uma relação de 1 para 1 com os usuários. Mas o resto são provavelmente muitas linhas por usuário?
fonte