Привет. Хочу реализовать поиск на сайте с помощью тегов(в будущем будет ajax, но я думаю, сейчас это не важно). У одной статьи может быть от одного до пятнадцати тегов. Вот как я думаю: Таблица tags: alias - имя для ссылки в html(href). name - имя для html id - id категории... Таблица articles: id - id статьи title - title fullText- ну тут понятно . Так вот.. Может создать в таблице articles поле типа text. И при создании статьи загружать через запятую категорию. Нормально? Удобно ли потом будет делать поиск по тегам(ajax) или есть вариант получше?
Ага. Прочитал. Спасибо. Просто интересно, это нормально? Или типа самый легкий путь? --- Добавлено --- В новой таблице articlesTags где будет id article и id tags больше, как я понял, ни каких полей не нужно?
правильно.. одна таблица с сообщениями одна таблица с тегами одна таблица связывающая в таблице с тегами два поля по сути, автоинкрементный tag_id и уникальный tag_name в связывающей таблице тоже два поля.. post_id и tag_id теоретически можно их связать внешними ключами с родительскими таблицами..
Создал как и сказали, добавил индексы к новым таблицам. Работаю в phpmyadmin. Но как только пытаюсь что-то связать - ошибка #1215. Куда нужно добавить первичный ключ?
в промежуточной таблице два поля post_id tag_id назначаете post_id внешний ключ из таблицы post столбец id тоже самое делаете для тега только естественно для таблица tags в phpMyAdmin есть кнопка СТРУКТУРА/СВЯЗИ - там наглядно все показано..
вот пример PHP: -- phpMyAdmin SQL Dump -- version 4.6.5.2 -- https://www.phpmyadmin.net/ -- -- Хост: 127.0.0.1:3306 -- Время создания: Июл 18 2017 г., 00:37 -- Версия сервера: 5.6.34 -- Версия PHP: 7.1.0 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- -- База данных: `test1` -- -- -------------------------------------------------------- -- -- Структура таблицы `link_post_tag` -- CREATE TABLE `link_post_tag` ( `post_id` int(10) NOT NULL, `tag_id` int(10) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Дамп данных таблицы `link_post_tag` -- INSERT INTO `link_post_tag` (`post_id`, `tag_id`) VALUES (2, 1), (2, 2); -- -------------------------------------------------------- -- -- Структура таблицы `posts` -- CREATE TABLE `posts` ( `post_id` int(10) NOT NULL, `subj` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `body` text COLLATE utf8mb4_unicode_ci NOT NULL, `author_id` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Дамп данных таблицы `posts` -- INSERT INTO `posts` (`post_id`, `subj`, `body`, `author_id`) VALUES (2, 'сабж1', 'тест1', 1); -- -------------------------------------------------------- -- -- Структура таблицы `tags` -- CREATE TABLE `tags` ( `tag_id` int(10) NOT NULL, `tag_name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -- Дамп данных таблицы `tags` -- INSERT INTO `tags` (`tag_id`, `tag_name`) VALUES (1, 'тег1'), (2, 'тег2'); -- -- Индексы сохранённых таблиц -- -- -- Индексы таблицы `link_post_tag` -- ALTER TABLE `link_post_tag` ADD KEY `post_id` (`post_id`), ADD KEY `tag_id` (`tag_id`); -- -- Индексы таблицы `posts` -- ALTER TABLE `posts` ADD PRIMARY KEY (`post_id`); -- -- Индексы таблицы `tags` -- ALTER TABLE `tags` ADD PRIMARY KEY (`tag_id`), ADD UNIQUE KEY `tag_name` (`tag_name`); -- -- AUTO_INCREMENT для сохранённых таблиц -- -- -- AUTO_INCREMENT для таблицы `posts` -- ALTER TABLE `posts` MODIFY `post_id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; -- -- AUTO_INCREMENT для таблицы `tags` -- ALTER TABLE `tags` MODIFY `tag_id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; -- -- Ограничения внешнего ключа сохраненных таблиц -- -- -- Ограничения внешнего ключа таблицы `link_post_tag` -- ALTER TABLE `link_post_tag` ADD CONSTRAINT `post_id` FOREIGN KEY (`post_id`) REFERENCES `posts` (`post_id`) ON DELETE CASCADE ON UPDATE CASCADE, ADD CONSTRAINT `tag_id` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`tag_id`) ON DELETE CASCADE ON UPDATE CASCADE;
ну сделай у обоих ансигнед. Это просто числа с минусом могут быть или нет. Для индексов обычно все больше нуля идут, т.е. unsigned.
А в php вытаскивать как? PHP: ("SELECT * FROM `articlesTags`"); А дальше, как связать все эти таблицы в php?
в промежуточную таблицу делаете запрос и выбираете все теги которые закреплены за нужной страницей. а таблицу тегов в этом вопросе связываете с помощью JOIN..
Ну.. Вы наверное пошлёте меня в google(там я уже был), но можно по подробнее? Пусть пример будет на русском, всё равно.
PHP: SELECT * FROM link AS l LEFT JOIN tags AS t ON(l.tag_id = t.tag_id) WHERE l.post_id = 5 получите все теги для поста с id = 5
Спасибо. Работает. Вот у меня теперь четыре функции: чтобы получить статьи и функцию вывода их в массив и для статьей с тегами тоже самое. Но что бы получить теги к каждой отдельной статье, а не в функции задавать её id, нужно объединить их? Или отправлять параметр из главной страницы в последнюю функцию и заносить его в WHERE l.post_id =5, вместо 5-ти параметр?
1. Вы берете из базы статью - получаете ее ID 2. Делаете запрос в промежуточную таблицу выбираете все строки у которых post_id равен id вашей статьи. вместе с этим потягиваете связи из таблицы тегов (JOIN)..
index.php - PHP: $articles= getTagByPostId(getArticles()); function.php(беру ID) - PHP: function getArticles(){ connectPDO(); global $pdo; $articlesResult = $pdo->query("SELECT `id` FROM `article` ORDER BY `id`"); return resultToArrayArticle($articlesResult ); } function resultToArrayArticle($articlesResult ){ $array = array(); while ($row = $articlesResult ->fetch( PDO::FETCH_ASSOC )){ $array[] = $row; } return $array; } запрос к промежуточной таблице - PHP: function getTagByPostId($articlesResult){ connectPDO(); global $pdo; $TagByPostId = $pdo->query("SELECT * FROM `articleTags` AS l LEFT JOIN `tags` AS t ON(l.tagID = t.id) WHERE l.articleID = $articlesResult"); return resultToArrayArticle($TagByPostId); } function resultToArrayTagByPostId($TagByPostId){ $array = array(); while ($row = $TagByPostId->fetch( PDO::FETCH_ASSOC )){ $array[] = $row; } return $array; } Правильно начал?
Код (Text): $TagByPostId = $pdo->query("SELECT * FROM `articleTags` AS l LEFT JOIN `tags` AS t ON(l.tagID = t.id) WHERE l.articleID = $articlesResult"); тут Вы в ID отправляете массив.. мускул Вас не поймет..
Нужно что-то типа такого - PHP: foreach ($articlesResultas $key => $value) { $TagByPostId = $pdo->query("SELECT * FROM `articleTags` AS l LEFT JOIN `tags` AS t ON(l.tagID = t.id) WHERE l.articleID = $key"); } ?
если Вам надо сразу для большого количество статей - то лучше не через цикл базу дергать, а через IN взять нужные записи а потом раскидать их куда надо.. или можно через функцию мускула group_concat