No MySQL 5.7, um novo tipo de dados para armazenar dados JSON em tabelas MySQL foi adicionado. Obviamente, será uma grande mudança no MySQL. Eles listaram alguns benefícios
Validação de documento - apenas documentos JSON válidos podem ser armazenados em uma coluna JSON, para que você obtenha validação automática de seus dados.
Acesso eficiente - mais importante, quando você armazena um documento JSON em uma coluna JSON, ele não é armazenado como um valor de texto simples. Em vez disso, ele é armazenado em um formato binário otimizado que permite acesso mais rápido aos membros do objeto e elementos da matriz.
Desempenho - melhore o desempenho de sua consulta criando índices em valores nas colunas JSON. Isso pode ser alcançado com “índices funcionais” em colunas virtuais.
Conveniência - A sintaxe inline adicional para colunas JSON torna muito natural integrar consultas de documentos em seu SQL. Por exemplo (features.feature é uma coluna JSON):
SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;
UAU ! eles incluem alguns recursos excelentes. Agora é mais fácil manipular dados. Agora é possível armazenar dados mais complexos na coluna. Portanto, o MySQL agora é temperado com NoSQL.
Agora posso imaginar uma consulta de dados JSON algo como
SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN
(
SELECT JSON_EXTRACT(data,"$.inverted")
FROM t1 | {"series": 3, "inverted": 8}
WHERE JSON_EXTRACT(data,"$.inverted")<4 );
Então, posso armazenar pequenas relações enormes em poucos json colum? Isso é bom? Isso quebra a normalização. Se isso for possível, acho que funcionará como NoSQL em uma coluna MySQL . Eu realmente quero saber mais sobre esse recurso. Prós e contras do tipo de dados JSON do MySQL.
Now it is possible to store more complex data in column
. Tenha cuidadoRespostas:
Usar uma coluna dentro de uma expressão ou função como essa estraga qualquer chance de a consulta usar um índice para ajudar a otimizar a consulta. A consulta mostrada acima é forçada a fazer uma varredura de tabela.
A afirmação sobre "acesso eficiente" é enganosa. Isso significa que, após a consulta examinar uma linha com um documento JSON, ela pode extrair um campo sem precisar analisar o texto da sintaxe JSON. Mas ainda é necessária uma varredura de tabela para pesquisar linhas. Em outras palavras, a consulta deve examinar todas as linhas.
Por analogia, se estou pesquisando uma lista telefônica por pessoas com o primeiro nome "Bill", ainda tenho que ler todas as páginas da lista telefônica, mesmo que os primeiros nomes tenham sido destacados para tornar um pouco mais rápido identificá-los.
O MySQL 5.7 permite que você defina uma coluna virtual na tabela e, em seguida, crie um índice na coluna virtual.
Então, se você consultar a coluna virtual, ela pode usar o índice e evitar a varredura da tabela.
Isso é bom, mas meio que perde o sentido de usar JSON. A parte atrativa de usar JSON é que ele permite adicionar novos atributos sem ter que fazer ALTER TABLE. Mas acontece que você precisa definir uma coluna extra (virtual) de qualquer maneira, se quiser pesquisar campos JSON com a ajuda de um índice.
Mas você não precisa definir colunas e índices virtuais para cada campo no documento JSON - apenas aqueles que deseja pesquisar ou classificar. Pode haver outros atributos no JSON que você só precisa extrair na lista de seleção como o seguinte:
Eu geralmente diria que esta é a melhor maneira de usar JSON no MySQL. Apenas na lista de seleção.
Quando você faz referência a colunas em outras cláusulas (JOIN, WHERE, GROUP BY, HAVING, ORDER BY), é mais eficiente usar colunas convencionais, não campos em documentos JSON.
Apresentei uma palestra chamada How to Use JSON in MySQL Wrong na conferência Percona Live em abril de 2018. Atualizarei e repetirei a palestra no Oracle Code One no outono.
Existem outros problemas com JSON. Por exemplo, em meus testes, exigiu 2 a 3 vezes mais espaço de armazenamento para documentos JSON em comparação com colunas convencionais que armazenam os mesmos dados.
O MySQL está promovendo seus novos recursos JSON agressivamente, principalmente para dissuadir as pessoas contra a migração para o MongoDB. Mas o armazenamento de dados orientado a documentos, como o MongoDB, é fundamentalmente uma forma não relacional de organizar dados. É diferente de relacional. Não estou dizendo que um seja melhor do que o outro, é apenas uma técnica diferente, adequada para diferentes tipos de consultas.
Você deve escolher usar JSON quando JSON tornar suas consultas mais eficientes.
Não escolha uma tecnologia apenas porque é nova ou por uma questão de moda.
Editar: A implementação da coluna virtual no MySQL deve usar o índice se sua cláusula WHERE usar exatamente a mesma expressão que a definição da coluna virtual. Ou seja, o seguinte deve usar o índice na coluna virtual, uma vez que a coluna virtual está definida
AS (JSON_EXTRACT(data,"$.series"))
Exceto que eu descobri, testando este recurso, que ele NÃO funciona por algum motivo se a expressão for uma função de extração JSON. Ele funciona para outros tipos de expressões, mas não para funções JSON.
fonte
JOIN
,WHERE
ou outras cláusulas. Basta buscar a coluna JSON na lista de seleção.O seguinte do MySQL 5.7 traz de volta a sensualidade com JSON parece bom para mim:
...
Observe o idioma sobre a validação do documento , pois é um fator importante. Eu acho que uma bateria de testes precisa ser executada para comparações das duas abordagens. Esses dois sendo:
A rede tem slideshares superficiais a partir de agora sobre o tópico mysql / json / performance pelo que estou vendo.
Talvez sua postagem possa ser um centro para isso. Ou talvez o desempenho seja uma reflexão tardia, não tenho certeza, e você está apenas animado para não criar um monte de tabelas.
fonte
[citation required]
você comparou essa unidade com a RAM?Tive esse problema recentemente e resumi as seguintes experiências:
1, Não há como resolver todas as questões. 2, você deve usar o JSON corretamente.
Um caso:
Eu tenho uma tabela chamada:
CustomField
e deve ter duas colunas:name
,fields
.name
é uma string localizada, o conteúdo deve ser:E
fields
deve ser assim:Como você pode ver, tanto o
name
quanto ofields
podem ser salvos como JSON e funciona!No entanto, se eu usar o
name
para pesquisar esta tabela com muita frequência, o que devo fazer? Use oJSON_CONTAINS
,JSON_EXTRACT
...? Obviamente, não é uma boa idéia para salvá-lo como JSON mais, devemos guardá-lo para uma tabela independente:CustomFieldName
.Do caso acima, acho que você deve manter estas idéias em mente:
obrigado
fonte
Pela minha experiência, a implementação JSON pelo menos no MySql 5.7 não é muito útil devido ao seu baixo desempenho. Bem, não é tão ruim para leitura de dados e validação. No entanto, a modificação JSON é 10-20 vezes mais lenta com MySql do que com Python ou PHP. Vamos imaginar um JSON muito simples:
Vamos supor que tenhamos que convertê-lo para algo assim:
Você pode criar um script simples com Python ou PHP que selecionará todas as linhas e as atualizará uma por uma. Você não é forçado a fazer uma grande transação para ele, então outros aplicativos podem usar a tabela em paralelo. Claro, você também pode fazer uma grande transação se quiser, então você terá a garantia de que o MySql executará "tudo ou nada", mas outros aplicativos provavelmente não serão capazes de usar o banco de dados durante a execução da transação.
Tenho uma tabela de 40 milhões de linhas e o script Python a atualiza em 3-4 horas.
Agora temos MySql JSON, então não precisamos mais de Python ou PHP, podemos fazer algo assim:
Parece simples e excelente. No entanto, sua velocidade é 10-20 vezes mais lenta do que a versão Python, e é uma transação única, portanto, outros aplicativos não podem modificar os dados da tabela em paralelo.
Portanto, se quisermos apenas duplicar a chave JSON em uma tabela de 40 milhões de linhas, não precisamos usar a tabela durante 30-40 horas. Não tem sentido.
Sobre a leitura de dados, pela minha experiência, o acesso direto ao campo JSON via
JSON_EXTRACT
inWHERE
também é extremamente lento (muito mais lento do queTEXT
com umaLIKE
coluna não indexada). As colunas geradas virtuais têm um desempenho muito mais rápido, no entanto, se conhecermos nossa estrutura de dados de antemão, não precisamos de JSON, podemos usar colunas tradicionais. Quando usamos JSON onde é realmente útil, ou seja, quando a estrutura de dados é desconhecida ou muda com frequência (por exemplo, configurações de plug-in personalizado), a criação de colunas virtuais regularmente para quaisquer novas colunas possíveis não parece uma boa ideia.Python e PHP tornam a validação JSON um encanto, então é questionável se precisamos de validação JSON no lado do MySql. Por que não validar também XML, documentos do Microsoft Office ou verificar a ortografia? ;)
fonte