Baza danych wartości atrybutów encji a e-commerce na podstawie ścisłego modelu relacyjnego

136

Można śmiało powiedzieć, że model bazy danych EAV / CR jest zły. To mówi,

Pytanie: Jaki model, technika lub wzorzec bazy danych należy zastosować w przypadku „klas” atrybutów opisujących produkty handlu elektronicznego, które można zmienić w czasie wykonywania?

W dobrej bazie danych handlu elektronicznego będziesz przechowywać klasy opcji (np. Rozdzielczość telewizora, a następnie rozdzielczość każdego telewizora, ale następny produkt może nie być telewizorem i nie mieć „rozdzielczości telewizyjnej”). Jak je przechowywać, efektywnie wyszukiwać i pozwalać użytkownikom konfigurować typy produktów za pomocą zmiennych pól opisujących ich produkty? Jeśli wyszukiwarka stwierdzi, że klienci zazwyczaj szukają telewizorów na podstawie głębokości konsoli, możesz dodać głębokość konsoli do swoich pól, a następnie dodać po jednej głębokości dla każdego typu telewizora w czasie wykonywania.

Dobre aplikacje do handlu elektronicznego mają fajną wspólną cechę, w której pokazują zestaw produktów, a następnie mają „szczegółowe” menu boczne, w których można zobaczyć „Rozdzielczość TV” jako nagłówek, oraz pięć najpopularniejszych rozdzielczości telewizyjnych dla znaleziony zestaw. Po kliknięciu jednego z nich wyświetla się tylko telewizory o tej rozdzielczości, umożliwiając dalsze przeglądanie, wybierając inne kategorie w menu bocznym. Te opcje to dynamiczne atrybuty produktu dodane w czasie wykonywania.

Dalsza dyskusja:

Krótko mówiąc, czy w Internecie są jakieś linki lub opisy modeli, które mogłyby „naukowo” naprawić następującą konfigurację? Dziękuję Noelowi Kennedy'emu za zasugerowanie tabeli kategorii, ale potrzeba może być większa. Poniżej opisuję to inaczej, starając się podkreślić znaczenie. Być może potrzebuję korekty punktu widzenia, aby rozwiązać problem, lub może być konieczne zgłębienie głębiej do EAV / CR.

Uwielbiam pozytywną reakcję na model EAV / CR. Moi koledzy programiści mówią o tym, o czym Jeffrey Kemp poruszył poniżej: „nowe jednostki muszą być modelowane i projektowane przez profesjonalistę” (wyrwane z kontekstu, przeczytaj jego odpowiedź poniżej). Problemem jest:

  • encje dodają i usuwają atrybuty co tydzień
    (słowa kluczowe wyszukiwania dyktują przyszłe atrybuty)
  • nowe jednostki przybywają co tydzień
    (produkty są składane z części)
  • stare elementy znikają co tydzień
    (archiwizowane, mniej popularne, sezonowe)

Klient chce dodać atrybuty do produktów z dwóch powodów:

  • wyszukiwanie działów / słów kluczowych / tabela porównawcza podobnych produktów
  • konfiguracja produktu konsumenckiego przed zakupem

Atrybuty muszą mieć znaczenie, a nie tylko wyszukiwanie słów kluczowych. Jeśli chcą porównać wszystkie ciasta, które mają „lukier z bitej śmietany”, mogą kliknąć ciasta, kliknąć motyw urodzinowy, kliknąć lukier z bitej śmietany, a następnie sprawdzić wszystkie interesujące ciasta, wiedząc, że wszystkie mają lukier z bitej śmietany. To nie jest specyficzne dla ciast, tylko przykład.

Zachary Scott
źródło
Dlaczego nie możesz po prostu mieć tabeli kategorii z kluczem obcym odnoszącym się do samego siebie?
Noel Kennedy
29
Nie jest bezpieczne ani precyzyjne stwierdzenie, że model bazy danych EAV jest zły, ponieważ dobrze nadaje się do niektórych aplikacji.
spencer7593
Co się stanie, jeśli ozdobisz różne obiekty różnymi właściwościami, dziedzicząc po rodzicu, jak w Entity Framework 4? W jaki sposób utrzymuje te obiekty?
Zachary Scott,
1
Wróćmy do tego znakomitego artykułu o doświadczeniach jednego konsultanta z systemem opartym na ekstremalnej wersji EAV. Przeczytaj to! simple-talk.com/opinion/opinion-pieces/bad-carma
Jeffrey Kemp,
1
EAV to bardzo realny model bazy danych. Pracuję nad podobnym problemem jak Ty i rozwiązaniem jest EAV. Poleciłbym
Sandor

Odpowiedzi:

75

Jest kilka ogólnych za i przeciw, które przychodzą mi do głowy, są sytuacje, w których jeden jest lepszy od drugiego:

Opcja 1, model EAV:

  • Zaleta: mniej czasu na zaprojektowanie i opracowanie prostej aplikacji
  • Pro: nowe encje łatwe do dodania (mogą nawet zostać dodane przez użytkowników?)
  • Pro: „ogólne” komponenty interfejsu
  • Wada: złożony kod wymagany do walidacji prostych typów danych
  • Wada: dużo bardziej złożony SQL dla prostych raportów
  • Wada: złożone raporty mogą stać się prawie niemożliwe
  • Wada: słaba wydajność w przypadku dużych zestawów danych

Opcja 2, modelowanie każdego podmiotu osobno:

  • Wada: więcej czasu potrzeba na zebranie wymagań i projektu
  • Wada: nowe jednostki muszą być modelowane i projektowane przez profesjonalistę
  • Wada: niestandardowe komponenty interfejsu dla każdej jednostki
  • Pro: ograniczenia typu danych i walidacja proste do wdrożenia
  • Pro: SQL jest łatwy do napisania, łatwy do zrozumienia i debugowania
  • Zaleta: nawet najbardziej złożone raporty są stosunkowo proste
  • Pro: najlepsza wydajność dla dużych zestawów danych

Opcja 3, kombinacja (modelowanie jednostek „prawidłowo”, ale dodaj „rozszerzenia” dla atrybutów niestandardowych dla niektórych / wszystkich jednostek)

  • Pro / Con: więcej czasu potrzeba na zebranie wymagań i projektu niż opcja 1, ale być może nie tak dużo jak opcja 2 *
  • Wada: nowe jednostki muszą być modelowane i projektowane przez profesjonalistę
  • Pro: nowe atrybuty można łatwo dodać później
  • Wada: złożony kod wymagany do walidacji prostych typów danych (dla atrybutów niestandardowych)
  • Wada: niestandardowe komponenty interfejsu są nadal wymagane, ale dla atrybutów niestandardowych mogą być dostępne ogólne komponenty interfejsu
  • Wada: SQL staje się złożony, gdy tylko jakikolwiek atrybut niestandardowy zostanie uwzględniony w raporcie
  • Wada: ogólnie dobra wydajność, chyba że musisz rozpocząć wyszukiwanie lub raportowanie według atrybutów niestandardowych

* Nie jestem pewien, czy opcja 3 koniecznie pozwoliłaby zaoszczędzić czas na etapie projektowania.

Osobiście skłaniałbym się ku opcji 2 i unikał EAV, gdy tylko jest to możliwe. Jednak w niektórych scenariuszach użytkownicy potrzebują elastyczności, która zapewnia EAV; ale wiąże się to z dużymi kosztami.

Jeffrey Kemp
źródło
Co by było, gdybyś miał pojedynczą tabelę z indeksami dla wartości tekstowych 1-n, a następnie w C # (w pamięci RAM) zamapuj to, czego chcesz, na to, czego potrzebujesz. Nadal działałby jak EAV, ale „dopasowania” byłyby modelami domeny. Trochę jak serializacja, ale możesz użyć selekcji SQL w indeksowanych polach tekstowych. Brak wielokrotnych wyborów na rekord. Cały „koszt” odbywa się w pamięci RAM.
Zachary Scott
1
@Zim, to brzmi prawie jak opcja 3. Każdy wiersz ma od 1 do n dodatkowych kolumn „ogólnych”, a dane w nich przechowywane są interpretowane na poziomie aplikacji. Uzyskasz korzyści wynikające z posiadania wszystkich danych z jednego rekordu w jednym miejscu. Jednak metadane dotyczące tych kolumn muszą być gdzieś przechowywane i tu wkrada się koszt. Jasne, możemy buforować metadane w pamięci RAM, ale nadal kosztuje to więcej niż modelowanie domeny bezpośrednio w kodzie aplikacji. Z pewnością lepszy niż pełnowartościowy model EAV!
Jeffrey Kemp
1
+10000 Świetna odpowiedź. W dzisiejszych czasach ludzie oszczędzają na projektowaniu baz danych i gromadzeniu wymagań. Wolą napisać sto razy więcej wierszy kodu, co wymaga czasu, aby stworzyć dobry projekt.
Tulains Córdova,
Nie potrzebujesz więcej projektu dla opcji relacyjnej (2) niż opcja EAV (1), jeśli dostarczasz tylko strukturę opcji 1. A interfejs relacyjny jest generyczny na podstawie metadanych opisujących tę strukturę. To usuwa wszystkie opcje 2 Wady. Jednak zapomniałeś o jedynym faktycznym Con: DDL może być zbyt wolnym zarządzaniem tabelami.
philipxy
Cześć @philipxy, nie powiedziałem „więcej projektowania”. Racją bytu EAV jest to, że (przypuszczalnie) projektant systemu może poświęcić mniej czasu na projektowanie modelu, pozostawiając później tę pracę projektową „użytkownikom” (ten brak profesjonalnego projektu prowadzi do wad wymienionych dla opcji 1) . Jeśli EAV nie prowadzi do żadnych oszczędności dla projektanta, to tylko dodaje więcej paliwa do ognia, aby odrzucić EAV z ręki. Nie zgadzam się też z tym, że DDL jest „zbyt wolny” - ponieważ powinien być potrzebny rzadko (np. Do naprawy błędów w modelu lub do implementacji nowych funkcji), jego wydajność powinna być stosunkowo nieistotna.
Jeffrey Kemp
63

Można śmiało powiedzieć, że model bazy danych EAV / CR jest zły.

Nie, nie jest. Chodzi tylko o to, że są one nieefektywnym wykorzystaniem relacyjnych baz danych. W tym modelu świetnie sprawdza się czysty magazyn kluczy / wartości.

A teraz do twojego prawdziwego pytania: jak przechowywać różne atrybuty i umożliwić ich przeszukiwanie?

Po prostu użyj EAV. W twoim przypadku byłby to pojedynczy dodatkowy stół. indeksuj go zarówno pod względem nazwy, jak i wartości, większość RDBM użyje kompresji przedrostków do powtórzeń nazw atrybutów, dzięki czemu jest naprawdę szybki i zwarty.

EAV / CR staje się brzydki, gdy używasz go do zastąpienia „prawdziwych” pól. Jak w przypadku każdego narzędzia, jego nadużywanie jest „złe” i daje zły obraz.

Javier
źródło
więc pytanie brzmi: mam 15 dodatkowych pól dla jednej z moich kategorii, aw modelu eav wymaga to 16 złączeń + głównej tabeli, więc pozostawiam 16 złączeń do wyszukiwania w produktach (i mam 16, jeśli klient chce) w 3-4 milionach rekordów ( strona internetowa do sprzedaży produktów z drugiej ręki), więc wydajność jest niska?
babak faghihian
2
Jeśli te „dodatkowe pola” są już zdefiniowane, zdecydowanie najlepiej byłoby to zrobić jako „pola rzeczywiste”. Oczywiście wykonanie nieograniczonej liczby złączeń w dużym zapytaniu byłoby dużym kosztem (ale nadal może być w porządku!). To, co zrobiłem w projekcie z dużą ilością metadanych, to zezwolenie na dowolną liczbę "tagów" (jako rekordów EAV) na "główny element", ale "duże zapytanie" wybiera tylko niektóre predefiniowane zmienne, ograniczając całkowitą liczbę złączeń (obecnie jest typowy tylko 4 znaczniki i inne dołącza około 5), a gdy użytkownik wybierze pozycja specyficzna, wtedy to fetchs wszystko związane, ale dla jednego elementu.
Javier
ale oczywiście ten konkretny system jest obecnie przenoszony na hstorepole (to tylko jeden z powodów, dla których używamy PostgreSQL)
Javier
15
// W tym miejscu chciałbym poświęcić chwilę, aby porozmawiać z tobą o Magento / formacie Adobe PSD .
// Magento / PSD nie jest dobrą platformą / formatem e-commerce . Magento / PSD nie jest nawet złą platformą e-commerce / formatem . Nazywanie tego tak byłoby
// obrażanie innych złych platform / formatów e-commerce , takich jak Zencart lub OsCommerce. Nie, Magento / PSD to fatalna platforma e-commerce / format . Mający
// pracowałem nad tym kodem już od kilku tygodni, moja nienawiść do Magento / PSD przerodziła się w szalejący ogień
// który płonie zaciekłą pasją miliona słońc.

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

Modele wewnętrzne są w najlepszym razie zwariowane, jakby ktoś włożył schemat do głupiej gry, zapieczętował to i włożył do shakera z farbą ...

Prawdziwy świat: Pracuję nad aplikacją do realizacji oprogramowania pośredniego i oto jedno z pytań, aby uzyskać informacje adresowe.

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'

Dokładne dane adresowe do zamówienia, leniwie

-

Podsumowanie: Używaj Magento tylko wtedy, gdy:

  1. Dostajesz duże worki pieniędzy
  2. Musisz
  3. Ciesz się bólem
Vee
źródło
To jest starszy post, ale żałuję, że nie znalazłem go 3 miesiące temu, kiedy zaczynałem projekt Magento dla klienta. +1 za analogię boggle / paint shaker!
trevorc
1
Co ciekawe, magento wydaje się być królem szos pod względem systemów e-commerce. Może tylko marketing jest bardzo dobry
Herr,
1
Magento nie jest popularne ze względu na poziom utrzymania, ale możliwość dostosowywania, umożliwiając każdemu wdrażanie nowych funkcji bez zmian architektury lub kilku modyfikacji. Ta funkcja jest płatna.
Diego Mendes
Trzymaj się z dala od Magento 2, jeśli chcesz uniknąć Triple Pain i More pain na wierzchu zarówno dla FE, jak i BE
TheBlackBenzKid
15

Dziwię się, że nikt nie wspomniał o bazach danych NoSQL.

Nigdy nie ćwiczyłem NoSQL w kontekście produkcyjnym (właśnie przetestowałem MongoDB i byłem pod wrażeniem), ale głównym celem NoSQL jest możliwość zapisywania elementów o różnych atrybutach w tym samym „dokumencie”.

Lucas T.
źródło
Weź pod uwagę, że zapisy do MongoDB wymagają blokowania na poziomie bazy danych i co to oznacza dla współbieżnego ruchu produkcyjnego.
Bill Karwin
Weź pod uwagę, że czas trwania blokady jest rzędu mikrosekund.
Hello World
12

Tam, gdzie wydajność nie jest głównym wymaganiem, jak w przypadku aplikacji typu ETL, EAV ma inną wyraźną zaletę: różnicowe oszczędności.

Zaimplementowałem wiele aplikacji, w których nadrzędnym wymogiem była możliwość przeglądania historii obiektu domeny od jego pierwszej „wersji” do aktualnego stanu. Jeśli ten obiekt domeny ma dużą liczbę atrybutów, oznacza to, że każda zmiana wymaga wstawienia nowego wiersza do odpowiedniej tabeli (nie aktualizacji, ponieważ historia zostałaby utracona, ale wstawienie). Załóżmy, że ten obiekt domeny to Osoba i mam 500 tys. Osób do śledzenia ze średnio ponad 100 zmianami różnych atrybutów w cyklu życia Osoby. Połącz to z faktem, że rzadka jest aplikacja, która ma tylko 1 główny obiekt domeny, a szybko przypuszczasz, że rozmiar bazy danych szybko wymknie się spod kontroli.

Łatwym rozwiązaniem jest zapisanie tylko zmian różnicowych w głównych obiektach domeny zamiast wielokrotnego zapisywania nadmiarowych informacji.

Wszystkie modele zmieniają się z czasem, aby odzwierciedlić nowe potrzeby biznesowe. Kropka. Używanie EAV to tylko jedno z narzędzi dostępnych w naszym pudełku; ale nigdy nie powinien być automatycznie klasyfikowany jako „zły”.

Jerry Jasperson
źródło
2
+1 za „Korzystanie z EAV jest tylko jednym z narzędzi dostępnych w naszym pudełku, ale nigdy nie powinno być automatycznie klasyfikowane jako„ złe ”.
Catchops
Przy okazji, nazywa się to SCD (powoli zmieniające się wymiary). Również wymagania czasowe (szczególny przypadek SCD typu 4) wymagają schematu EAV dla atrybutów, które mają tę właściwość. Pamiętaj, że 99% NoSQL nie ma natywnych złączeń, więc jeśli potrzebujesz złączeń „na żywo” z tego typu danymi, EAV jest jedyną drogą.
cowbert
3

Zmagam się z tym samym problemem. Może Cię zainteresować poniższa dyskusja na temat dwóch istniejących rozwiązań e-commerce: Magento (EAV) i Joomla (zwykła struktura relacyjna): https://forum.virtuemart.net/index.php?topic=58686.0

Wygląda na to, że wydajność EAV Magento jest prawdziwym hitem.

Dlatego skłaniam się ku znormalizowanej strukturze. Aby przezwyciężyć brak elastyczności, myślę o dodaniu w przyszłości oddzielnego słownika danych (XML lub oddzielne tabele DB), który można by edytować i na tej podstawie kod aplikacji do wyświetlania i porównywania kategorii produktów z nowym zestawem atrybutów byłby generowane wraz ze skryptami SQL.

Taka architektura wydaje się w tym przypadku słodka - elastyczna i jednocześnie performatywna.

Problemem może być częste używanie ALTER TABLE w środowisku na żywo. Używam Postgres, więc mam nadzieję, że jego MVCC i transakcyjny DDL złagodzą ból.

aaimnr
źródło
2

Nadal głosuję za modelowaniem na najniższym znaczącym poziomie atomowym dla EAV. Pozwól standardom, technologiom i aplikacjom, które kierują się w stronę określonej społeczności użytkowników, decydować o modelach treści, potrzebach powtarzania atrybutów, ziarnistości itp.

Amanda Xu
źródło
2

Jeśli chodzi tylko o atrybuty katalogu produktów, a zatem wymagania dotyczące walidacji tych atrybutów są raczej ograniczone, jedyną prawdziwą wadą EAV jest wydajność zapytań, a nawet to jest tylko problem, gdy zapytanie dotyczy wielu „rzeczy” (produktów) z atrybutami, wykonanie zapytania „podaj wszystkie atrybuty produktu o identyfikatorze 234”, mimo że nie jest optymalne, jest nadal bardzo szybkie.

Jednym z rozwiązań jest użycie modelu bazy danych SQL / EAV tylko po stronie administratora / edycji katalogu produktów i zastosowanie pewnego procesu denormalizującego produkty w coś, co umożliwia ich przeszukiwanie. Ponieważ masz już atrybuty i dlatego jest raczej prawdopodobne, że chcesz facetingu, to może być Solr lub ElasticSearch. Takie podejście pozwala uniknąć w zasadzie wszystkich wad modelu EAV, a dodatkowa złożoność ogranicza się do serializacji całego produktu do formatu JSON podczas aktualizacji.

pion
źródło
2

EAV ma wiele wad:

  1. Spadek wydajności z upływem czasu Gdy ilość danych w aplikacji przekroczy pewien rozmiar, pobieranie i manipulowanie tymi danymi będzie prawdopodobnie coraz mniej wydajne.
  2. Zapytania SQL są bardzo złożone i trudne do napisania.
  3. Problemy z integralnością danych. Nie możesz zdefiniować kluczy obcych dla wszystkich potrzebnych pól.
  4. Musisz zdefiniować i utrzymywać własne metadane.
Gabriel Voinea
źródło
1. Dotyczy to również większości relacyjnych baz danych; dlatego wymyślono sharding. 2. Modelowanie danych może być złożone i trudne do wdrożenia. Spędziłem tygodnie-miesiące czekając na zmiany schematu kostki OLAP. 3. W większości już zrobione w oprogramowaniu. 4. Musisz to zrobić "w ERwin, Excel i Visio" podczas modelowania schematu relacyjnego.
cowbert
1

Mam nieco inny problem: zamiast wielu atrybutów z rzadkimi wartościami (co jest prawdopodobnie dobrym powodem do korzystania z EAV), chcę przechowywać coś bardziej jak arkusz kalkulacyjny. Kolumny w arkuszu mogą się zmieniać, ale w arkuszu wszystkie komórki będą zawierały dane (nie są rzadkie).

Wykonałem mały zestaw testów, aby porównać dwa projekty: jeden wykorzystujący EAV, a drugi wykorzystujący Postgres ARRAY do przechowywania danych komórki.

EAV wprowadź opis obrazu tutaj

Szyk wprowadź opis obrazu tutaj

Oba schematy mają indeksy w odpowiednich kolumnach, a indeksy są używane przez planistę.

Okazało się, że schemat oparty na tablicy był o rząd wielkości szybszy zarówno w przypadku wstawiania, jak i zapytań. Z szybkich testów wydawało się, że oba skalowały się liniowo. Testy nie są jednak zbyt dokładne. Sugestie i widelce mile widziane - są objęte licencją MIT.

z0r
źródło
Jak wykonałeś łączenia kolumn arkusza (tj. vlookup) z modelem tablicowym? Nie musisz pisać własnej funkcji sortowania przez scalanie tablicy? Wątpię, czy może być tak dobre, jak prekompilowane sortowanie przez scalanie, jeśli użyłeś id_arkusza + współrzędna x + współrzędna y komórki jako klucza wartości komórki. (aby emulować program Excel, wygeneruj wstępnie tabelę odnośników dla współrzędnych x, gdzie 0-18278 to kolumny A-ZZZ (maksymalne wartości programu Excel przy 16384)), możesz następnie wybrać wartości, gdzie sheet_id = uuid i x-koordyn = 0 i y-koordyn <1001, aby uzyskać pierwsze 1000 wierszy
kolumny
@cowbert masz rację; właściwie po prostu ładuję interesujące mnie kolumny i wykonuję złączenie w Pythonie. Luźny!
z0r