MySQL дизайн, запрос, дублированные строки - PullRequest
1 голос
/ 17 сентября 2009

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

Posts
-id
-title

Categories
-id
-name

CategoryBindings
-id
-postId
-categoryId

Допустим, у меня есть эти данные:

Posts
1 Title1
2 Title2

Categories
1 category1
2 category2

CategoryBindings
1 1 1
2 1 2
3 2 1

Запрос, который я использую сейчас для получения своих сообщений с категориями:

SELECT `p`.*, `cb`.`categoryId`, `c`.`name` AS `categoryName` 
FROM `Posts` AS `p` 
LEFT JOIN `CategoryBindings` AS `cb` ON p.id = cb.postId 
LEFT JOIN `Categories` AS `c` ON cb.categoryId = c.id

Что дает следующий результат:

1 Title1 1 category1
1 Title1 2 cateogry2
2 Title2 1 cateogry1

Я получаю дубликат поста 1, так как это две категории привязки к нему. Я написал код, который с помощью php исправляет результат, так что я получаю.

1 Title1 array(1 category1, 2 category2)
2 Title2 array(1 category1)

и он работал нормально, пока не вспомнил, что мне нужно использовать ограничение с в моих запросах. Я хочу показать 10 сообщений на странице, но не могу использовать ограничения, так как мой запрос возвращает дублированные строки. Это способ изменить мой запрос, чтобы он работал так, как я хочу, или мне нужно изменить дизайн моих таблиц? Если да, то как бы вы посоветовали мне переделать мои столы?

1 Ответ

1 голос
/ 17 сентября 2009

Вы можете использовать GROUP_CONCAT И CONCAT_WS:

SELECT `p`.`id`, `p.title`, GROUP_CONCAT(CONCAT_WS(' ', `cb`.`categoryId`, `c`.`name`)) AS `categoryNames` 
FROM `Posts` AS `p` 
LEFT JOIN `CategoryBindings` AS `cb` ON p.id = cb.postId 
LEFT JOIN `Categories` AS `c` ON cb.categoryId = c.id
GROUP BY id, title

Кстати: вы не должны SELECT * в коде, лучше написать то, что вы хотите явно. Это позволяет избежать ненужных накладных расходов, если вы добавляете столбец, который не используется в коде, и завершится неудачно, если вы удалите / переименуете столбец.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...