LINUX.ORG.RU

Хранение тегов к изображениями в mysql

 


3

3

Есть набор изображений. Пока их было меньше 100 рядом с каждым хранил xml файл с описанием и списком тегов. Грепал каталог по тегу, получал список файлов, скармливал дальше.

ВНЕЗАПНО каталог разросся до 500 ГБ. греп теперь работает 5 минут, что неудобно. Хочу перенести в базу mysql, благо она уже поднята.

Как мне хранить теги к изображениям (структура таблицы), учитывая что у изображения есть минимум один тег, и может их быть хоть полмиллиона. С заточкой под производительность, ибо файлов очень много.

★★★★★

Последнее исправление: PPP328 (всего исправлений: 1)
Ответ на: комментарий от theNamelessOne

С запросами типа like '%2017%' есть одна проблема: ни MySQL, ни Postgres не могут использовать индексы, если паттерн начинается на wildcard (т.е. первый символ шаблона — '%').

Это верно, но можно не лайкать, а строить Fulltext Index , а затем использовать поиск в BOOLEAN MODE, работает очень быстро и будет удобно складывать и даже исключать теги, например «+геленджик -лето» найдет все геленджики кроме тех, что с летом.

surefire ★★★
()
Последнее исправление: surefire (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

У моего запроса будет using index, если я не путаю. А что у вас?

Вот этого не скажу. У меня только постгрес есть, а он про tmp ничего не говорит.

aureliano15 ★★
()
Ответ на: комментарий от AndreyKl

сортировка всё таки дело дорогое.

Имхо, если фотографии будут добавляться намного реже, чем просматриваться, то относительно не такое уж и дорогое.

aureliano15 ★★
()
Ответ на: комментарий от surefire

вероятно лучшее решение, я уже и забыл про фуллтекс индексы

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

Можно взять Postgres и хранить теги (или идентификаторы тегов) в массивах, получится примерно такой вариант, как и у тебя, только без ограничения на количество тегов для отдельной записи и монструозных запросов.

theNamelessOne ★★★★★
()
Ответ на: комментарий от aureliano15

Так у него ведь в запросе сортировка. т.е. частота добавления не важна, так как сортировка выполняется на каждый селект.

AndreyKl ★★★★★
()
Ответ на: комментарий от theNamelessOne

Спасибо за ссылку.

Что то в searching in arrays не упомянуто про индексы. Индексы то будут?

АПД.

Ан нет, пардон, сказали будут индексы, это я пропустил.

Спасибо.

Вопрос про фуллтекст в силе, если будет минутка, буду благодарен.

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от AndreyKl

А кстати говоря, постгрес может полнотекстовый поиск в булевом режиме

в булевом режиме

Это типа «искать документы, в которых встречаются одни теги и нет других»? Может, ссылка раз:

to_tsquery creates a tsquery value from querytext, which must consist of single tokens separated by the Boolean operators & (AND), | (OR) and ! (NOT). These operators can be grouped using parentheses.

ссылка два.

Рекомендую почитать доку.

theNamelessOne ★★★★★
()
Ответ на: комментарий от theNamelessOne

Похоже на правду, благодарю за ссылки.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

Что то в searching in arrays не упомянуто про индексы. Индексы то будут?

Да, массивы можно проиндексировать GIN-индексами, которые поддерживают операторы @> (массив содержит подмассив), <@ (подмассив содержится в массиве), =, && (у двух массивов непустое пересечение, то есть у них есть общие элементы). Операции «содержится» можно использовать, чтобы найти записи, в которых есть все теги из перечисленных, операцию «пересечение» — чтобы найти записи, в которых есть любой из перечисленных тегов.

theNamelessOne ★★★★★
()
Ответ на: комментарий от PPP328

УЖСНХ...

Вот на три таблицы, выборка по множеству тегов, быстрая:

SELECT
        f.filename
    FROM tags_files tf
    INNER JOIN files f
        ON f.id = tf.file_id
    WHERE tf.tag_id IN(
        SELECT
                id
            FROM tags
            WHERE name IN('tag1', 'tag2', 'tag3', 'tagN')
    )
    GROUP BY f.id
Какие в жопу лайки в тегах? Имя тега неделимо на подстроки, это же теги.

deep-purple ★★★★★
()
Ответ на: комментарий от AndreyKl

Так у него ведь в запросе сортировка. т.е. частота добавления не важна, так как сортировка выполняется на каждый селект.

Наверно я чего-то не понимаю, но, как мне кажется, для того и придуманы индексы. Создать индекс для поля filename таблицы images, и ничего сортировать каждый раз не придётся.

aureliano15 ★★
()
Ответ на: комментарий от anonymous

Ну тогда HAVING в конец добавляем чтобы было равно кол-ву переданных тегов. Но мне было бы интересно погонять на больших объемах данных вот эти вагончики:

SELECT
        f.filemane
    FROM files f
    /* tag1 */
    INNER JOIN tags_files tf1
        ON tf1.file_id = f.id
    INNER JOIN tags t1
        ON t1.id = tf1.tag_id
            AND t1.name = 'tag1'
    /* tag2 */
    INNER JOIN tags_files tf2
        ON tf2.file_id = f.id
    INNER JOIN tags t2
        ON t2.id = tf2.tag_id
            AND t2.name = 'tag2'
    /* tag3 */
    INNER JOIN tags_files tf3
        ON tf3.file_id = f.id
    INNER JOIN tags t3
        ON t3.id = tf3.tag_id
            AND t3.name = 'tag3'
    /* tagN */
    INNER JOIN tags_files tfN
        ON tfN.file_id = f.id
    INNER JOIN tags tN
        ON tN.id = tfN.tag_id
            AND tN.name = 'tagN'

deep-purple ★★★★★
()
Ответ на: комментарий от anonymous

Так id есть, по нему можно будет и партиционировать в перспективе (:

MrClon ★★★★★
()
Ответ на: комментарий от aureliano15

вероятно так не получится. сортируется ведь _выборка_. А если индекс создать то он на всю таблицу а не на выборку. в общем случае индекс на таблице никак не поможет отсортировать выборку.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

Да. Похоже так и есть. В некоторых случаях даже при выборке можно для сортировки использовать индекс, но не для having. По крайней мере, если верить http://www.nsc.ru/win/docs/db/sql/sql25.htm :

10. Для фильтрации записей используйте WHERE, а не HAVING.

Избегайте использования раздела HAVING вместе с GROUP BY на индексированных столбцах. В этом случае индекс не используется. Фильтруйте строки с помощью раздела WHERE, а не раздела HAVING.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

не, это вроде не про сортировку.

просто where может использовать индекс, и тогда отработает очень быстро. Это как раз то что я сделал в своём первом варианте. А having в принципе не может, это ж группировка выборки, там результат непредсказуем в общем случае.

AndreyKl ★★★★★
()

ВНЕЗАПНО каталог разросся до 500 ГБ. греп теперь работает 5 минут, что неудобно

А если использовать локейл вместо грепа?

ya-betmen ★★★★★
()
Ответ на: комментарий от AndreyKl

не, это вроде не про сортировку.
просто where может использовать индекс, и тогда отработает очень быстро. Это как раз то что я сделал

Да, посмотрел внимательней, именно так. Но всё-таки в мускуле возможно в некоторых случаях использование индекса в order by даже при наличии фильтра where. Вот что я нагуглил: http://www.mysql.ru/docs/man/ORDER_BY_optimisation.html и https://habrahabr.ru/post/138163/ .

Хотя, если честно, раньше мне казалось, что индексы для сортировки могут использоваться куда чаще, чем на самом деле. :-)

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

ссылки на доки хороши, я что то этого не читал раньше, спасибо.

AndreyKl ★★★★★
()
Ответ на: комментарий от Twissel

https://www.youtube.com/watch?v=mkI2q6twyc0

Спасибо за ссылку. Всё никак не мог собраться посмотреть, но наконец-то добрался. Интересная лекция. Там, вроде, и другие есть. Тоже как-нибудь посмотрю. Оказывается, с мускулом всё даже ещё хуже, чем я думал. Хотя для домашней бд с одним пользователем большинство косяков, о которых говорилось в лекции, не имеют значения.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Оказывается, с мускулом всё даже ещё хуже, чем я думал. Хотя для домашней бд с одним пользователем большинство косяков, о которых говорилось в лекции, не имеют значения.

Ага. Дьявол скрывается в деталях.

Twissel ★★★★★
()
Ответ на: комментарий от aureliano15

Вот тебе взгляд с другой стороны (1, 2). Юзеры посгреса в значительной мере склонны к сектантству. Связано с диким и непрекращающимся по сию пору баттхёртом от слова LAMP.

anonymous
()
Ответ на: комментарий от anonymous

Вот тебе взгляд с другой стороны (1, 2).

Спасибо за ссылки. Было интересно почитать. И хотя лекция на ютюбе лично мне кажется более аргументированной, всегда интересно узнать доводы противоположной стороны. Ведь если мускул ещё не умер, значит это кому-нибудь нужно... :-)

aureliano15 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.