Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Выборка тэгов
 
 автор: Qiao   (07.05.2009 в 11:00)   письмо автору
 
 

Привет, ребята.

Делаю систему тэгов для новостей.

У каждой новости есть поле tags, в которой через запятую перечислены id тэгов. Например: 3,7,12

Когда щёлкаешь по имени тэга (которое формируется через id), должен появиться список новостей, у которых есть этот тэг.

Вот тут я и споткнулся - есть id тэга, требуется выбрать новости, у которых в поле tags оно встречается. Пользоваться поиском нельзя: тэг 12 станет тэгом 1 и 2.


Подскажите, пожалуйста, как лучше решить эту проблему.

  Ответить  
 
 автор: Trianon   (07.05.2009 в 11:14)   письмо автору
 
   для: Qiao   (07.05.2009 в 11:00)
 

лучше хранить 3 7 и 12 не в одной ячейке, а на отдельных строках.

  Ответить  
 
 автор: Qiao   (07.05.2009 в 11:49)   письмо автору
 
   для: Trianon   (07.05.2009 в 11:14)
 

А сколько тогда строк делать? Ведь неизвестно сколько у одной новости тэгов.
Да, обычно 1-2-3, но ведь может иногда попадаться и по 5-10. Получается будет много пустых, да и ограничения.

Пока что лучшее что нашёл - выкручиваться регулярными выражениями - WHERE tags REGEXP '[^\d]$id[^\d]'.
Но не знаю насколько это оптимально - говорят, регулярки базу грузят.

  Ответить  
 
 автор: cheops   (07.05.2009 в 11:57)   письмо автору
 
   для: Qiao   (07.05.2009 в 11:49)
 

Почему строки и удобны, если они пустые - их можно не создавать, а создавать только те записи, которые заполнены. Со столбцами такой номер уже не проходит.

Просто не жадничайте на таблицы - выделите под это дело отдельную таблицу и дело с концом.

  Ответить  
 
 автор: Qiao   (07.05.2009 в 12:08)   письмо автору
 
   для: cheops   (07.05.2009 в 11:57)
 

Я не понимаю.
Например, есть таблица новостей:
id | body | tags

Вы предлагаете
id | body | tag1 | tag2 | tag3 | tag4 | tag5 ...
?

И как выделить таблицу? У меня есть таблица тэгов, но там просто
id | name

Поясните, пожалуйста, про новую таблицу.

  Ответить  
 
 автор: Trianon   (07.05.2009 в 12:14)   письмо автору
 
   для: Qiao   (07.05.2009 в 12:08)
 

предлагалось хранить номера тегов не в разных ячейках одной строки, а в одном столбце, на разных строках отдельной - третьей таблицы.

  Ответить  
 
 автор: cheops   (07.05.2009 в 12:17)   письмо автору
 
   для: Qiao   (07.05.2009 в 12:08)
 

Я предлагаю в первую таблицу новостей сделать такой
id | body
Вторую таблицу тэгов
id | name
оставить без изменений, и ввести третью таблицу, связывающую первые две
id | id_news | id_tag

PS Т.е. выполнить классическую нормализацию.

  Ответить  
 
 автор: Qiao   (07.05.2009 в 12:23)   письмо автору
 
   для: cheops   (07.05.2009 в 12:17)
 

Спасибо всем, дошло.
Попробую так.

Просто раньше никогда не создавал таблицы, в которых id не было бы чем-то реальным.
Хотя в теории когда-то что-то подобное читал )

  Ответить  
 
 автор: Trianon   (07.05.2009 в 12:44)   письмо автору
 
   для: Qiao   (07.05.2009 в 12:23)
 

А Вы можете этот столбик id не создавать вообще.

А перичный ключ составным сделать (по двум живым полям)

  Ответить  
 
 автор: Qiao   (07.05.2009 в 12:34)   письмо автору
 
   для: cheops   (07.05.2009 в 12:17)
 

Хотя я вот вашу же цитату в соседней теме прочёл:

> Существует только два фундаментальных способа оптимизации обслуживающего кода и баз данных: чтобы было удобно программистам (скорость разработки) и машине (скорость вычисления). Начинают с первого способа, если не хватает мощности, переходят ко второму.

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

Поэтому меня сейчас терзают сомнения как лучше начать - регулярками или нормализацией.

  Ответить  
 
 автор: Trianon   (07.05.2009 в 12:48)   письмо автору
 
   для: Qiao   (07.05.2009 в 12:34)
 

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

Пля.

  Ответить  
 
 автор: Qiao   (07.05.2009 в 13:04)   письмо автору
 
   для: Trianon   (07.05.2009 в 12:48)
 

Просто уже молоточек зашлифовал - REGEXP '.*\[^\\d\]?$tagID\[^\\d\]?.*'
Красота )

Но вы убедили - буду таблицу делать.
Даже не столько ради производительности, столько для того, чтобы попробовать теорию на практике. А там, глядишь, привыкну.


А что, кстати, оптимальней (по производительности) - делать id или составной ключ?

  Ответить  
 
 автор: Trianon   (07.05.2009 в 14:02)   письмо автору
 
   для: Qiao   (07.05.2009 в 13:04)
 

зависит от характера и частоты запросов...

  Ответить  
 
 автор: Qiao   (07.05.2009 в 14:25)   письмо автору
 
   для: Trianon   (07.05.2009 в 14:02)
 

Запросов тут может быть только два:
SELECT id_news WHERE id_tag=$id
SELECT id_tag WHERE id_news=$id

  Ответить  
 
 автор: Trianon   (07.05.2009 в 14:29)   письмо автору
 
   для: Qiao   (07.05.2009 в 14:25)
 

Здрасти. А добавлять строки в таблицу святым духом будете?

  Ответить  
 
 автор: Trianon   (08.05.2009 в 01:41)   письмо автору
 
   для: Qiao   (07.05.2009 в 14:25)
 

>SELECT id_news WHERE id_tag=$id

Для этого запроса нужен индекс на поле id_tag, либо составной уникальный индекс на полях id_tag, id_news

>SELECT id_tag WHERE id_news=$id

Для этого запроса нужен индекс на поле id_news, либо составной уникальный индекс на полях id_news, id_tag

В принципе, можно сделать два составных индекса (один из которых назначить первичным ключом)

  Ответить  
 
 автор: Qiao   (08.05.2009 в 06:39)   письмо автору
 
   для: Trianon   (08.05.2009 в 01:41)
 

Я сделал
ALTER TABLE `newstags` ADD PRIMARY KEY ( `news_id` , `tag_id` ) ;


Ссылка интересная по теме:
http://www.c2.com/cgi/wiki?FearOfAddingTables

  Ответить  
 
 автор: Trianon   (08.05.2009 в 08:08)   письмо автору
 
   для: Qiao   (08.05.2009 в 06:39)
 

для второго запроса потребуется еще
ALTER TABLE `tagsnews` ADD UNIQUE KEY (`tag_id` , `news_id`) ;

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования