База даних значень атрибутів суб'єкта господарювання порівняно із суворою реляційною моделлю електронної комерції


136

Можна з упевненістю сказати, що модель бази даних EAV / CR погана. Це сказав:

Питання: Яку модель, техніку чи зразок бази даних слід використовувати для роботи з "класами" атрибутів, що описують продукти електронної комерції, які можна змінити під час виконання?

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

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

Подальше обговорення:

Якщо коротко розповісти, чи є в Інтернеті посилання чи описи моделей, які могли б "академічно" зафіксувати наступні налаштування? Я дякую Ноелю Кеннеді за те, що він запропонував таблицю категорій, але потреба може бути більшою за це. Я описую це по-іншому нижче, намагаючись підкреслити значення. Мені може знадобитися виправлення точки зору для вирішення проблеми, або мені може знадобитися заглибитись до EAV / CR.

Любіть позитивну відповідь на модель EAV / CR. Мої колеги-розробники говорять про те, що Джефрі Кемп торкнувся нижче: "нові об'єкти повинні моделювати та розробляти професіонал" (виймати з контексту, читайте його відповідь нижче). Проблема полягає в наступному:

  • суб'єкти щотижня додають та видаляють атрибути
    (ключові слова пошуку диктують майбутні атрибути)
  • нові організації прибувають щотижня
    (продукція збирається з деталей)
  • старі організації відходять щотижня
    (архівовані, менш популярні, сезонні)

Замовник хоче додати атрибути до продуктів з двох причин:

  • відділ / пошук ключових слів / діаграма порівняння між подібними продуктами
  • конфігурація споживчих товарів перед оформленням замовлення

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


Чому ви просто не можете мати таблицю "категорії", де зовнішній ключ позначається на собі?
Ноель Кеннеді

29
Небезпечно, ані точно, сказати, що модель бази даних EAV погана, оскільки вона добре підходить для деяких програм.
spencer7593

Що робити, якщо ви прикрасите різні предмети різними властивостями, успадкувавши від батьків, як в Entity Framework 4? Як він зберігає ці об’єкти?
Закарі Скотт

1
Назад, щоб вказати на цю чудову статтю про досвід одного консультанта із системою, заснованою на екстремальній версії EAV. Читати! simple-talk.com/opinion/opinion-pieces/bad-carma
Джеффрі Кемп

1
EAV - дуже життєздатна модель бази даних. Я працюю над подібною проблемою, як ви, і рішення EAV. Я рекомендував би наступну статтю: sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/…
Sandor

Відповіді:


75

Є декілька загальних плюсів і мінусів, які я можу придумати, є ситуації, коли один краще, ніж інший:

Варіант 1, Модель EAV:

  • Pro: менше часу на розробку та розробку простого додатка
  • Pro: нові об'єкти легко додати (можливо, навіть додадуть користувачі?)
  • Про: "загальні" компоненти інтерфейсу
  • Con: складний код, необхідний для перевірки простих типів даних
  • Con: набагато складніший SQL для простих звітів
  • Кон: складні звіти можуть стати майже неможливими
  • Con: низька продуктивність для великих наборів даних

Варіант 2, Моделювання кожної сутності окремо:

  • Con: більше часу потрібно для збору вимог та дизайну
  • Кон: нові організації повинні бути спроектовані та спроектовані професіоналом
  • Con: компоненти користувальницького інтерфейсу для кожної сутності
  • Pro: обмеження типу даних та перевірка простоти у здійсненні
  • Pro: SQL легко писати, легко розуміти та налагоджувати
  • Про: навіть найскладніші звіти відносно прості
  • Pro: найкраща ефективність для великих наборів даних

Варіант 3, Поєднання (модельні об'єкти "належним чином", але додайте "розширення" для спеціальних атрибутів для деяких / всіх об'єктів)

  • Pro / Con: для збирання вимог та дизайну потрібно більше часу, ніж варіант 1, але, можливо, не стільки, скільки варіант 2 *
  • Кон: нові організації повинні бути спроектовані та спроектовані професіоналом
  • Pro: нові атрибути можуть бути легко додані згодом
  • Con: складний код, необхідний для перевірки простих типів даних (для спеціальних атрибутів)
  • Con: компоненти користувальницького інтерфейсу все ще потрібні, але для користувацьких атрибутів можуть бути можливі загальні компоненти інтерфейсу
  • Con: SQL стає складним, як тільки будь-який спеціальний атрибут включений у звіт
  • Con: хороша ефективність, як правило, якщо вам не потрібно шукати користувацькі атрибути або звітувати за ними

* Я не впевнений, чи варіант 3 обов'язково заощадить будь-який час на етапі проектування.

Особисто я схиляюся до варіанту 2 і уникаю EAV, коли це можливо. Однак для деяких сценаріїв користувачі потребують гнучкості, що постачається разом із EAV; але це коштує з великими витратами.


Що робити, якщо у вас була єдина таблиця з індексами для текстових значень 1-n, то в C # (у таран) зробіть карту того, що вам потрібно, і що вам потрібно. Він би все ще працював як EAV, але "відповідники" будуть доменними моделями. Начебто як серіалізація, але ви можете використовувати вибір SQL у індексованих текстових полях. Немає кратного вибору на запис. Вся "вартість" відбувається в оперативній пам'яті.
Захарі Скотт

1
@Zim, це дуже схоже на варіант 3. Кожен рядок має 1-n додаткових "загальних" стовпців, а дані, що зберігаються в них, інтерпретуються на рівні програми. Ви отримуєте перевагу від продуктивності, коли всі дані для одного запису в одному місці. Метадані про ці стовпчики потрібно десь зберігати, і саме тут витрачається вартість. Звичайно, ми можемо кешувати метадані в операційному режимі, але це все-таки коштує більше, ніж моделювання домену безпосередньо в коді програми. Звичайно, краще, ніж повноцінна модель EAV!
Джефрі Кемп

1
+10000 Чудова відповідь. Сьогодні люди скупіться на розробку баз даних та збір вимог. Вони вважають за краще написати в сто разів більше рядків коду, які потребують часу, щоб зробити гарний дизайн.
Tulains Córdova

Для реляційного варіанту (2) вам не потрібно більше дизайну, ніж параметр EAV (1), якщо ви лише надаєте структуру варіанту 1. А реляційний інтерфейс є загальним для метаданих, що описують цю структуру. Це видаляє всі варіанти 2 мінусів. Однак ви забули єдиний фактичний Con: DDL може бути занадто повільним керуванням таблицями.
philipxy

Привіт @philipxy, я не сказав "більше дизайну". Основна причина для EAV полягає в тому, що (імовірно) дизайнер системи може витратити менше часу на розробку моделі, залишаючи цю проектну роботу "користувачам" згодом (ця відсутність професійного дизайну призводить до мінусів, перелічених у варіанті 1) . Якщо EAV не призводить до економії для дизайнера, це лише додає більше палива до вогню для відхилення EAV з-під руки. Також я не погоджуюся з тим, що DDL є "занадто повільним" - оскільки його потрібно вимагати лише рідко (тобто виправляти помилки в моделі або впроваджувати нові функції), її продуктивність повинна бути відносно неважливою.
Джеффрі Кемп

63

Можна з упевненістю сказати, що модель бази даних EAV / CR погана.

Ні це не так. Просто вони неефективно використовують реляційні бази даних. Суто ключ-цінність магазину чудово працює з цією моделлю.

Тепер до вашого справжнього питання: як зберігати різні атрибути та підтримувати їх пошук?

Просто використовуйте EAV. У вашому випадку це була б одна додаткова таблиця. індексуйте його як на ім'я атрибута, так і на значення, більшість RDBM використовуватимуть префікс-компресію для повторень імен атрибутів, що робить його дійсно швидким та компактним.

EAV / CR стає некрасивим, коли ви використовуєте його для заміни "реальних" полів. Як і будь-який інструмент, надмірне використання його є «поганим» і дає йому поганий образ.


тож питання у мене є 15 додаткових полів для однієї з моїх категорій, і в моделі EAV він вимагає 16 приєднатись + основна таблиця, щоб зробити 16 лівих приєднань для пошуку продуктів (а також 16, де, якщо хоче охотник) у 3-4 мільйонах записів ( веб-сайт для продажу людей, що вживаються у користування), тому це займе перофрманс?
babak faghihian

2
Якщо ці "додаткові поля" вже визначені, то це, безумовно, найкраще зробити як "реальні поля". І звичайно, велика кількість приєднань до великого запиту було б важкою справою (але все одно може бути нормально!). Що я робив для важкого метаданих проекту, це дозволити будь-яку кількість "тегів" (як EAV-записи) на "головний елемент", але "великий запит" вибирає лише деякі заздалегідь задані імена тегів, зберігаючи загальну кількість приєднань обмеженою ( в даний час типова всього 4 мітки і близько 5 інших сполук), і коли користувач вибирає конкретний пункт, то він fetchs все , що пов'язано, але для одного елемента.
Хав’єр

але, звичайно, ця конкретна система зараз переноситься на hstoreполе (лише одна з причин, чому ми використовуємо PostgreSQL)
Хав'єр

15
// На даний момент я хотів би скористатись хвилиною, щоб поговорити з вами про формат Magento / Adobe PSD .
// Magento / PSD не є хорошою платформою / форматом електронної комерції . Magento / PSD - це навіть не погана платформа / формат електронної комерції . Називати його таким було б
// образа інших платних / форматів електронної комерції , таких як Zencart або OsCommerce. Ні, Magento / PSD - це ненормальна платформа / формат електронної комерції . Маючи
// працював над цим кодом вже кілька тижнів, моя ненависть до Magento / PSD переросла до бурхливої ​​пожежі
// що горить лютою пристрастю мільйона сонців.

http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107

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

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

CREATE OR REPLACE VIEW sales_flat_addresses AS
SELECT sales_order_entity.parent_id AS order_id, 
       sales_order_entity.entity_id, 
       CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type, 
       GROUP_CONCAT( 
         CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value )
         ORDER BY sales_order_entity_varchar.value DESC
         SEPARATOR '!!!!!' 
       ) as data
  FROM sales_order_entity
       INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id
       INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id
   AND sales_order_entity.entity_type_id =12
 GROUP BY sales_order_entity.entity_id
 ORDER BY eav_attribute.attribute_code = 'address_type'

Ліниво чекає адресну інформацію для замовлення

-

Підсумок: Використовуйте Magento лише у випадку:

  1. Вам дають великі мішки грошей
  2. Ти повинен
  3. Насолоджуйтесь болем

Це старіший пост, але я б хотів, щоб це я знайшов 3 місяці тому, коли я розпочав проект Magento для клієнта. +1 за аналогію із забоєм / шейкером!
trevorc

1
Дуже цікаво, магенто здається, що це король дороги в плані систем електронної комерції. Може бути , тільки це маркетинг дуже добре
Herr

1
Magento не користується популярністю через рівень обслуговування, але можливість налаштувати, що дозволяє будь-якому користувачеві реалізовувати нові функції без змін архітектури або декількох модифікацій. Ця особливість поставляється з вартістю.
Дієго Мендес

Тримайтеся подалі від Magento 2, якщо ви хочете уникнути потрійного болю та більше болю на верху як для FE, так і для BE
TheBlackBenzKid

15

Я здивований, що ніхто не згадував бази даних NoSQL.

Я ніколи не практикував NoSQL у виробничому контексті (просто перевіряв MongoDB і був вражений), але вся суть NoSQL в змозі зберігати елементи з різними атрибутами в одному "документі".


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

Врахуйте, що тривалість блокування знаходиться в порядку мікросекунд.
Hello World

12

Якщо продуктивність не є основною вимогою, як у застосуванні типу ETL, у EAV є ще одна чітка перевага: диференціальна економія.

Я реалізував ряд застосувань, де вимогою над архівуванням була можливість бачити історію доменного об’єкта від його першої "версії" до його поточного стану. Якщо цей об’єкт домену має велику кількість атрибутів, це означає, що кожна зміна потребує вставлення нового рядка у відповідну таблицю (не оновлення, оскільки історія буде втрачена, а вставка). Скажімо, цей об’єкт домену - це Особа, і у мене є 500 тис. Осіб, щоб відстежувати в середньому 100+ змін за життєвий цикл Особи до різних атрибутів. У поєднанні з тим, що рідкісною є програма, яка має лише 1 основний доменний об’єкт, і ви швидко переконаєтесь, що розмір бази даних швидко вийде з-під контролю.

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

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


2
+1 для "Використання EAV - це лише один із інструментів, який ми використовуємо у вікні, але він ніколи не повинен автоматично класифікуватися як" поганий "."
Catchops

Btw, це називається SCD (повільно змінюються розміри). Також бітемпоральні вимоги (конкретний випадок SCD типу 4) вимагають схеми EAV для атрибутів, що мають це властивість. Пам'ятайте, що 99% NoSQL не має вбудованих приєднань, тому якщо вам потрібно "живий" приєднання до цього типу даних, EAV - це єдиний шлях.
коуберт

3

Я борюся з тим же питанням. Вам може бути цікаво ознайомитись із наступною дискусією щодо двох існуючих рішень електронної комерції: Magento (EAV) та Joomla (регулярна реляційна структура): https://forum.virtuemart.net/index.php?topic=58686.0

Здається, виступ Magento EAV - справжній шоуперпер.

Тому я схиляюся до нормалізованої структури. Щоб подолати брак гнучкості, я думаю про те, щоб у майбутньому додати окремий словник даних (XML або окремі таблиці БД), які можна було б відредагувати, і виходячи з цього, кодом програми для відображення та порівняння категорій продуктів з новими наборами атрибутів буде згенеровано разом із SQL-скриптами.

Така архітектура, здається, є приємною плямою в цьому випадку - гнучкою та одночасно ефективною.

Проблемою може бути часте використання ALTER TABLE у живих умовах. Я використовую Postgres, тому його MVCC і транзакційний DDL сподіваються полегшити біль.


2

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


2

Якщо мова йде лише про атрибути каталогу товарів і, отже, вимоги перевірки цих атрибутів досить обмежені, єдиний реальний недолік EAV - це ефективність запитів, і навіть це лише проблема, коли ваш запит має справу з кількома "речами" (продуктами) з атрибутами, продуктивність для запиту "надайте мені всі атрибути для продукту з ідентифікатором 234", тоді як не оптимальна все ще досить швидка.

Одне з варіантів - використовувати базу даних SQL / модель EAV лише для адміністратора / редагування каталогу продукту та мати певний процес, який денормалізує продукти у щось, що робить його пошуком. Оскільки у вас вже є атрибути, а отже, цілком ймовірно, що ви хочете облицювати, це щось може бути Solr або ElasticSearch. Цей підхід в основному дозволяє уникнути всіх недоліків моделі EAV, а додаткова складність обмежується серіалізацією повного продукту до JSON при оновленні.


2

EAV має багато недоліків:

  1. Зниження продуктивності з часом Після того, як кількість даних у програмі перевищить певний розмір, їх отримання та обробка цими даними, ймовірно, стануть менш ефективними.
  2. Запити SQL дуже складні і важко записати.
  3. Проблеми цілісності даних. Ви не можете визначити зовнішні ключі для всіх необхідних полів.
  4. Ви повинні визначити та підтримувати власні метадані.

1. Це справедливо і для більшості реляційних баз даних; саме тому було винайдено заточування. 2. Моделювання даних може бути складним і складним у здійсненні. Я проводив тижні-місяці в очікуванні змін схеми куба OLAP. 3. Вже в основному це робиться зараз у програмному забезпеченні. 4. Вам потрібно робити це "в ERwin, Excel та Visio", коли все-таки моделюють реляційну схему.
коуберт

1

У мене дещо інша проблема: замість багатьох атрибутів із розрідженими значеннями (що, можливо, є вагомою причиною для використання EAV), я хочу зберігати щось більше, як електронну таблицю. Стовпці на аркуші можуть змінюватися, але всередині аркуша всі комірки будуть містити дані (не розріджені).

Я зробив невеликий набір тестів, щоб порівняти два дизайни: один використовував EAV, а другий використовував Postgres ARRAY для зберігання даних комірок.

EAV введіть тут опис зображення

Масив введіть тут опис зображення

Обидві схеми мають індекси у відповідних стовпцях, а індекси використовуються планувальником.

Виявилося, що схема на основі масиву була на порядок швидшою як для вставок, так і для запитів. З швидких тестів здавалося, що обидва масштабуються лінійно. Проте тести не дуже ретельні. Пропозиції та виделки вітаються - вони мають ліцензію MIT.


як ви зробили об'єднання на стовпцях аркушів (тобто vlookup) з моделлю масиву? Чи не потрібно писати власну функцію сортування злиття масиву? Ви дуже сумніваєтесь, що це може бути так само добре, як попередньо складений сортування злиття, якщо ви використовували sheet_id + x-координату + y-координату комірки, як ключ значення комірки. (для емуляції excel, попередньо створити таблицю пошуку для x-координат, де 0-18278 є стовпцями A-ZZZ (excel максимуми на 16384)), тоді ви можете вибрати значення, де sheet_id = uuid та x -ord = 0 і y-координата <1001, щоб отримати перші 1000 рядків
колонки

@cowbert ти маєш рацію; насправді я просто завантажую колонки, які мене цікавлять, і роблю приєднання в Python. Слабість!
z0r
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.