|
|
|
| Привет, ребята.
Делаю систему тэгов для новостей.
У каждой новости есть поле tags, в которой через запятую перечислены id тэгов. Например: 3,7,12
Когда щёлкаешь по имени тэга (которое формируется через id), должен появиться список новостей, у которых есть этот тэг.
Вот тут я и споткнулся - есть id тэга, требуется выбрать новости, у которых в поле tags оно встречается. Пользоваться поиском нельзя: тэг 12 станет тэгом 1 и 2.
Подскажите, пожалуйста, как лучше решить эту проблему. | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 11:00)
| | лучше хранить 3 7 и 12 не в одной ячейке, а на отдельных строках. | |
|
|
|
|
|
|
|
для: Trianon
(07.05.2009 в 11:14)
| | А сколько тогда строк делать? Ведь неизвестно сколько у одной новости тэгов.
Да, обычно 1-2-3, но ведь может иногда попадаться и по 5-10. Получается будет много пустых, да и ограничения.
Пока что лучшее что нашёл - выкручиваться регулярными выражениями - WHERE tags REGEXP '[^\d]$id[^\d]'.
Но не знаю насколько это оптимально - говорят, регулярки базу грузят. | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 11:49)
| | Почему строки и удобны, если они пустые - их можно не создавать, а создавать только те записи, которые заполнены. Со столбцами такой номер уже не проходит.
Просто не жадничайте на таблицы - выделите под это дело отдельную таблицу и дело с концом. | |
|
|
|
|
|
|
|
для: cheops
(07.05.2009 в 11:57)
| | Я не понимаю.
Например, есть таблица новостей:
id | body | tags
Вы предлагаете
id | body | tag1 | tag2 | tag3 | tag4 | tag5 ...
?
И как выделить таблицу? У меня есть таблица тэгов, но там просто
id | name
Поясните, пожалуйста, про новую таблицу. | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 12:08)
| | предлагалось хранить номера тегов не в разных ячейках одной строки, а в одном столбце, на разных строках отдельной - третьей таблицы. | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 12:08)
| | Я предлагаю в первую таблицу новостей сделать такой
id | body
Вторую таблицу тэгов
id | name
оставить без изменений, и ввести третью таблицу, связывающую первые две
id | id_news | id_tag
PS Т.е. выполнить классическую нормализацию. | |
|
|
|
|
|
|
|
для: cheops
(07.05.2009 в 12:17)
| | Спасибо всем, дошло.
Попробую так.
Просто раньше никогда не создавал таблицы, в которых id не было бы чем-то реальным.
Хотя в теории когда-то что-то подобное читал ) | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 12:23)
| | А Вы можете этот столбик id не создавать вообще.
А перичный ключ составным сделать (по двум живым полям) | |
|
|
|
|
|
|
|
для: cheops
(07.05.2009 в 12:17)
| | Хотя я вот вашу же цитату в соседней теме прочёл:
> Существует только два фундаментальных способа оптимизации обслуживающего кода и баз данных: чтобы было удобно программистам (скорость разработки) и машине (скорость вычисления). Начинают с первого способа, если не хватает мощности, переходят ко второму.
Если так судить, то мне легче с регулярными работать, да и база в близжашем будущем будет маленькой.
Однако в вашей цитате не учтена стоимость "перехода". Ведь если я захочу перейти к третьей таблици ради оптимизации, то придётся попотеть, тобы создать таблицу из строчки и преобразовать обслуживающий код.
Поэтому меня сейчас терзают сомнения как лучше начать - регулярками или нормализацией. | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 12:34)
| | "Сижу с шурупом и молотком у стены и думаю, как лучше начать - то ли шуруп молотком забить (быстро), то ли за отверткой сходить (медленно, но держаться лучше будет)."
Пля. | |
|
|
|
|
|
|
|
для: Trianon
(07.05.2009 в 12:48)
| | Просто уже молоточек зашлифовал - REGEXP '.*\[^\\d\]?$tagID\[^\\d\]?.*'
Красота )
Но вы убедили - буду таблицу делать.
Даже не столько ради производительности, столько для того, чтобы попробовать теорию на практике. А там, глядишь, привыкну.
А что, кстати, оптимальней (по производительности) - делать id или составной ключ? | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 13:04)
| | зависит от характера и частоты запросов... | |
|
|
|
|
|
|
|
для: Trianon
(07.05.2009 в 14:02)
| | Запросов тут может быть только два:
SELECT id_news WHERE id_tag=$id
SELECT id_tag WHERE id_news=$id | |
|
|
|
|
|
|
|
для: Qiao
(07.05.2009 в 14:25)
| | Здрасти. А добавлять строки в таблицу святым духом будете? | |
|
|
|
|
|
|
|
для: 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
В принципе, можно сделать два составных индекса (один из которых назначить первичным ключом) | |
|
|
|
|
|
|
|
для: Trianon
(08.05.2009 в 01:41)
| | Я сделал
ALTER TABLE `newstags` ADD PRIMARY KEY ( `news_id` , `tag_id` ) ;
Ссылка интересная по теме:
http://www.c2.com/cgi/wiki?FearOfAddingTables | |
|
|
|
|
|
|
|
для: Qiao
(08.05.2009 в 06:39)
| | для второго запроса потребуется еще
ALTER TABLE `tagsnews` ADD UNIQUE KEY (`tag_id` , `news_id`) ; | |
|
|
|