Каков наилучший способ в Postgres хранить несколько произвольных логических значений для строки? - PullRequest
5 голосов
/ 05 декабря 2011

У меня есть база данных, полная рецептов, по одному рецепту на строку.Мне нужно хранить несколько произвольных «флагов» для каждого рецепта, чтобы отметить различные свойства, такие как отсутствие глютона, отсутствие мяса, отсутствие красного мяса, отсутствие свинины, отсутствие животных, быстрый, легкий, низкий уровень жира, низкий уровень сахара, низкая калорийность,Низкий натрий и низкий карбонат.Пользователи должны иметь возможность искать рецепты, содержащие один или несколько из этих флагов, установив флажки в пользовательском интерфейсе.

Я ищу лучший способ сохранить эти свойства в таблице рецептов.Мои идеи до сих пор:

  1. Для каждого свойства есть отдельный столбец и создайте индекс для каждого из этих столбцов.У меня может быть более 20 таких свойств, поэтому мне интересно, есть ли какие-либо недостатки в создании целой группы столбцов BOOL в одной таблице.
  2. Используйте битовую маску для всех свойств и сохраните все этов одном числовом столбце, который содержит соответствующее количество битов.Создайте отдельный индекс для каждого бита, чтобы поиск был быстрым.
  3. Создайте ENUM со значением для каждого тега, а затем создайте столбец с массивом этого типа ENUM.Я полагаю, что ЛЮБОЕ предложение в столбце массива может использовать INDEX, но никогда этого не делали.
  4. Создайте отдельную таблицу, в которой есть сопоставление рецептов «один ко многим» с тегами.Каждый тег будет строкой в ​​этой таблице.Таблица будет содержать ссылку на рецепт и значение ENUM, для которого тег «включен» для этого рецепта.При запросе я должен был бы сделать вложенный SELECT, чтобы отфильтровать рецепты, в которых не было хотя бы одного из этих тегов.Я думаю, что это более «нормальный» способ сделать это, но он делает некоторые запросы более сложными - если я хочу запросить 100 рецептов, а также отобразить все их теги, мне придется использовать INNER JOIN и объединитьстрок или используйте вложенный SELECT и агрегируйте на лету.

Производительность записи здесь не слишком большая проблема, так как рецепты добавляются бэкэнд-процессом, а скорость поиска критична (может бытьнесколько сотен тысяч рецептов в итоге).Я сомневаюсь, что я буду добавлять новые теги так часто, но я хочу, чтобы по крайней мере было возможно обойтись без серьезных головных болей.

Спасибо!

1 Ответ

4 голосов
/ 05 декабря 2011

Я бы посоветовал вам использовать нормализованную установку. Настроить это с самого начала как ненормализованную структуру - это не то, что я бы посоветовал.

Не зная всех подробностей того, что он делает, я думаю, что лучшая установка будет иметь вашу таблицу рецептов и новую таблицу свойств и новую таблицу recipe_property. Это позволяет рецепту иметь 0 или несколько свойств и нормализует ваши данные, делая его быстрым и простым в обслуживании и запросе ваших данных.

Структура высокого уровня будет:

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