2013-03-03 2 views
-2

Я разрабатываю форум в PHP MySQL. Я хочу сделать мой форум настолько эффективным, насколько я могу.Как эффективно создавать базу данных MySQL для моего конкретного случая

Я сделал эти две таблицы

  1. tbl_threads
  2. tbl_comments

Теперь проблемы является то, что существует, как и не нравится кнопка под каждым комментарием. Я должен хранить user_name, который нажал кнопку Like или Dislike с помощью comment_id. Я создал столбец user_likes и столбец user_dislikes в tbl_comments для хранения разделенных запятыми имен пользователей. Но на этом форуме я прочитал, что это не эффективный способ. Мне было рекомендовано создать третью таблицу для хранения Likes and Dislikes и выполнить дизайн моей базы данных с помощью 1NF.

Но проблема в том, если я делаю третью таблицу tbl_user_opinion и сделать два поля как этот 1. comment_id 2. типа (например, или нелюбовь)

Таким образом, я должен буду работать так много запросов SQL так как есть комментарии на моей странице, чтобы получить понравившиеся и не понравиться данные для каждого комментария. Будет ли это неэффективно. Я думаю, что есть некоторая путаница с моей стороны здесь. Может кто-нибудь это разъяснит.

+0

Postgres может сделать иерархический запрос намного проще, чем mysql –

ответ

0

У вас есть реляционная схема, как это:

Есть два способа решить эту проблему. Первый, «чистый» - это построить свою «подобную» таблицу и сделать «count (*)» в соответствующем столбце.

Второе, чтобы сохранить в каждом комментарии счетчик, указав, сколько там было вверх и вниз. Если вы хотите проверить, если определенный пользователь проголосовал за комментарий, вам нужно только проверить одну запись, с которой вы можете легко обрабатывать собственный запрос и объединить их за пределами вашей базы данных (для этого используется запрос, в результате которого возникает комментарий и вид голосования, который пользователь сделал в определенной теме.)

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

("Одна информация - один Dataset"!)

+1

Если я следую первому подходу и создаю отдельную таблицу для хранения симпатий и антипатий. Тогда будет связь между тремя моими таблицами. Сначала я получу комментарии от tbl_comments на основе tbl_threads.thread_id = tbl_comments.thread_id, тогда мне нужно будет проверить, понравился или не понравился зарегистрированный пользователь, извлекая данные из tbl_likes. Не будет ли это сложным и трудоемким SQL-запросом. –

0

Запятая-отдельный список нарушает принцип atomicity, и, следовательно, 1nf. Вам будет трудно поддерживать ссылочную целостность и, по большей части, запросы.

Вот один из способов сделать это в нормализованной моды:

enter image description here

Это очень clustering содружественная: она группирует вверх голосов, принадлежащих одному и тому же комментарий физически близко друг к другу (Ditto для понижающего голосов), что делает весьма эффективным следующий запрос:

SELECT 
    COMMENT.COMMENT_ID, 
    <other COMMENT fields>, 
    COUNT(DISTINCT UP_VOTE.USER_ID) - COUNT(DISTINCT DOWN_VOTE.USER_ID) SCORE 
FROM COMMENT 
    LEFT JOIN UP_VOTE 
     ON COMMENT.COMMENT_ID = UP_VOTE.COMMENT_ID 
    LEFT JOIN DOWN_VOTE 
     ON COMMENT.COMMENT_ID = DOWN_VOTE.COMMENT_ID 
WHERE 
    COMMENT.COMMENT_ID = <whatever> 
GROUP BY 
    COMMENT.COMMENT_ID, 
    <other COMMENT fields>; 

[SQL Fiddle]

Просьба измерять реалистичные объемы данных, если это работает достаточно быстро для вас.Если нет, то денормализовать модель и кешировать общий балл в таблице COMMENT и поддерживать его в реальном времени через триггеры каждый раз, когда новая строка вставляется или удаляется из * _VOTE-таблиц.

Если вам также необходимо получить комментарии, на которые проголосовали определенные пользователи, вам понадобятся индексы на * _VOTE {USER_ID, COMMENT_ID}, т. Е. Обратная ссылка основного/кластеризованного ключа выше.


Это одна из причин, почему я не пошел только с одной VOTE таблицы, содержащей дополнительное поле, которое может быть либо 1 (до-голосования) или -1 (для down-vote): он менее эффективен для cover со вторичными индексами.

Смежные вопросы