2011-12-05 16 views
5

Mam bazę danych pełną przepisów, jeden przepis na wiersz. Muszę przechowywać kilka arbitralnych "flag" dla każdej receptury, aby zaznaczyć różne właściwości, takie jak Gluton-Free, No meat, No Red Meat, No Pork, No Animals, Quick, Easy, Low Fat, Low Sugar, Low Calorie, Niski Sód i Niski Węgiel. Użytkownicy muszą mieć możliwość wyszukania przepisów, które zawierają jedną lub więcej takich flag, zaznaczając pola wyboru w interfejsie użytkownika.Jaki jest najlepszy sposób w PostgreSQL do przechowywania grup arbitralnych wartości boolowskich dla wiersza?

Szukam najlepszego sposobu przechowywania tych właściwości w tabeli Przepisy. Moje dotychczasowe pomysły:

  1. Masz osobną kolumnę dla każdej nieruchomości i utwórz indeks dla każdej z tych kolumn. Mogę mieć około 20 takich właściwości, więc zastanawiam się, czy są jakieś wady z tworzeniem całej grupy kolumn BOOL na jednej tabeli.
  2. Użyj maski bitowej dla wszystkich właściwości i przechowuj całość w jednej kolumnie numerycznej zawierającej odpowiednią liczbę bitów. Utwórz oddzielny indeks dla każdego bitu, aby wyszukiwanie było szybkie.
  3. Utwórz ENUM z wartością dla każdego tagu, a następnie utwórz kolumnę, która ma ARRAY tego typu ENUM. Wierzę, że klauzula ANY w kolumnie tablicy może używać INDEKSU, ale nigdy tego nie robił.
  4. Utwórz osobną tabelę z odwzorowaniem receptur jeden do wielu dla znaczników. Każdy tag będzie wierszem w tej tabeli. Tabela zawierałaby link do receptury oraz wartość ENUM, dla której znacznik jest "włączony" dla tej receptury. Podczas odpytywania, musiałbym zagnieżdżony SELECT, aby odfiltrować receptury, które nie zawierały co najmniej jednego z tych tagów. Wydaje mi się, że jest to bardziej "normalny" sposób robienia tego, ale sprawia, że ​​pewne pytania są bardziej skomplikowane - jeśli chcę zapytać o 100 receptur, a także wyświetlić wszystkie ich tagi, będę musiał użyć INNER JOIN i skonsolidować wiersze lub użyj zagnieżdżonego SELECT i agreguj w locie.

Wydajność zapisu nie jest tu zbyt duża, ponieważ receptury są dodawane w procesie backendu, a szybkość wyszukiwania jest krytyczna (może być kilkaset tysięcy przepisów). Wątpię, czy dodam nowe znaczniki tak często, ale chcę, żeby to było przynajmniej możliwe bez poważnych bólów głowy.

Dzięki!

Odpowiedz

4

Zaleca się stosowanie konfiguracji znormalizowanej. Ustalenie tego od samego początku, jako odroczonej struktury, nie jest tym, co bym poradził.

Nie znając wszystkich szczegółów na temat tego, co się dzieje, myślę, że najlepszą konfiguracją byłoby posiadanie tabeli receptur i nowej tabeli właściwości oraz nowej tabeli receptury_właściwości. Dzięki temu receptura może mieć 0 lub wiele właściwości i normalizuje dane, dzięki czemu jest ona łatwa w utrzymaniu i sprawdzaniu danych.

struktura wysoki poziom byłby:

CREATE TABLE recipe(recipe_id); 
CREATE TABLE property(property_id); 
CREATE TABLE recipe_property(recipe_property_id,recipe_id,property_id); 
+0

Yup to zdecydowanie jedna droga. Zastanawiam się również nad użyciem 'ENUM' zamiast' property_id' i nie mając tabeli 'property'. Chociaż wewnętrznie w bazie danych to to samo, co masz. –

+0

Upewnij się, że ostateczne rozwiązanie nie pomaluje Cię w kąt. – Kuberchaun

+1

Skończyło się na znormalizowanej trasie po otrzymaniu tej samej porady od wielu ekspertów. Jednak krótko zajrzałam do modułu 'hstore' dla PostgreSQL, który jest całkiem słodki; jednak postanowiłem nie używać go w tej konkretnej sytuacji. –

Powiązane problemy