Статьи

Решение проблем «разнообразия» с помощью Nog-расширений Postgres

Поднимите руку, если вы слышали три «V» больших данных?

  • Скорость — ваш запрос / обновления исключительно быстрые или большие. Ваша обработка всего твиттера.
  • Объем — вы храните огромное количество данных в состоянии покоя. Вы сканировали сеть и храните всю сеть в базе данных.
  • Разнообразие — структура записей сильно различается. Вам нужно хранить информацию о людях, но в редких случаях вы хотели бы узнать об их питомцах, их именах, иногда именах ветеринаров их питомцев, иногда девичьей фамилии их матери.

Три «V» являются важной частью нашей работы, помогая клиентам понять, нужен ли им NoSQL или нет. У многих клиентов возникают проблемы, такие как:

Помогите нам с разнообразием! На самом деле у нас нет проблем с масштабированием объема / скорости, но наша модель данных становится странной. Мы думаем, что должны перейти от нашего реляционного решения к NoSQL из-за нашего динамического разнообразия от записи к записи.

Переключение на NoSQL для небольшого дополнительного «разнообразия» и не масштабирование сфокусированных проблем объема / скорости всегда казалось мне неправильным. Мы предоставляем этим клиентам довольно сложные компромиссы для перехода на NoSQL. Многие из этих компромиссов включают принудительное использование иерархических, денормализованных моделей данных, которые решают конкретные целевые шаблоны запросов в огромном масштабе объема / скорости. Многие клиенты не совсем понимают, сколько мощных специальных запросов они теряют, уходя из SQL.

Но как мы можем иметь лучшее из обоих миров? К счастью для нас, Postgres работает над очень удобным решением. В следующем выпуске ( 9.4 ) Postgres получает первоклассную поддержку документов JSON. Что это значит? Давайте возьмем это для пробного вращения:

JSON CRUD

Во-первых, выйдите и установите postgres 9.4 beta 2 там, где вас не волнует (у меня есть бродячая коробка ).

Во-вторых, запустите psql или все, что вы делаете в postgresing, и давайте начнем взламывать!

Создайте таблицу, которая выглядит как любая другая таблица SQL

create table person (                                                                                
  id serial,
  first_name varchar(40),
  last_name varchar(40),
  extra_details jsonb
);

За исключением заметки, что маленький тип столбца «jsonb» Это наш удобный двоичный тип столбца JSON . Что мы можем сделать с этим столом? Ну, мы можем вставить несколько записей:

Из мирского

insert into person (first_name, last_name, extra_details) 
VALUES ('doug','turnbull','{"age": 34}');
insert into person (first_name, last_name, extra_details) 
VALUES ('eric','pugh','{"age": 37}');

без схемы:

insert into person (first_name, last_name, extra_details)
VALUES ('daniel','beach','{"age": 37, "cats": {"names": ["itsy", "bitsy", "cottontail"]}}');

и посмотри на мой JSON!

select*from person;
 id | first_name | last_name |                          extra_details                          
----+------------+-----------+-----------------------------------------------------------------1| doug       | turnbull  |{"age":34}2| eric       | pugh      |{"age":37}3| daniel     | beach     |{"age":37,"cats":{"names":["itsy","bitsy","cottontail"]}}

Отлично, мы можем хранить и извлекать произвольный JSON в столбце SQL. Мы решили нашу проблему «разнообразия» — верно?

Но как мы можем найти вещи в нашем JSON?

Ну, осталась одна вещь — как мы можем запрашивать документы JSON? Postgres предоставляет несколько операторов для применения к данным JSON. Во-первых, есть базовые запросы к элементам в документе JSON с использованием оператора ->:

select*from person WHERE extra_details->'age'='37';
 id | first_name | last_name |                           extra_details                           
----+------------+-----------+-------------------------------------------------------------------2| eric       | pugh      |{"age":37}3| daniel     | beach     |{"age":37,"cats":{"names":["itsy","bitsy","cottontail"]}}

или выберите атрибуты в полях JSON:

select id, extra_details->'age'as how_old 
from person 
where extra_details->'age'='37';
 id | how_old
----+---------2|373|37

Важный оператор, который нужно знать из списка, — оператор локализации. Этот оператор спрашивает данные JSON. Является ли этот операнд справа подмножеством данных JSON слева? Или, другими словами, пересечение документов JSON A и B == документ B?

Например, давайте найдем всех людей с кошками по имени «итси» и «крошка»

select*from person
where extra_details @>'{"cats": {"names": ["itsy", “bitsy”]}}';

Да, но индексы?

Вы ставите. Нам повезло, потому что столбцы JSON поддерживают индексы Postgres GIN (инвертированный индекс). Приведенный выше запрос на подмножество можно ускорить, просто создав индекс GIN для всего столбца (индексируя весь документ):

CREATE INDEX alldetails ON person USING gin (extra_details);

Или только на конкретное свойство в JSON:

CREATE INDEX age ON person USING gin ((extra_details->'age'));

Схема FTW — верно? хорошо, может быть.

Это, наверное, одна из самых крутых вещей, с которыми я играл весь месяц. Это, безусловно, бьет по голове, так как многие клиенты нуждаются в более широком, непредсказуемом разнообразии в своих моделях данных, не оставляя специальных возможностей своих баз данных SQL. Если у каждого человека в нашей базе данных есть набор дополнительных данных, которые будут такими разными, мы не можем легко предвидеть создание новых таблиц для этих данных, то это отличное решение.

Но слово для мудрых: без схемы — немного неправильное название. Вы обычно заботитесь о проблемах «схемы». Когда мы говорим «без схемы», мы на самом деле просто подразумеваем «мы поставили задачу для вас, потребителя, для проверки данных». Конечно, это замечательно, когда проверка может быть легче и менее самоуверенным. Или когда валидация очень специфична для приложения и, возможно, даже более самоуверенна, чем то, соответствует ли входная строка заданному типу примитива, такому как строка, целое число и т. Д.

Иногда люди говорят «без схемы» и имеют в виду «перестань заставлять меня думать о реляционной модели данных». Это открытый вопрос, который мы обнаружим с помощью этих новых функций Postgres — можно ли просто иметь базу данных с одной таблицей и одним столбцом JSON, который мы запрашиваем? Вероятно, это эквивалентно вопросу «я должен перейти на MongoDB»? Что ж, это, вероятно, нормально, пока мы не столкнемся с болезненными причинами, по которым реляционные базы данных были созданы в первую очередь — потому что нормализация — это действительно хорошая вещь (R), которая моделирует отношения сущностей гораздо более богато, чем иерархические представления, такие как JSON.

Я просто рад, что теперь смогу охватить оба мира и принимать обоснованные инженерные решения, которые используют лучшее из реляционного и нереляционного.

Вы рассматриваете технологии NoSQL? Вы обеспокоены тем, что ваша реляционная база данных не может удовлетворить сегодняшние потребности? Хотите сбалансированное мнение о том, какая технология лучше всего подходит для решения ваших проблем с данными? Ну , свяжитесь с нами , и спросите об одном из наших оценок архитектуры данных!