Alternatywa dla EAV dla pól dynamicznych w hurtowni danych w schemacie gwiazdy


13

Potrzebuję obsługiwać dynamiczne pola i wartości w dużej przechowalni danych do przechowywania dziennika żądań API, moim przypadkiem użytkownika jest to, że muszę przechowywać wszystkie ciągi zapytań API i móc wykonywać zapytania przeciwko nim w przyszłości (więc nie jest to tylko przechowywanie, więc nie mogę używać dla nich obiektów blob)

na przykład http://example.com/?action=test&foo=abc&bar=def...

Muszę przechowywać wszystkie field => valuemapowania, tzn. (action => test), (foo => abc), (bar => def)Ponieważ pole jest tak dynamiczne, jedynym rozwiązaniem, jakie znalazłem, jest użycie Entity-Attribute-Value, jednak ludzie twierdzą, że jest to bardzo zły projekt.

Zastanów się więc nad moim przykładem użycia, jaka byłaby odpowiednia alternatywa dla EAV?

Mój obecny schemat za pomocą KAV

  1. Tabela requests
    (id, timestamp, uri)
    np(1, 149382220, '/')

  2. Tabela params
    (request_id, key, value)
    np(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')

Jakieś sugestie?

Aktualizacja: Prowadzimy magazyn na AWS RedShift


2
Co jest złego w próbowaniu tego, co sugerujesz w bazie danych deweloperów? Mówisz też o SQL Server? Znacznik sql jest dość szeroki.
Max Vernon

Zaktualizowałem moje pytanie
Howard

1
Z którego DBMS korzystasz? Niektóre mają całkiem dobre możliwości indeksowania tekstu, więc nie wykluczam używania pola „długiego tekstu” do przechowywania żądań. Powiedziawszy to, nie miałbym problemu z użyciem proponowanego modelu. Chociaż EAV w ścisłym tego słowa znaczeniu, jest wykorzystywany tylko do tego bardzo konkretnego celu. Ponownie, powiedziawszy to, jakie pytania musisz wykonać? Spróbuj napisać te zapytania w odniesieniu do tego modelu, aby sprawdzić, czy działa on dla Ciebie.
Colin 't Hart

1
Jakiego RDBMS używasz? SQLnie jest wystarczająco szczegółowe. Zostałeś dwukrotnie zapytany. Jestem trzeci
Erwin Brandstetter,

2
Od RedShift jest oparta na PostgreSQL, chciałbym spróbować użyć hstorelub jsontypy danych (lub jsonbjeśli / kiedy „upgrade” do 9,4).
Colin 't Hart

Odpowiedzi:


11

Mogę wymyślić trzy rozwiązania - EAV, XML i rzadkie kolumny. Ten ostatni jest specyficzny dla dostawcy i może nie być dla Ciebie przydatny.

Niezależnie od wybranej metody, możesz rozważyć zapisanie oryginalnych danych żądania w surowym formacie, w pliku tabeli lub pliku płaskim. Ułatwi to wypróbowanie nowych sposobów przechowywania danych, pozwoli na ponowne załadowanie danych, jeśli odkryjesz błąd w sposobie analizowania żądań, i zaoferuje możliwości analizowania żądań interfejsu API przy użyciu przetwarzania wsadowego lub „dużych zbiorów danych” narzędzia, jeśli okaże się, że hurtownia danych nie jest w stanie skutecznie poradzić sobie z danymi.

Uwagi dotyczące EAV

EAV / KVS, jak to opisano powyżej, prawdopodobnie będzie najprostszą implementacją.

Niestety będzie to również bardzo kosztowne - aby uzyskać wydajne zapytania dotyczące często używanych kluczy, musisz mieć indeksy w kolumnie kluczy, które mogą ulec bardzo fragmentacji. Zapytanie o określone klucze byłoby niezwykle kosztowne.

Możesz być w stanie obniżyć koszty indeksowania lub skanowania indeksów, wspierając sklep EAV za pomocą zmaterializowanych widoków (obsługuje to wielu dostawców) w celu zapytania o klucze lub wartości, na których Ci zależy.

XML

Większość korporacyjnych systemów baz danych oferuje bardzo dojrzałą obsługę XML, w tym sprawdzanie poprawności, indeksowanie i zaawansowane zapytania.

Załadowanie żądania API do bazy danych jako XML zapewniłoby jedną krotkę na żądanie, co logicznie może być dla ciebie bardziej smaczne niż posiadanie nieznanej liczby wierszy w tabeli EAV.

To, czy jest to wydajne, zależy w dużej mierze od dostawcy RDBMS i wdrożenia.

Największym minusem jest to, że jest to prawdopodobnie jedyny sposób zarządzania danymi, który jest bardziej skomplikowany niż manipulowanie ciągiem pierwotnego żądania!

Rzadkie kolumny / tradycyjne tabele

Możliwe, że możesz załadować swoje dane do tradycyjnej struktury tabeli, z jedną kolumną na klucz.

Funkcja rzadkich kolumn programu SQL Server jest doskonałą alternatywą dla sklepu EAV. Tabela z rzadkimi kolumnami zachowuje się tak samo jak normalna tabela, z tym wyjątkiem, że może mieć do 30 000 kolumn, a wartości NULL w rzadkich kolumnach nie zajmują miejsca w tabeli.

Połączenie ich z Filtrowanymi Indeksami (kolejna funkcja specyficzna dla SQL Server) może zapewnić niezwykle wydajną alternatywę dla sklepu EAV, jeśli często pytasz o kilka konkretnych kolumn i / lub wartości.

Używanie tradycyjnej tabeli z innymi dostawcami może być opłacalne - IBM obsługuje ponad 700 kolumn na tabelę, a Oracle około 1000, a funkcje takie jak kompresja lub przetwarzanie przez Oracle wartości końcowych zer może oznaczać, że możesz dość skutecznie przechowywać dane API.

Oczywistym minusem tego podejścia jest to, że po dodaniu nowych kluczy do interfejsu API konieczne będzie odpowiednie dostosowanie schematu.


2
W PostgreSQL nie polecam XML ale albo hstorealbo json. W nadchodzących 9,4 jsonbbędzie moją rekomendacją.
Colin 't Hart

Naprawdę podoba mi się ta odpowiedź z zaletami i wyjaśnieniem każdego z nich. Bardzo pouczające - zdecydowanie doceniam informacje o rzadkich kolumnach. Chciałbym przykład EAV wykorzystujący podejście rzadkich kolumn.
StixO

9

EAV nie jest złym projektem, sam w sobie, to po prostu projekt, który wymaga sporego dogłębnego przemyślenia i może być spowodowany problemami z wydajnością w miarę wzrostu ilości danych. Może być tak, że w twoim systemie działałoby to dobrze.

Kiedy zaprojektowany system do przechowywania ciągów zapytań, nie miałem pojęcia, z wyprzedzeniem co polach byłbym zainteresowany. Stworzyłem tabelę do przechowywania ciąg kwerendy w formacie serializowanym binarnym, a wbudowany system, który pozwolił mi rozpadł zapytania po zapoznaniu się z kawałkami, którymi się interesowałem, zawiążcie w jego elementach składowych. Stamtąd stworzyłem zestaw tabel; po jednym dla zestawów danych zwykle zawartych w ciągu zapytania.

Na przykład w końcu miałem tabelę dla danych odsyłających, jedną dla danych żądania docelowego i jedną dla elementów związanych z użytkownikiem, takich jak wyszukiwane hasło, które wprowadzili.

Znalazłem możliwość przechowywania całego ciągu zapytania w jednej tabeli jako obiektu blob, a jednocześnie możliwość dzielenia tego obiektu w przyszłości bardzo dobrze spełniło moje potrzeby.


1
Zarówno w pytaniu, jak i w odpowiedzi BLOBużyto terminu, co oznacza Binarny Długi Obiekt. Wolałbym używać CLOB(Object Long OBject) lub czegoś takiego jak textw PostgreSQL, ponieważ mówimy o postaci, a nie danych binarnych.
Colin 't Hart

2
Użyłem pola binarnego, ponieważ właściwie serializowałem cały obiekt sesji i zapisałem całą rzecz w bazie danych.
Max Vernon
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.