Эффективный метод поиска строк базы данных, которые имеют * одно или несколько * качеств из списка из семи качеств - PullRequest
1 голос
/ 14 января 2011

По этому вопросу я смотрю, есть ли у кого-нибудь лучшее представление о том, как реализовать то, что я в настоящее время планирую реализовать (ниже):

Я отслеживаю набор изображений, используя базу данных. Каждое изображение представлено одной строкой.

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

Изображения в этой базе данных могут содержать до семи цветов:

-красный

1011 *-оранжевый *

-Желтая

-зеленый

-Синий

-Indigo

-Violet


Вот несколько примеров пользовательских запросов:

«Я хочу изображение, содержащее красный цвет».

«Я хочу изображение, содержащее красный и синий.»

«Я хочу изображение, содержащее желтый и фиолетовый.»

«Мне нужно изображение, содержащее красный, оранжевый, желтый, зеленый, синий, индиго и фиолетовый.»


И так далее. Пользователи делают этот выбор с помощью флажков в HTML-форме. Они могут установить нулевые флажки, все семь и все, что между ними.

Мне любопытно услышать, что люди считают наиболее эффективным способом поиска в базе данных.

У меня есть два возможных варианта сейчас, но я чувствую, что должно быть что-то лучшее, о чем я не думаю.

(вариант 1)
-Для каждой строки просто есть семь дополнительных полей в базе данных, по одному для каждого цвета. Каждое поле содержит значение 1 или 0 (истина / ложь), и я выбираю в зависимости от того, что выбрал пользователь. (Мне не очень понравилось это решение, потому что было несколько расточительно добавить семь дополнительных полей ... тем более, что большинство изображений в этой таблице будут иметь максимум 3-4 цвета, хотя некоторые могут иметь до 7. Так что это означает, что я храню много нулей.) Кроме того, если бы я добавил больше доступных для поиска цветов позже (что, я думаю, не буду, но это всегда возможно), я должен был бы добавить больше полей.

(вариант 2)
-Для каждой строки изображения у меня может быть текстовое поле «цвета», в котором хранятся разделенные пробелами названия цветов (или цифры для компактности). Затем я мог бы выполнить полнотекстовое сопоставление с поиском по полям, выбрав строки, содержащие «красный, желтый, зеленый» (или «1 3 4»). Но я вроде не хотел выполнять полнотекстовый поиск, потому что я уже разрешил поиск по ключевым словам, и я действительно не хотел делать два полнотекстовых поиска для поиска изображений. Кроме того, если база данных становится большой, полнотекстовые файлы могут замедляться.

Есть лучшие варианты, о которых я не думал?

Спасибо!

Примечание: я использую PHP для работы с базой данных MySQL.

Ответы [ 3 ]

4 голосов
/ 14 января 2011

Вы можете создать вторую таблицу под названием цвета.

  colors = (color_id, name)

и таблица отношений image_colors.

  image_colors = (image_id, color_id)

Затем в таблицу image_colors вы добавляете строку для каждого цвета каждого изображения.

 image_colors
 Image_id     Color_id
  1            1
  2            3
  2            4

Таким образом, изображение 1 имеет один цвет, а изображение 2 имеет два цвета.

Чтобы найти изображение с, скажем, цветом 4 и 5, вы можете

    select  i.fileName, etc
    from images i JOIN image_colors c ON
         i.image_id = c.image_id
    where
         c.color_id = 4 OR
         c.color_id = 5

Преимуществом этого решения является простота запросов.

1 голос
/ 14 января 2011

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

Для чего стоит, если выкогда-либо получится перейти на Oracle, растровые индексы созданы именно для такого рода вещей.

0 голосов
/ 14 января 2011

Вы можете сохранить дополнительное поле INT и сохранить 1 число, представляющее побитовое определение флагов связанных цветов.При поиске вы можете просто выполнить ту же побитовую операцию, чтобы запросить конкретное целочисленное значение.

Посмотрите на комментарий Марка Каина на этой странице справочного руководства MySql для хорошего примера того, что я предлагаю:

http://dev.mysql.com/doc/refman/5.0/en/bit-functions.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...