Estou implementando o seguinte modelo para armazenar dados relacionados ao usuário em minha tabela - eu tenho 2 colunas - uid
(chave primária) e uma meta
coluna que armazena outros dados sobre o usuário no formato JSON.
uid | meta
--------------------------------------------------
1 | {name:['foo'],
| emailid:['[email protected]','[email protected]']}
--------------------------------------------------
2 | {name:['sann'],
| emailid:['[email protected]','[email protected]']}
--------------------------------------------------
É este um caminho melhor (em termos de performance, design-wise) do que o modelo de uma coluna-per-propriedade, onde a mesa terá muitas colunas como uid
, name
, emailid
.
O que eu gosto no primeiro modelo é que você pode adicionar o maior número possível de campos, sem limitações.
Além disso, eu estava pensando, agora que implementei o primeiro modelo. Como faço para executar uma consulta, como, eu quero buscar todos os usuários que têm nome como 'foo'?
Pergunta - Qual é a melhor maneira de armazenar dados relacionados ao usuário (lembrando que o número de campos não é fixo) no banco de dados usando - JSON ou coluna por campo? Além disso, se o primeiro modelo for implementado, como consultar o banco de dados conforme descrito acima? Devo usar os dois modelos, armazenando todos os dados que podem ser pesquisados por uma consulta em uma linha separada e os outros dados em JSON (é uma linha diferente)?
Atualizar
Como não haverá muitas colunas nas quais eu preciso executar a pesquisa, é aconselhável usar os dois modelos? Chave por coluna para os dados que preciso pesquisar e JSON por outros (no mesmo banco de dados MySQL)?
fonte
Respostas:
Actualizado 4 de junho de 2017
Como essa pergunta / resposta ganhou popularidade, achei que valeria a pena ser atualizado.
Quando esta pergunta foi publicada originalmente, o MySQL não tinha suporte para tipos de dados JSON e o suporte no PostgreSQL estava em sua infância. Desde 5.7, o MySQL agora suporta um tipo de dados JSON (em um formato de armazenamento binário) e o PostgreSQL JSONB amadureceu significativamente. Ambos os produtos fornecem tipos JSON de alto desempenho que podem armazenar documentos arbitrários, incluindo suporte para indexar chaves específicas do objeto JSON.
No entanto, continuo defendendo minha afirmação original de que sua preferência padrão, ao usar um banco de dados relacional, ainda deve ser coluna por valor. Os bancos de dados relacionais ainda são construídos com a suposição de que os dados dentro deles serão razoavelmente bem normalizados. O planejador de consultas possui melhores informações de otimização ao examinar colunas do que ao examinar chaves em um documento JSON. Chaves estrangeiras podem ser criadas entre colunas (mas não entre chaves em documentos JSON). Importante: se a maioria do seu esquema for volátil o suficiente para justificar o uso de JSON, convém pelo menos considerar se um banco de dados relacional é a escolha certa.
Dito isto, poucas aplicações são perfeitamente relacionais ou orientadas a documentos. A maioria dos aplicativos possui uma mistura de ambos. Aqui estão alguns exemplos em que eu pessoalmente achei o JSON útil em um banco de dados relacional:
Ao armazenar endereços de email e números de telefone para um contato, é muito mais fácil gerenciar o armazenamento deles como valores em uma matriz JSON do que em várias tabelas separadas
Salvando preferências arbitrárias do usuário da chave / valor (onde o valor pode ser booleano, textual ou numérico e você não deseja ter colunas separadas para diferentes tipos de dados)
Armazenando dados de configuração que não possuem esquema definido (se você estiver criando o Zapier ou o IFTTT e precisar armazenar dados de configuração para cada integração)
Tenho certeza de que existem outros também, mas esses são apenas alguns exemplos rápidos.
Resposta original
Se você realmente deseja adicionar quantos campos quiser, sem limitação (que não seja um limite arbitrário de tamanho de documento), considere uma solução NoSQL como o MongoDB.
Para bancos de dados relacionais: use uma coluna por valor. Colocar um blob JSON em uma coluna torna praticamente impossível consultar (e muito lento quando você realmente encontra uma consulta que funciona).
Os bancos de dados relacionais aproveitam os tipos de dados durante a indexação e devem ser implementados com uma estrutura normalizada .
Como uma observação lateral: isso não significa que você nunca deve armazenar JSON em um banco de dados relacional. Se você estiver adicionando metadados verdadeiros ou se o seu JSON estiver descrevendo informações que não precisam ser consultadas e são usadas apenas para exibição, pode ser um exagero criar uma coluna separada para todos os pontos de dados.
fonte
virtually impossible to query
" - hoje psql permite-lhe procurar e indexar seu jsonb"For relational databases"
em sua resposta = PComo a maioria das coisas "depende". Não é certo ou errado / bom ou ruim por si só armazenar dados em colunas ou JSON. Depende do que você precisa fazer com isso mais tarde. Qual é a sua maneira prevista de acessar esses dados? Você precisará cruzar outros dados?
Outras pessoas responderam muito bem quais são as vantagens técnicas.
Poucas pessoas discutiram que seu aplicativo e recursos evoluem com o tempo e como essa decisão de armazenamento de dados afeta sua equipe.
Como uma das tentações de usar o JSON é evitar a migração do esquema e, portanto, se a equipe não for disciplinada, é muito fácil colar outro par de chave / valor em um campo JSON. Não há migração para isso, ninguém se lembra para que serve. Não há validação nele.
Minha equipe usou o JSON ao longo das colunas tradicionais no postgres e, a princípio, era a melhor coisa desde o pão fatiado. O JSON era atraente e poderoso, até que um dia percebemos que a flexibilidade tinha um custo e, de repente, é um verdadeiro problema. Às vezes, esse ponto surge muito rapidamente e fica difícil mudar, porque criamos muitas outras coisas em cima dessa decisão de design.
Horas extras, adicionando novos recursos, tendo os dados em JSON, resultaram em consultas de aparência mais complicada do que o que poderia ter sido adicionado se mantivéssemos as colunas tradicionais. Então começamos a pescar certos valores-chave em colunas para que pudéssemos fazer junções e fazer comparações entre valores. Péssima ideia. Agora tivemos duplicação. Um novo desenvolvedor viria a bordo e ficaria confuso? Qual é o valor que eu devo salvar novamente? O JSON ou a coluna?
Os campos JSON tornaram-se gavetas de lixo eletrônico para pequenos pedaços disso e daquilo. Sem validação de dados no nível do banco de dados, sem consistência ou integridade entre documentos. Isso empurrou toda essa responsabilidade para o aplicativo, em vez de obter uma verificação rígida de tipo e restrição de colunas tradicionais.
Olhando para trás, o JSON nos permitiu iterar muito rapidamente e obter algo fora da porta. Foi ótimo. No entanto, depois que atingimos um determinado tamanho de equipe, a flexibilidade também nos permitiu ficar com uma longa corda de dívida técnica, que diminuiu o progresso subsequente na evolução dos recursos. Use com cuidado.
Pense muito sobre qual é a natureza dos seus dados. É a base do seu aplicativo. Como os dados serão usados ao longo do tempo. E como é provável que mude?
fonte
Apenas lançando-o por aí, mas o WordPress tem uma estrutura para esse tipo de coisa (pelo menos o WordPress foi o primeiro lugar em que o observei, provavelmente se originou em outro lugar).
Ele permite chaves ilimitadas e é mais rápido pesquisar do que usar um blob JSON, mas não tão rápido quanto algumas das soluções NoSQL.
EDITAR
Para armazenar histórico / várias chaves
e consulta através de algo como isto:
fonte
emailid
chave no exemplo que dei na minha pergunta.a desvantagem da abordagem é exatamente o que você mencionou:
torna MUITO lento encontrar coisas, pois cada vez que você precisa fazer uma pesquisa de texto nela.
o valor por coluna corresponde à sequência inteira.
Sua abordagem (dados baseados em JSON) é adequada para dados pelos quais você não precisa pesquisar e só precisa exibir junto com seus dados normais.
Edit: Apenas para esclarecer, o exposto acima vale para bancos de dados relacionais clássicos. O NoSQL usa JSON internamente e provavelmente é uma opção melhor se esse for o comportamento desejado.
fonte
Basicamente, o primeiro modelo que você está usando é chamado de armazenamento baseado em documento. Você deve dar uma olhada no popular banco de dados NoSQL baseado em documentos, como MongoDB e CouchDB . Basicamente, nos bancos de dados baseados em documentos, você armazena dados em arquivos json e pode consultar esses arquivos json.
O segundo modelo é a estrutura popular de banco de dados relacional.
Se você quiser usar o banco de dados relacional como o MySql, sugiro que você use apenas o segundo modelo. Não faz sentido usar o MySql e armazenar dados como no primeiro modelo .
Para responder sua segunda pergunta, não há como consultar um nome como 'foo' se você usar o primeiro modelo .
fonte
Parece que você está principalmente hesitando em usar ou não um modelo relacional.
Tal como está, seu exemplo se encaixaria razoavelmente bem em um modelo relacional, mas o problema pode surgir naturalmente quando você precisar fazer esse modelo evoluir.
Se você tiver apenas um (ou alguns níveis predeterminados) de atributos para sua entidade principal (usuário), ainda poderá usar um modelo de valor de atributo de entidade (EAV) em um banco de dados relacional. (Isso também tem seus prós e contras.)
Se você prevê que obterá valores menos estruturados que deseja pesquisar usando seu aplicativo, o MySQL pode não ser a melhor opção aqui.
Se você estivesse usando o PostgreSQL, poderia obter o melhor dos dois mundos. (Isso realmente depende da estrutura real dos dados aqui ... O MySQL também não é necessariamente a escolha errada, e as opções NoSQL podem ser de seu interesse, só estou sugerindo alternativas.)
De fato, o PostgreSQL pode criar índice em funções (imutáveis) (que o MySQL não pode, tanto quanto eu sei) e em versões recentes, você pode usar o PLV8 nos dados JSON diretamente para criar índices em elementos JSON específicos de interesse, o que melhoraria a velocidade das suas consultas ao pesquisar esses dados.
EDITAR:
A mistura dos dois modelos não é necessariamente errada (assumindo que o espaço extra é desprezível), mas pode causar problemas se você não garantir que os dois conjuntos de dados sejam mantidos sincronizados: seu aplicativo nunca deve alterar um sem também atualizar o outro .
Uma boa maneira de conseguir isso seria fazer com que um gatilho execute a atualização automática executando um procedimento armazenado no servidor de banco de dados sempre que uma atualização ou inserção for feita. Tanto quanto sei, a linguagem de procedimentos armazenados do MySQL provavelmente não possui suporte para qualquer tipo de processamento JSON. Novamente, o PostgreSQL com suporte a PLV8 (e possivelmente outros RDBMS com linguagens de procedimento armazenado mais flexíveis) deve ser mais útil (atualizar sua coluna relacional automaticamente usando um gatilho é bastante semelhante a atualizar um índice da mesma maneira).
fonte
algum tempo na mesa será uma sobrecarga. vamos dizer para OLAP. se eu tiver duas tabelas, uma é a tabela ORDERS e a outra é ORDER_DETAILS. Para obter todos os detalhes do pedido, precisamos unir duas tabelas, o que tornará a consulta mais lenta quando não aumentar o número de linhas nas tabelas, digamos milhões ou mais .. a junção esquerda / direita é muito mais lenta que a junção interna. Acho que se adicionarmos JSON string / Object na respectiva entrada ORDERS, JOIN será evitado. adicionar geração de relatórios será mais rápido ...
fonte
resposta curta que você precisa misturar entre eles, use json para dados que você não fará relações com eles, como dados de contato, endereço, variáveis de produtos
fonte
Você está tentando ajustar um modelo não-relacional em um banco de dados relacional, acho que você seria melhor atendido usando um banco de dados NoSQL, como MongoDB . Não existe um esquema predefinido que atenda ao seu requisito de não ter limitação ao número de campos (consulte o exemplo típico da coleção do MongoDB). Confira a documentação do MongoDB para ter uma idéia de como você consultaria seus documentos, por exemplo,
fonte
Como outros já apontaram, as consultas serão mais lentas. Eu sugiro adicionar pelo menos uma coluna '_ID' para consulta por isso.
fonte