Не считайте определенные столбцы в «LIMIT»

0

У меня есть система, где могут быть "сообщения", "комментарии" к сообщениям и "комментарии" к другим комментариям. Подумайте об этом как о очень упрощенной системе комментариев в facebook.

Чтобы вернуть данные, я решил использовать одну таблицу для сообщений и комментариев, так как их структура почти такая же:

ID (комментария или сообщения) | TopParentID (если сообщение, то же, что и ID, если комментарий, идентификатор сообщения) | DirectParentID (0, если сообщение, либо идентификатор сообщения, либо идентификатор родительского комментария, если комментарий) | Еще несколько полей, которые одинаковы для сообщений и комментариев

Что я хотел бы достичь: выберите, например, первые 20 сообщений. Тем не менее, с сообщениями, также выберите комментарии этого сообщения.

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

Тем не менее, я не знаю, как спроектировать мой запрос с приведенным выше дизайном таблицы; Мне нужно было бы выбрать первые x строк, где DirectParentID = 0, но также и строки, где TopParentID = идентификатор сообщения для каждой выбранной строки.

Должен ли я просто изменить свой дизайн стола в конце концов?

  • 0
    См. Meta.stackoverflow.com/questions/333952/…
  • 0
    @ Клубника Ах, прости. Спасибо за ссылку. Я обновлю его, как только смогу.
Теги:
database-design
relational-database

2 ответа

0

Я рекомендую вам иметь одну таблицу для "Тема" плюс одну таблицу для "Комментарии". Вероятно, "Посты" можно просто выбросить с помощью комментариев, но не пытайтесь также вставлять Thread.

Если вам нужна иерархия (Комментарии к комментариям), Post следует отличать от комментариев просто с помощью directParentId = 0.

Если вам не нужна иерархия, тогда все, что вам нужно, это thread_id на всех сообщениях/комментариях, а также простой флаг, чтобы сказать, что является исходным сообщением.

0

Вы могли бы сделать что-то вроде этого:

SELECT *
FROM   t
WHERE  topParentId IN (SELECT id
                       FROM   t
                       WHERE  directParentId = 0
                              AND id <= 20); 

LIMIT не может использоваться в подзапросах, поэтому вам понадобится предложение where, чтобы отфильтровать ваши родительские сообщения (возможно, по дате или пользователю или что-то еще).

Если вы хотите использовать лимит, вы можете использовать "self-join", например:

SELECT t.*
FROM   (SELECT *
        FROM   t
        WHERE  t.did = 0
        LIMIT  20) AS t1
       INNER JOIN t
               ON t.tid = t1.id; 

В вашем дизайне нет ничего плохого. Обычные таблицы ссылок являются общими. Вы можете рассмотреть, что ваша таблица содержит "объекты с комментариями", и оба комментария и сообщения могут быть разделены на них. Но запросы, которые обрабатывают сообщения и комментарии как два отдельных объекта, могут быть сложнее/сложнее создать для таблицы, рассматривающей их как единую сущность (по крайней мере, это для меня :))

  • 0
    Это похоже на LIMIT в подзапросе. Кстати, обратите внимание, что LIMIT без ORDER BY довольно бессмысленно
  • 0
    Да, это забавно, я получаю эту ошибку, если я использовал первую команду с лимитом: эта версия MySQL еще не поддерживает подзапрос «LIMIT & IN / ALL / ANY / SOME». Но со вторым все работает хорошо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню