Дизайн системы комментирования - PullRequest
1 голос
/ 15 апреля 2011

Вот мой текущий дизайн системы комментариев:

enter image description here

Я разрабатываю его для веб-сайта, на котором есть много областей, блогов, учебных пособий и т. Д. Как и предполагалосьдля разработки отдельной таблицы комментариев для каждого (tblBlogComments, tblTutorialComments) и т. д., и т. д., я пытаюсь использовать единую структуру, подходящую для всех.

Таким образом, я могу превратить систему комментариев ввеб-элемент управления, и просто перетащите его на любую страницу, для которой я хочу комментарии.Это означает, что у меня есть только один набор правил, один набор файлов кода для обслуживания.

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

Например, одним из решений будет:

tblComment
-------------
Section (int)
SectionIdentifier (int)

, где 'Section' соответствует уникальному для каждой части сайта, например:

Blog = 1
Articles = 2
Tutorials = 3
...

A SectionIdentifier - это своего рода уникальный идентификатор для этой страницы, например:

ViewBlog.aspx?ID=5

Это будет раздел 1, идентификатор 5. Итак, теперь комментарий с Section = 1, SectionIdentifier = 5означает, что это комментарий к записи в блоге № 5.

Это прекрасно работает, но за счет ремонтопригодности и прочной структуры, так как SectionIdentifier является анонимным и никакие отношения не могут быть построены.

Этот дизайн в порядке, или есть лучшее решение (например, какая-то родительская таблица для комментария?)

Ответы [ 5 ]

3 голосов
/ 15 апреля 2011

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

К сожалению, SQL является бледнымотражение этого первоначального видения, поскольку, как вы уже отметили, оно не предоставляет этой способности.

Один из стандартных способов обхода проблемы - создать новое отношение, которое содержит ключи ко всем остальным.Но это не очень хорошее решение в этом случае, так как оно создает точку разногласия, если много вставок происходит одновременно.

Я бы справился с этим, чтобы создать значение - давайте назовем его КомментарийЯкорь - который вы можете поместить в каждую таблицу, в которой должны быть комментарии.Это значение (в отличие от всех других ключей в хорошо спроектированной базе данных) должно быть GUID.Тогда у каждого комментария может быть привязка к комментарию, указывающая, на какое значение он ссылается.

Делая его GUID, вы всегда можете вставлять уникальные значения в свой блог или учебник или что-то подобное, без спора.Вам не нужно вести основной список привязок комментариев, и ни один раздел не конкурирует с другим разделом или не блокируется им.

Это будет хорошо работать для обычного сценария поиска всех комментариев.например, для отдельной записи в блоге.Чтобы пойти другим путем, от комментария к тому, что комментируется, вы можете поставить флаг в таблице комментариев, указывающий, к какой таблице делается ссылка, но я бы не стал этого делать.Я бы просто обыскал все таблицы, может быть, с видом или что-то.Обратный запрос был бы достаточно редким, так что я не вижу особого смысла в поддержании инфраструктуры для него, и этот флаг был бы избыточными данными, что является проклятием СУБД.

Еще одно преимущество этой системы -что это легко растяжимо.Если вы создаете новый тип данных или решаете добавить комментарии к существующему типу данных, вам нужно всего лишь добавить столбец Comment-Anchor в таблицу.Никакой дополнительной работы не должно быть сделано на стороне базы данных.И даже часть промежуточного программного обеспечения, которая обрабатывает комментарии, не нуждается в модификации каким-либо образом, поскольку она не знает, какие вещи принимают комментарии.

2 голосов
/ 15 апреля 2011

Для дизайна таблицы я бы смоделировал ее как можно ближе к тому, какой будет структура класса в этом случае. Из того, что вы сказали, это выглядит примерно так:

Section <- Post <- Comment

Итак, у вас будет:

  1. Таблица разделов (например, блог, статьи, учебные пособия и т. Д.)
  2. Таблица сообщений (для отдельных сообщений в каждом разделе)
  3. Таблица комментариев (для комментариев к каждому сообщению)

Каждый пост будет содержать ссылку на свой раздел, а каждый комментарий будет содержать ссылку на свой пост. БД может иметь ссылки в виде симпатичных чистых внешних ключей, а классы могут иметь списки на одной или обеих сторонах отношений, так как они нужны вашему приложению.

Мне это кажется хорошей, простой, гибкой структурой, которая не усложняет вещи и все же позволяет вам вывешивать лишние биты, такие как правки и голоса за них.

1 голос
/ 15 апреля 2011

Я хотел бы избежать создания столбца id, который определяет различные отношения в зависимости от другого столбца в той же таблице. Например, в вашем примере SectionIdentifier может представлять любое количество ссылок на внешние ключи в зависимости от значения Section. Это сводит меня с ума по общему принципу. Он также оставляет на столе несколько преимуществ современных платформ СУБД, поскольку он не поддерживается.

Какова ваша общая архитектура для этих различных разделов? Я работал с несколькими CMS, которые требуют, чтобы каждый из ваших разделов разделял общую базовую сущность, называя ее «модулем» или «подключаемым модулем». Каждый экземпляр данного модуля имеет свой собственный идентификатор, который используется для сопоставления с любым содержимым, требуемым этим конкретным экземпляром.

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

В любом случае, можете ли вы пролить немного света на то, как ваши секции соединены под капотом?

0 голосов
/ 17 апреля 2011

Посмотрите на принятый ответ для на этот вопрос .Прочитайте все комментарии тоже.

0 голосов
/ 15 апреля 2011

Кажется, что. Ваша система комментариев состоит из множества комментариев (tblBlogComments, tblTutorialComments ..... и т. Д.). Я хотел бы предложить вам принять шаблон проектирования стратегии.

Скажем так. У вас есть интерфейс IComment. И все виды классов комментариев реализуют интерфейс IComment.

interface IComment
{
    int ID {get; set; }
    int Section  {get; set; }
    ....
}

class BlogComment : IComment
{
    ....
}

class TutorialComment : IComment
{
    ....
}

И WebControl, который знает только, как обращаться с IComment

class WebControl
{
    IComment _comment = null;

    public WebControl(IComment comment)
    {
        _comment = comment;
    }
}

Конечно, вам нужен CommentCreater для загрузки данных комментариев из базы данных и построения объекта комментария.

public static void main()
{
    var creater = new CommentCreater();
    IComment comment1 = creater.CreateBlogComment()
    WebControl webcontrol = new WebControl(comment1);
    ......

    IComment comment2 = creater.CreateTutorialComment()
    webcontrol = new WebControl(comment2);
    ........
}

Таким образом, ваш веб-элемент управления может обрабатывать все виды комментариев одинаково. Неважно, что это за комментарий. и вы также можете просто поддерживать CommentCreater для правильного построения каждого вида класса комментариев.

...