Qual é a forma normal de JSON?
Vai parecer uma pergunta trivial, mas gosto de pensar que é realmente profunda. A pergunta simples é: "Qual é a forma normal de um objeto JSON típico?" Para referência, coloco um exemplo abaixo, mas considere qualquer objeto JSON típico com o qual você tenha lidado, a mesma pergunta se aplica.
Eu faço esta pergunta teórica por uma razão prática. Na prática, muitas vezes precisamos converter objetos JSON em algum conjunto de tabelas. Uma vez que são tabelas, as tabelas têm formas normais mensuráveis com base em todas as regras usuais das formas normais.
Mas chegar a essas tabelas com sua forma normal dá trabalho. Agora, o que mais "dá trabalho". Resposta: passando de formas normais inferiores para formas normais superiores. O que não "dá trabalho", está indo para as formas normais. Ou pelo menos uma quantidade trivial de trabalho. Ou seja, se eu tiver 6NF, posso manipular rapidamente meu caminho para qualquer forma normal inferior. Se eu tiver, digamos 2NF, e precisar trabalhar meu caminho para pelo menos 5NF por alguma razão prática, tenho muito trabalho a fazer.
Bem ... já que é bastante difícil levar JSON a qualquer forma normal decente, intuitivamente parece que deve estar em uma forma normal muito baixa. Espero que alguém aqui possa quantificar essa forma normal do JSON . Muito apreciado.
Mas ainda não dei a justificativa mais crítica. Não é incomum que líderes não técnicos peçam milagres. Não estou criticando, todos nós sabemos que acontece. E o milagre é algo na forma, "basta escrever algum código para transformar JSON automaticamente em tabelas".
Mas espere! Se minha teoria estiver correta e JSON for basicamente 0NF ou algo assim, então você não pode automatizar sua saída. Você não pode ir de um NF de JSON muito baixo para algo decente, como 3NF +, em um fashing automatizado porque isso "dá trabalho". Ou seja, são necessários humanos inteligentes para entender o domínio.
Agora, eu sei que alguns JSON triviais podem se tornar algumas tabelas triviais. Eu sei que existem algumas ferramentas que lidam com casos simples. Mas eu acredito que um conversor JSON para Tabela de propósito geral não é teoricamente possível porque JSON é tão baixo nas informações de normalização (no sentido rigoroso de Claude Shannon), que você não pode automatizá-lo.
Então, qual é a forma normal de um objeto JSON típico ? E há alguma teoria que eu não descobri que já prova que você não pode automatizar sua saída disso.
Obrigado!
{
"data": {
"cust1": {
"name": "Jane",
"age": 33,
"address": "Main Street",
"favorites": {
"colors": ["blue", "green"]
}
},
"cust2": {
"name": "Joe",
"age": 44,
"address": "West Road",
"favorites": {
"colors": ["red", "yellow"]
}
}
}
}
Respostas
Em resumo
JSON é uma representação de dados de acordo com uma sintaxe sem esquema sem semântica predefinida. Por outro lado, as formas normais são definidas para o modelo de dados abstrato com uma semântica relacional de acordo com um esquema fixo. Portanto, não faz sentido aplicar formulários normais a JSON.
No entanto, você pode adicionar um esquema ou alguma semântica ao formato JSON que permitiria a análise normal do formulário. Mas, apesar da viabilidade, geralmente é de pouco benefício, porque um modelo de objeto rico com objetos aninhados e relacionados destina-se a expressar dados autocontidos de maneira diferente e mais flexível do que por meio de relações tabulares predefinidas fixas.
Mais detalhes
Isso faz sentido?
A forma normal foi inventada no contexto de modelos relacionais pelo pioneiro Edgar F. Codd . A teoria da álgebra relacional não é sobre tabelas e colunas, mas sobre relações abstratas, atributos e conjuntos (que podem ser facilmente representados com tabelas). A forma normal é sobre os dados (tuplas) nas relações, a forma de seus atributos e suas interdependências.
JSON não é um modelo, mas uma representação de dados com uma sintaxe precisa, mas sem semântica definida. Não há regra sobre como relacionar dois objetos diferentes: cada JSON representa um objeto diferente e pode representar uma relação única, feita de uma única tupla e não relacionada a nenhuma outra, ou representar um conjunto de instâncias relacionadas de uma relação.
Conclusão: o conceito de forma normal não se aplica a objetos JSON, porque é definido para um modelo relacional e JSON é usado em modelos radicalmente diferentes (normalmente o modelo de documento).
Isso poderia fazer sentido?
Nada impede que você adicione alguma semântica à sintaxe JSON. Não é raro que um conjunto de documentos JSON esteja relacionado e represente tuplas da mesma relação, e que elementos que compartilham o mesmo nome correspondam ao mesmo atributo e tenham seus valores potenciais no mesmo domínio (seguindo um esquema implícito ou explícito ) . Na verdade, seu exemplo usa JSON exatamente dessa maneira.
Em que nível a forma normal deve ser considerada?
- Você considera o próprio objeto JSON como um único atributo em uma relação? Uma vez que não é elementar / atômico, mas feito de uma agregação de vários elementos, seria de fato UNF.
- Você considera o JSON como uma tupla? Afinal, Codd observou tuplas
(a,b,c)usando a ordem dos nomes dos atributos(p1,p2, p3)e nunca fingiu que uma tupla era UNF. Portanto,{p1:a, p2:b, p3:c}poderia facilmente ser considerado 1NF se cada um de seus elementos elementares / atômicos.
No segundo caso, existem no entanto mais algumas questões. E se:
- alguns elementos são objetos aninhados: estes não são atômicos. Portanto, devemos considerá-los como uma relação separada e aplicar a regra sobre a forma normal recursivamente, olhando dentro do JSON incorporado? Ou concluímos que qualquer JSON contendo um JSON incorporado não está mais em 1NF?
- alguns elementos são arrays: também não são atômicos. Então, você considera que não é apenas a forma normal ou considera o array como uma relação definida por tuplas fechadas e então olha recursivamente para cada elemento do array?
Conclusão: A adoção de algumas semânticas para a sintaxe JSON permite aplicar a análise de forma normal.
Como estender a forma normal para JSON?
Na prática, com a semântica definida na seção anterior e escolhendo a análise recursiva para as questões abertas, você define um mapeamento entre seus JSONs e um formulário relacional . Na verdade, uma equipe de pesquisadores de Yale até publicou um artigo para descrever esse algoritmo .
Com esse mapeamento, você pode apenas aplicar os critérios de forma normal ao modelo relacional mapeado para categorizar sua representação JSON.
Por exemplo, este JSON:
{ customers: [ { id:1, name:"Smith", turnover:324233.22},
{ id:2, name:"Wesson", turnover:1600256.00} ],
products: [ { id:1234, label:"Screwdriver", lauched: { y:2019,m:9 }},
{ id:1235, label:"Hammer (row)", lauched: { y:2011,m:1 }} ]
}
poderia ter o seguinte mapeamento relacional:
TABLE CUSTOMERS (id, name, turnover);
TABLE PRODUCTS (id, label);
TABLE PRODUCT-LAUNCH (product-id, year, month);
Então você poderia alegar que JSON é BCNF , porque o mapeamento relacional possui tabelas apenas com atributos atômicos, que os atributos de cada tabela dependem exclusivamente da chave primária e não de uma parte da chave primária, que obviamente não há dependência transitiva, .. .
Mas qual é o benefício?
Afirmo que a forma normal de JSON na maioria dos casos não traz nenhum benefício :
Se você escolheu uma codificação JSON e uma base de dados de documentos NOSQL, é porque deseja se livrar do modelo relacional. Não porque o modelo relacional seria ruim (na verdade, ele é excelente e obteve um desempenho excepcional em domínios onde se ajusta às necessidades), mas porque o modelo relacional provavelmente não atende às suas necessidades específicas. Portanto, não faz sentido introduzir restrições artificiais.
Se todo o seu design é baseado em objetos de negócios ricos e você não deseja achatá-los e reidratá-los por meio de uma camada ORM , a forma normal não o ajudará: seus objetos são independentes e a redundância pode não importar da mesma forma que nas tabelas. É exatamente por isso que geralmente é analisado caso a caso para implementar associações um-para-muitos em um banco de dados de documentos, ou seja, documentos embutidos versus referências a outros documentos .
Conclusão: A forma normal em geral não adiciona benefícios ao JSON, a menos que você precise fazer ORM. No entanto, os pensamentos sobre redundâncias e dependências funcionais, que são ingredientes centrais das formas normais, podem ajudar a avaliar os limites entre os objetos.
Zeroth.
A primeira forma normal diz que os dados devem ser atômicos. Como em um único booleano, um único número. Mesmo uma única string já é questionável. Depende de como ela é usada, uma string pode ser usada para representar algo, caso em que não é mais um dado realmente atômico. Na verdade, até mesmo um número pode ser usado dessa forma.
Portanto, em geral , um documento JSON está na forma normal zero porque é, bem, um documento, não um único valor atômico.
Ele é possível ter um documento JSON na Primeira forma normal, por exemplo, este documento:
true
No entanto, mesmo este documento já não está mais na primeira forma normal:
{ "property": true }
Não é um valor de dados atômico, é um objeto que contém um par de valores de chave em que a chave é uma string e o valor é um booleano.
É claro que, na verdade , a definição de Primeira Forma Normal fala explicitamente sobre Relações (ou Tabelas) e, portanto, a resposta real é: JSON não tem Relações ou Tabelas, então a própria questão não faz sentido.
Esta é realmente uma questão complicada, uma vez que a normalização e as formas normais são definidas em termos de relações e tuplas (isto é, tabelas com colunas digitadas). Portanto, você não pode realmente falar sobre a forma normal de dados de estruturas de árvore como o exemplo Json.
Os dados devem estar em forma de tabela antes que você possa falar de forma significativa sobre formulários normais. Não se pode dizer que o JSON em si tenha qualquer forma normal.
Se você colocar o JSON na forma de tabela, obterá:
id | name | age | address | favorite colors
--------------------------------------------------
cust1 | Jane | 33 | Main Street | blue, green
cust2 | Joe | 44 | West Road | red, yellow
A coluna "favorita" quebra a primeira forma normal por ter vários valores. Portanto, a tabela não está nem na primeira forma normal. Isso às vezes é chamado de forma normal zero ou 0NF.
Você questiona se uma tradução de JSON em formato de tabela 0NF pode ser feita automaticamente ou requer conhecimento de domínio. Direi que isso pode ser feito automaticamente de várias maneiras. Qualquer estrutura JSON arbitrária pode ser representada como tabelas. Acontece apenas que as tabelas resultantes serão 0NF e, portanto, sujeitas a todos os problemas de dados desnormalizados. Portanto, não é algo que eu recomendaria.
Um exemplo poderia ser uma tabela com o formato:
node id | name | type | value | parent node id
------------------------------------------------
1 | data | object | | NULL
2 | cust1 | object | | 1
3 | name | string | Jane | 2
E assim por diante. Isso seria capaz de representar qualquer carga JSON, mas também seria extremamente tedioso para consultar.