Мне нужно поддерживать динамические поля и значения в большом хранилище данных для хранения журнала запросов API, в моем случае пользователь должен хранить строку запроса всех запросов API и иметь возможность выполнять запрос к ним в будущем (так что это не просто хранилище, поэтому я не могу использовать BLOB для них)
например http://example.com/?action=test&foo=abc&bar=def...
Мне нужно хранить все field => value
сопоставления, т. Е. (action => test), (foo => abc), (bar => def)
Поскольку поле является таким динамическим, единственное решение, которое я нашел, - это использовать Entity-Attribute-Value, однако люди продолжают говорить, что это очень плохой дизайн.
Итак, рассмотрим мой вариант использования выше, что будет подходящей альтернативой EAV?
Моя текущая схема с использованием KAV
Таблица,
requests
(id, timestamp, uri)
например(1, 149382220, '/')
Таблица,
params
(request_id, key, value)
например(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')
Какие-либо предложения?
Обновление: запускаем склад на AWS RedShift
SQL
не достаточно конкретен. Вас спросили дважды. Я третий.hstore
илиjson
тип данных (или ,jsonb
если / когда они «обновить» до 9.4).Ответы:
Я могу придумать три решения - EAV, XML и Sparse Columns. Последнее зависит от поставщика и может оказаться бесполезным для вас.
Какой бы метод вы ни выбрали, вы можете рассмотреть возможность сохранения исходных данных запроса в необработанном формате, в виде таблицы или плоского файла. Это позволит легко опробовать новые способы хранения данных, позволит перезагрузить данные, если вы обнаружите ошибку при анализе ваших запросов, и предложит возможности для анализа запросов API с помощью пакетной обработки или «больших данных». инструменты, если вы обнаружите, что ваше хранилище данных не в состоянии эффективно обрабатывать данные.
EAV соображения
EAV / KVS, как вы описали выше, вероятно, будет самой простой реализацией.
К сожалению, это также будет очень дорого - чтобы получить любые эффективные запросы по часто используемым ключам, вам понадобятся индексы для ключевого столбца, которые могут быть очень фрагментированными. Запрос конкретных ключей будет чрезвычайно дорогим.
Вы можете уменьшить стоимость индексирования или сканирования индекса, поддерживая свое хранилище EAV материализованными представлениями (многие поставщики поддерживают это) для запроса ключей или значений, которые вас интересуют.
XML
Большинство систем баз данных предприятия предлагают очень зрелую обработку XML, включая проверку, индексацию и сложные запросы.
Загрузка запроса API в базу данных в виде XML обеспечит один кортеж на запрос, что логически может быть более приемлемым для вас, чем наличие неизвестного количества строк в таблице EAV.
Эффективность этого будет во многом зависеть от вашего поставщика RDBMS и вашей реализации.
Самым большим недостатком является то, что это, вероятно, единственный способ управления данными, который является более сложным, чем манипуляции со строками исходного запроса!
Разреженные столбцы / традиционные таблицы
Возможно, вы могли бы загрузить свои данные в традиционную структуру таблицы, с одним столбцом на ключ.
Функция Sparse Columns в SQL Server - отличная альтернатива хранилищу EAV. Таблица с разреженными столбцами ведет себя так же, как обычная таблица, за исключением того, что она может содержать до 30 000 столбцов, а значения NULL в разреженных столбцах не занимают места в таблице.
Объединение их с отфильтрованными индексами (еще одна особенность SQL Server) может обеспечить чрезвычайно эффективную альтернативу хранилищу EAV, если вы часто запрашиваете пару конкретных столбцов и / или значений.
Использование традиционной таблицы с другими поставщиками может быть целесообразным - IBM поддерживает более 700 столбцов на таблицу, а Oracle - около 1000, а такие функции, как сжатие или обработка завершающих нулей Oracle, могут означать, что вы можете хранить свои данные API довольно эффективно.
Очевидный недостаток этого подхода заключается в том, что по мере добавления новых ключей в API вам необходимо соответствующим образом изменить свою схему.
источник
hstore
либоjson
. В ближайшие 9.4jsonb
будет моя рекомендация.EAV - это не плохой дизайн, сам по себе, это просто проект, который требует значительного количества продуманной работы и может быть вызван проблемами производительности при увеличении количества данных. Возможно, для вашей системы это будет работать хорошо.
Когда я разработал систему для хранения строк запроса, я понятия не имел , заранее , какие поля мне было бы интересно. Я создал таблицу для хранения строки запроса в сериализации двоичного формата, и построил систему , которая позволила мне раскололось запрос разбить его на части, как только я узнаю, какие части меня интересуют. Оттуда я создал набор таблиц; по одному для наборов данных, обычно содержащихся в строке запроса.
Например, у меня в конечном итоге была таблица для данных реферера, одна для данных целевого запроса и одна для элементов, связанных с пользователем, таких как введенный ими поисковый запрос.
Я обнаружил, что возможность хранить всю строку запроса в одной таблице в виде большого двоичного объекта, в то же время предоставляя возможность разбивать этот большой двоичный объект в будущем, очень хорошо отвечал моим потребностям.
источник
BLOB
который означает двоичный длинный объект. Я бы предпочел использоватьCLOB
(Character Long OBject) или что-то вродеtext
PostgreSQL, так как мы говорим о символах, а не двоичных данных.