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 => value
mapowania, 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
Tabela
requests
(id, timestamp, uri)
np(1, 149382220, '/')
Tabela
params
(request_id, key, value)
np(1, 'action', 'test'), (1, 'foo', 'abc'), (1, 'bar', 'def')
Jakieś sugestie?
Aktualizacja: Prowadzimy magazyn na AWS RedShift
SQL
nie jest wystarczająco szczegółowe. Zostałeś dwukrotnie zapytany. Jestem trzecihstore
lubjson
typy danych (lubjsonb
jeśli / kiedy „upgrade” do 9,4).Odpowiedzi:
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.
źródło
hstore
albojson
. W nadchodzących 9,4jsonb
będzie moją rekomendacją.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.
źródło
BLOB
użyto terminu, co oznacza Binarny Długi Obiekt. Wolałbym używaćCLOB
(Object Long OBject) lub czegoś takiego jaktext
w PostgreSQL, ponieważ mówimy o postaci, a nie danych binarnych.