Альтернатива EAV для динамічних полів у сховищі даних зіркової схеми


13

Мені потрібно підтримувати динамічні поля та значення у великому сховищі даних для зберігання журналу запитів 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

  1. Таблиця, requests
    (id, timestamp, uri)
    наприклад(1, 149382220, '/')

  2. Таблиця, params
    (request_id, key, value)
    наприклад(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')

Будь-які пропозиції?

Оновлення: ми запускаємо склад на AWS RedShift


2
Що не в тому, щоб спробувати те, що ви пропонуєте, у базі даних розробників? Також ви говорите про SQL Server? SQL тег досить широкий.
Макс Вернон

Оновлено моє запитання
Говард

1
Які СУБД ви використовуєте? Деякі мають досить хороші можливості індексації тексту, тому я не виключаю використання поля "довгий текст" для зберігання запитів. Сказавши це, у мене не виникне проблем із використанням запропонованої вами моделі. Хоча EAV в суворому розумінні, він використовується лише для цієї дуже конкретної мети. Знову ж таки, сказавши це, які запити потрібно мати, щоб мати можливість? Спробуйте і запишіть ці запити щодо цієї моделі, щоб побачити, чи працює вона для вас.
Колін 'Харт

1
Які RDBMS ви використовуєте? SQLнедостатньо конкретний. Вас просили двічі. Я третій.
Ервін Брандстеттер

2
Оскільки RedShift базується на PostgreSQL, я б спробував використати hstoreабо jsonтипи даних (або jsonbякщо / коли вони "модернізуються" до 9.4).
Colin 't Hart

Відповіді:


11

Я можу придумати три рішення - EAV, XML та розріджені стовпці. Останній є специфічним для продавця і може не бути корисним вам.

Який би метод ви не вибрали, ви можете розглянути можливість зберігання вихідних даних запиту в необробленому форматі, в таблиці або плоскому файлі. Це дозволить легко спробувати нові способи зберігання даних, дозволить перезавантажити дані, якщо ви виявите помилку з тим, як ви аналізуєте ваші запити, і запропонує можливості для аналізу запитів API за допомогою пакетної обробки або "великих даних" інструменти, якщо ви виявите, що ваш сховище даних не в змозі ефективно працювати з даними.

Міркування EAV

EAV / KVS, як ви це описали вище, швидше за все, буде найбільш простою реалізацією.

На жаль, це також буде дуже дорогим - щоб отримувати будь-які ефективні запити на часто використовуваних клавішах, вам потрібно мати індекси на стовпчиках ключів, які можуть бути дуже фрагментарними. Запит на конкретні ключі був би надзвичайно дорогим.

Можливо, ви зможете знизити витрати на індексацію або сканування покажчиків, підтримуючи свій магазин EAV з матеріалізованими поданнями (багато постачальників це підтримують) для запитів ключів або значень, які вас цікавлять.

XML

Більшість корпоративних систем баз даних пропонують дуже зрілі обробки XML, включаючи перевірку, індексацію та складні запити.

Завантаження запиту API в базу даних як XML забезпечить один кордон на запит, що, логічно, може бути трохи приємніше для вас, ніж невідоме число рядків у таблиці EAV.

Чи буде це ефективно, багато що залежатиме від вашого постачальника RDBMS та вашої реалізації.

Найбільшим недоліком є ​​те, що це, мабуть, єдиний спосіб управління даними, який є складнішим, ніж обробна обробка оригінального запиту!

Рідкі стовпці / традиційні таблиці

Можливо, ви можете завантажити свої дані в традиційну структуру таблиці з одним стовпцем на ключ.

Функція розріджених стовпців SQL Server є чудовою альтернативою магазину EAV. Таблиця з розрідженими стовпцями поводиться приблизно так само, як у звичайній таблиці, за винятком того, що вона може містити до 30 000 стовпців, а значення NULL у розріджених стовпцях не потребують місця в таблиці.

Поєднання їх з відфільтрованими індексами (ще одна особливість SQL Server) може стати надзвичайно ефективною альтернативою магазину EAV, якщо ви часто запитуєте кілька конкретних стовпців та / або значень.

Використання традиційної таблиці з іншими постачальниками може бути життєздатним - IBM підтримує понад 700 стовпців на таблицю, а Oracle близько 1000, а такі функції, як стиснення або обробка Oracle відслідковуючими нулями, можуть означати, що ви можете зберігати свої дані API досить ефективно.

Очевидним недоліком цього підходу є те, що, додаючи нові ключі до свого API, вам потрібно буде відповідно налаштувати схему.


2
У PostgreSQL я б не рекомендував XML, але або hstoreабо json. У майбутньому 9.4 jsonbбуде моєю рекомендацією.
Колін 'Харт

Мені дуже подобається ця відповідь із плюсами і поясненнями кожного. Дуже інформативний - я безумовно ціную інформацію про розріджені стовпці. Я хотів би зробити приклад EAV з використанням підходу з розрідженою колоною.
StixO

9

EAV - це не поганий дизайн, сам по собі, це просто дизайн, який вимагає неабиякої продуманості і може бути пов'язаний з проблемами продуктивності, оскільки кількість даних збільшується. Можливо, для вашої системи це буде добре.

Коли я розробив систему для зберігання рядків запиту, я поняття не мав , заздалегідь , які поля мені було б цікаво. Я створив таблицю для зберігання рядка запиту в сериализации довічного формату, і побудував систему , яка дозволила мені розкололося запит рядок у складові його частини, коли я знав, що цікавлять мене. Звідти я створив набір таблиць; по одному для наборів даних, які зазвичай містяться в рядку запиту.

Наприклад, у мене в кінцевому підсумку була таблиця для даних рефералів, одна для даних цільового запиту та одна для елементів, пов’язаних з користувачем, таких як пошуковий запит, який вони ввели.

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


1
І в питанні, і у відповіді використовується термін BLOB, що означає Бінарний довгий об'єкт. Я вважаю за краще використовувати CLOB(Character Long OBject) або щось подібне textв PostgreSQL, оскільки ми говоримо про символи, а не бінарні дані.
Колін 'Харт

2
Я використовував двійкове поле, оскільки фактично серіалізував весь об’єкт сеансу і зберігав всю річ у базі даних.
Макс Вернон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.