Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: Отметка о почтении средствами MySQL [РЕШЕНО]  (Прочитано 931 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн gva230

  • Автор темы
  • Активист
  • *
  • Сообщений: 981
  • GUI-овый линуксоид
    • Просмотр профиля
    • Моя дикая страничка
Есть сайт с пользователями и статьями. В списке статей на сайте пользователь видит рядом с заголовком надпись "новая" или не видит таковой, если уже статью читал. Данные о прочитанных статьях хранятся в виде списка номеров статей через запятую, соответствующего номеру пользователя. Выглядит примерно так:
user_id | article_id                    |
-----------------------------------------
1       | 1,2,10,11,12,25,45,15,28,32,5 |
2       | 2,15,12,55,32,22              |
4       | 23,2,22,12,14,52,24           |
-----------------------------------------
Нужно во время выборки статей из другой таблицы проверять article_id соответствующего пользователя на наличие её номера, чтобы определить прочитана-ли она пользователем или нет. И это нужно сделать средствами MySQL.

У меня получилась вот такая нерабочая конструкция:
Код: (sql) [Выделить]
SELECT articles_table.id, articles_table.name, EXISTS(SELECT readed_table.article_id FROM readed_table WHERE readed_table.user_id = '2' AND readed_table.article_id REGEXP 'articles_table.id') AS readed FROM articles_table
А не работает оно потому что в качестве шаблона для регулярного выражения передаётся строка "articles_table.id" вместо содержимого этой ячейки. Как бы так передать это содержимое? Есть идеи?
« Последнее редактирование: 02 Сентября 2013, 23:09:22 от gva230 »
Kubuntu - наше фсё! :Ь

Оффлайн MonoLife

  • Активист
  • *
  • Сообщений: 357
  • "Пилите, Шура, пилите!" ©
    • Просмотр профиля
    • Under sky of Half-Life
Re: Отметка о почтении средствами MySQL
« Ответ #1 : 02 Сентября 2013, 07:50:57 »
без одинарных кавычек или таких: `articles_table.id`
не?

Оффлайн MuadDlb

  • Участник
  • *
  • Сообщений: 147
  • The Dune Messiah
    • Просмотр профиля
Re: Отметка о почтении средствами MySQL
« Ответ #2 : 02 Сентября 2013, 08:35:03 »
Немного не понял в чем у вас проблема. На каком языке пишите?

Вобще вы отдаете себе отчет в том что вы делаете?
Выполните explain ваш_запрос и киньте его сюда, а заодно еще раз перечитайте мой вопрос.
Если таки отдаете: надеюсь у вас хотя бы таблицы myisam

Храните флаг просмотра статьи в куки, если не устраивают куки то таблица
create table readed_table(article_id int(8) unsigned not null, user_id int(8) unsigne not null, primary key (article_id, user_id)) engine=mysiam;
тогда

SELECT at.id, at.name,if(rt.user_id>0,1,0) as readed FROM articles_table as at left join readerd_table as rt on at.id=rt.article_id and rt.user_id=2

и при прочтении статьи просто выполняете инсерт игнорирую ошибку дублирования ключа.

Оффлайн gva230

  • Автор темы
  • Активист
  • *
  • Сообщений: 981
  • GUI-овый линуксоид
    • Просмотр профиля
    • Моя дикая страничка
Re: Отметка о почтении средствами MySQL
« Ответ #3 : 02 Сентября 2013, 23:07:55 »
Проблема решена! MonoLife, MuadDlb, примите мои благодарности за пинки в правильном направлении. :)

Как я и предполагал, проблема крылась в шаблоне, передаваемом в REGEXP. Собственно, нужно было передать переменную, но REGEXP отказывался меня понимать. В примере из первого поста я опустил парсинг строки, для простоты понимания. Но делать этого не стоило, ведь проблема была именно там. Изначально конструкция выглядела примерно так:
Код: (sql) [Выделить]
SELECT articles_table.id, EXISTS(SELECT readed_table.article_id FROM readed_table WHERE readed_table.user_id = '2' AND readed_table.article_id
REGEXP 'articles_table.id') AS readed
FROM articles_table
Здесь REGEXP ищет строку "articles_table.id" и разумеется всегда её не находит. Корректный код выглядит так:
Код: (sql) [Выделить]
SELECT articles_table.id, EXISTS(SELECT readed_table.article_id FROM readed_table WHERE readed_table.user_id = '2' AND readed_table.article_id
REGEXP articles_table.id) AS readed
FROM articles_table
Здесь REGEXP ищет номер статьи в строке из поля "articles_table.id" и находит его, однако во избежание путаницы с многозначными номерами статей, нужен парсинг этой строки и вот тут у меня возник затык. Один из вариантов неправильного кода выглядит так:
Код: (sql) [Выделить]
SELECT articles_table.id, EXISTS(SELECT readed_table.article_id FROM readed_table WHERE readed_table.user_id = '2' AND readed_table.article_id
REGEXP '(^articles_table.id,)|(,articles_table.id,)|(,articles_table.id$)') AS readed
FROM articles_table
Текст "(^articles_table.id,)|(,articles_table.id,)|(,articles_table.id$)" трактуется MySQL, как строка, а так как слова "articles_table.id" у меня в таблице нет, от код ищет не понятно что и естественно ничего не находит. Один из вариантов правильного кода выглядит так:
Код: (sql) [Выделить]
SELECT articles_table.id, EXISTS(SELECT readed_table.article_id FROM readed_table WHERE readed_table.user_id = '2' AND readed_table.article_id
REGEXP CONCAT('(^',articles_table.id,',)|(,',articles_table.id,',)|(,',articles_table.id,'$)')) AS readed
FROM articles_table
Здесь в строку "CONCAT('(^',articles_table.id,',)|(,',articles_table.id,',)|(,',articles_table.id,'$)')" вместо "articles_table.id" подставляются соответствующие значения и REGEXP получает корректный шаблон для поиска.

Всем спасибо за внимание. :)
Kubuntu - наше фсё! :Ь

Оффлайн MuadDlb

  • Участник
  • *
  • Сообщений: 147
  • The Dune Messiah
    • Просмотр профиля
Re: Отметка о почтении средствами MySQL [РЕШЕНО]
« Ответ #4 : 03 Сентября 2013, 08:29:55 »
Ну как хотите: хана вашей базе когда накопится тысяч 50 строк.

Оффлайн gva230

  • Автор темы
  • Активист
  • *
  • Сообщений: 981
  • GUI-овый линуксоид
    • Просмотр профиля
    • Моя дикая страничка
Re: Отметка о почтении средствами MySQL [РЕШЕНО]
« Ответ #5 : 03 Сентября 2013, 20:58:45 »
Ну как хотите: хана вашей базе когда накопится тысяч 50 строк.
Ну вот смотрите, допустим есть 10000 статей и 1000 пользователей. Предложенная вами таблица будет иметь максимум 10000000 (десять миллионов!) строк. Моя таблица будет иметь 1000 строк - ни больше, ни меньше. 50000 строк появится только при наличии 50000 пользователей.

Или я чего-то не понимаю? Поясните пожалуйста.
Kubuntu - наше фсё! :Ь

 

Страница сгенерирована за 0.018 секунд. Запросов: 22.