Какая обычная форма JSON?
Это прозвучит тривиально, но мне нравится думать, что это действительно глубокий вопрос. Простой вопрос: «Какова нормальная форма типичного объекта JSON?» Для справки я привожу пример ниже, но рассмотрите любой типичный объект JSON, с которым вы имели дело, применим тот же вопрос.
Я задаю этот теоретический вопрос из практических соображений. На практике нам часто требуется преобразовать объекты JSON в некоторый набор таблиц. Как только они являются таблицами, они имеют измеримые нормальные формы, основанные на всех обычных правилах нормальных форм.
Но чтобы добраться до этих таблиц в их нормальной форме, нужно потрудиться. Теперь о том, что еще «требует работы». Ответ: переход от низших нормальных форм к высшим нормальным формам. Что не «требует работы», так это нормальные формы. Или хотя бы тривиальный объем работы. То есть, если у меня есть 6НФ, я могу довольно быстро перейти к любой более низкой нормальной форме. Если у меня есть, скажем, 2NF, и мне нужно работать, по крайней мере, до 5NF по какой-то практической причине, у меня много работы.
Что ж ... поскольку довольно сложно привести JSON в какую-либо приличную нормальную форму, интуитивно кажется, что он должен быть в очень низкой нормальной форме. Я надеюсь, что кто-то здесь сможет количественно оценить эту нормальную форму JSON . Многое оценено.
Но я до сих пор не дал самого критического обоснования. Нетехнические лидеры нередко просят о чудесах. Я не критикую, мы все знаем, что такое бывает. И чудо - это что-то вроде того, «просто напишите код, чтобы автоматически преобразовывать JSON в таблицы».
Но ждать! Если моя теория верна, и JSON в основном 0NF или около того, то вы не можете автоматизировать выход из него. Вы не можете перейти от очень низкого NF JSON к чему-либо приличному, например, 3NF +, в автоматическом прошивке, потому что это «требует работы». То есть нужны умные люди, разбирающиеся в предметной области.
Теперь я знаю, что некоторые тривиальные JSON могут превратиться в тривиальные таблицы. Я знаю, что есть несколько инструментов для простых случаев. Но я считаю, что преобразователь JSON-to-Table общего назначения теоретически невозможен, потому что JSON настолько мало информации о нормализации (в строгом смысле Клода Шеннона), что вы не можете автоматизировать его.
Итак, какова нормальная форма типичного объекта JSON ? И есть какая-то теория, которую я не нашел, которая уже доказывает, что вы не можете автоматизировать выход из этого.
Благодаря!
{
"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"]
}
}
}
}
Ответы
Коротко
JSON - это представление данных в соответствии с синтаксисом без схемы без предопределенной семантики. Напротив, нормальные формы определены для абстрактной модели данных с реляционной семантикой в соответствии с фиксированной схемой. Поэтому применять к JSON обычные формы не имеет смысла.
Однако вы можете добавить схему или некоторую семантику в свой формат JSON, которые позволят анализировать нормальную форму. Но, несмотря на осуществимость, это обычно не приносит большой пользы, потому что богатая объектная модель с вложенными и связанными объектами предназначена для выражения автономных данных по-другому и более гибко, чем через фиксированные предопределенные табличные отношения.
Подробнее
Имеет ли это смысл?
Нормальная форма была изобретена в контексте реляционных моделей пионером Эдгаром Ф. Коддом . Теория реляционной алгебры - это не таблицы и столбцы, а абстрактные отношения, атрибуты и множества (которые легко могут быть представлены в виде таблиц). Нормальная форма - это данные (кортежи) в отношениях, форма их атрибутов и их взаимозависимости.
JSON - это не модель, а представление данных с точным синтаксисом, но без определенной семантики. Не существует правила о том, как связать два разных объекта: каждый JSON представляет отдельный объект и может представлять уникальное отношение, состоящее из одного кортежа и не связанное ни с каким другим, или представлять набор связанных экземпляров отношения.
Вывод: концепция нормальной формы не применяется к объектам JSON, поскольку она определена для реляционной модели, а JSON используется в радикально разных моделях (обычно в модели документа).
Может ли это иметь смысл?
Ничто не мешает добавить семантику в синтаксис JSON. Нередко набор документов JSON связан и представляет собой кортежи одного и того же отношения, а элементы с одинаковым именем соответствуют одному и тому же атрибуту и имеют свои потенциальные значения в одном домене (согласно неявной или явной схеме ) . Фактически, ваш пример использует JSON именно так.
На каком уровне следует рассматривать нормальную форму?
- Считаете ли вы сам объект JSON как отдельный атрибут в отношении? Поскольку он не элементарный / атомарный, а состоит из совокупности нескольких элементов, это действительно будет UNF.
- Считаете ли вы JSON кортежем? В конце концов, Кодд отмечал кортежи,
(a,b,c)используя порядок имен атрибутов,(p1,p2, p3)и никогда не притворялся, что кортеж является UNF. Так{p1:a, p2:b, p3:c}что легко можно было бы считать 1НФ, если каждый его элементарный / атомарный.
Однако во втором случае есть еще несколько вопросов. Что если:
- некоторые элементы являются вложенными объектами: они не атомарны. Итак, рассматриваем ли мы их как отдельное отношение и рекурсивно применяем правило о нормальной форме, просматривая встроенный JSON? Или мы делаем вывод, что любого JSON, содержащего встроенный JSON, больше нет в 1NF?
- некоторые элементы являются массивами: они тоже не атомарны. Итак, считаете ли вы, что это просто ненормальная форма, или вы рассматриваете массив как отношение, определяемое заключенными кортежами, а затем рекурсивно просматриваете каждый элемент массива?
Вывод: Принятие некоторой семантики к синтаксису JSON позволяет применять анализ нормальной формы.
Как расширить обычную форму до JSON?
На практике, используя семантику, определенную в предыдущем разделе, и выбирая рекурсивный анализ для открытых вопросов, вы определяете соответствие между вашими JSON и реляционной формой . Фактически, группа исследователей из Йельского университета даже опубликовала статью с описанием такого алгоритма .
С таким отображением вы можете просто применить критерии нормальной формы к сопоставленной реляционной модели, чтобы категоризировать ваше представление JSON.
Например, этот 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 }} ]
}
может иметь следующее реляционное отображение:
TABLE CUSTOMERS (id, name, turnover);
TABLE PRODUCTS (id, label);
TABLE PRODUCT-LAUNCH (product-id, year, month);
Таким образом, вы можете утверждать, что JSON - это BCNF , потому что реляционное сопоставление имеет таблицы только с атомарными атрибутами, что атрибуты каждой таблицы зависят исключительно от первичного ключа, а не от части первичного ключа, что, очевидно, нет транзитивной зависимости, .. .
Но в чем польза?
Я утверждаю, что обычная форма для JSON в большинстве случаев не имеет никакой пользы :
Если вы выбрали кодировку JSON и базу данных документов NOSQL, это потому, что вы хотите освободиться от реляционной модели. Не потому, что реляционная модель была бы плохой (на самом деле она превосходна и обеспечивала выдающуюся производительность в тех областях, где она соответствует потребностям), а потому, что реляционная модель, вероятно, не соответствует вашим конкретным потребностям. В таком случае нет смысла вводить искусственные ограничения.
Если весь ваш дизайн основан на богатых бизнес-объектах, и вы не хотите сглаживать и восстанавливать их через слой ORM , обычная форма вам не поможет: ваши объекты являются самодостаточными, а избыточность может не иметь такого же значения, как и в таблицах. Именно поэтому обычно анализируется от случая к случаю, особенно для реализации ассоциаций «один ко многим» в базе данных документов, то есть встроенных документов по сравнению со ссылками на другие документы .
Вывод: Обычная форма, как правило, не добавляет преимуществ JSON, если вам не нужно использовать ORM. Однако мысли об избыточности и функциональных зависимостях, которые являются ключевыми ингредиентами нормальных форм, могут помочь оценить границы между объектами.
Zeroth.
Первая нормальная форма говорит, что данные должны быть атомарными. Как и одно логическое значение, одно число. Даже одна строка уже вызывает сомнения. Это зависит от того, как она используется, строка может использоваться для представления чего-либо, и в этом случае это больше не атомарные данные. Фактически, таким образом можно было использовать даже число.
Итак, в общем , документ JSON находится в нулевой нормальной форме, потому что это, ну, документ, а не одно атомарное значение.
Это есть возможность иметь документ JSON в первой нормальной форме, например , в этом документе:
true
Однако даже этот документ уже не в Первой нормальной форме:
{ "property": true }
Это не атомарное значение данных, это объект, содержащий пару «ключ-значение», где ключ является строкой, а значение является логическим.
Конечно, на самом деле определение Первой нормальной формы явно говорит об отношениях (или таблицах), и поэтому реальный ответ таков: JSON не имеет отношений или таблиц, поэтому сам вопрос не имеет смысла.
На самом деле это сложный вопрос, поскольку нормализация и нормальные формы определяются в терминах отношений и кортежей (т. Е. Таблиц с типизированными столбцами). Таким образом, вы не можете говорить о нормальной форме данных древовидной структуры, такой как пример Json.
Прежде чем вы сможете осмысленно говорить о нормальных формах, данные должны быть в виде таблицы. Сам JSON нельзя сказать , чтобы иметь любую нормальную форму.
Если вы поместите JSON в виде таблицы, вы получите:
id | name | age | address | favorite colors
--------------------------------------------------
cust1 | Jane | 33 | Main Street | blue, green
cust2 | Joe | 44 | West Road | red, yellow
Столбец «избранное» нарушает первую нормальную форму, имея несколько значений. Так что таблица даже не в первой нормальной форме. Иногда это называют нулевой нормальной формой или 0NF.
Вы спрашиваете, может ли перевод из JSON в табличную форму 0NF выполняться автоматически или требует знания предметной области. Я скажу, что это можно сделать автоматически несколькими способами. Любая произвольная структура JSON может быть представлена в виде таблиц. Просто результирующие таблицы будут 0NF и, следовательно, будут подвержены всем проблемам денормализованных данных. Так что это не то, что я бы рекомендовал.
Примером может служить таблица вида:
node id | name | type | value | parent node id
------------------------------------------------
1 | data | object | | NULL
2 | cust1 | object | | 1
3 | name | string | Jane | 2
И так далее. Это могло бы представлять любую полезную нагрузку JSON, но также было бы чрезвычайно утомительно для запроса.