评论系统设计

发布于 2024-11-01 22:40:38 字数 908 浏览 1 评论 0原文

这是我当前的评论系统设计:

在此处输入图像描述

我正在为一个有很多区域的网站开发它,博客,教程,手册等。正如应该为每个(tblBlogCommentstblTutorialComments)等开发一个单独的评论表,我试图采用一个结构适合所有人 方法。

这样,我可以将评论系统变成一个 Web 控件,然后将其放在我想要评论的任何页面上。这意味着我只有一套规则、一套代码文件需要维护。

唯一的问题是,想出一种“好”的方法来确定属于哪个部分(博客/教程/手册)。

例如,一种解决方案是:

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

其中“Section”映射到网站每个部分的唯一 ID,EG:

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

SectionIdentifier 是该页面的某种唯一 ID ,例如:

ViewBlog.aspx?ID=5

是对博客条目编号 5 的评论。

这将是第 1 节,标识符 5。因此,现在,带有 Section = 1SectionIdentifier = 5 的评论意味着这 作品很好,但代价是可维护性和坚固的结构,因为 SectionIdentifier 是匿名的,无法建立任何关系。

这个设计可以吗,或者有更好的解决方案(即某种用于评论的父表?)

Here is my current comment system design:

enter image description here

I'm developing it for a website that has lots of areas, blogs, tutorials, manuals etc etc. As supposed to developing a separate comment table for each (tblBlogComments, tblTutorialComments) etc etc, I'm trying to go for a one structure fits all approach.

This way, I can turn the comment system into a web control, and just drop it on any page that I want comments for. It means I only have one set of rules, one set of code files to maintain.

The only problem is, is coming up with a 'nice' way to determine which section (blog/tutorial/manual) belongs to.

For example, one solution would be:

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

Where 'Section' maps to a unique to each part of the site, EG:

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

A SectionIdentifier is some sort of unique ID for that page, eg:

ViewBlog.aspx?ID=5

This would be section 1, identifier 5. So now, a comment with Section = 1, SectionIdentifier = 5 means it's a comment for blog entry number 5.

This works great, but at the cost of maintainability, and a solid structure, as the SectionIdentifier is anonymous and no relationships can be built.

Is this design OK, or is there a better solution (IE some sort of parent table for a comment?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只有影子陪我不离不弃 2024-11-08 22:40:39

在 Codd 最初设计的关系模型中,外键可以引用不同表中的多个主键,并且如果任何一个表包含该值,则引用完整性有效。

不幸的是,正如您所指出的,SQL 是最初愿景的苍白反映,因为它不提供这种能力。

一个标准的解决方法是创建一种新的关系,该关系掌握着所有其他关系的关键。但在这种情况下,这不是一个很好的解决方案,因为如果同时发生大量插入,就会产生争论点。

我处理这个问题的方法是创建一个值(我们称之为注释锚),您可以将其放入每个有注释的表中。该值(与精心设计的数据库中的所有其他键不同)应该是 GUID。然后每个评论都可以有一个 Comment-Anchor 来指示它所引用的值。

通过使其成为 GUID,您始终可以在博客或教程等中插入唯一值,而不会发生争用。您不必在任何地方维护评论锚点的主列表,并且没有任何部分与任何其他部分竞争或被任何其他部分阻止。

例如,这对于查找单个博客条目的所有评论的正常用例非常有效。换句话说,从评论到正在评论的事物,您可以在评论表中放置一个标志来标识正在引用哪个表,但我不会这样做。我会搜索所有的表,也许有一个视图或其他东西。反向查询非常罕见,我认为维护它的基础设施没有太多意义,而且标志将是冗余数据,这是 RDBMS 的祸根。

该系统的另一个好处是它易于扩展。如果您创建新类型的数据,或决定向现有数据类型添加注释,则只需将 Comment-Anchor 列添加到表中。数据库端不需要做任何额外的工作。即使处理注释的中间件部分也不需要以任何方式进行修改,因为它不知道什么样的事物需要注释。

In Codd's original designed for the Relational Model, a foreign key could reference multiple primary keys in different tables, and the referential integrity was valid if any one table contained the value.

Unfortunately, SQL is a pale reflection of that original vision, since it does not provide this ability, as you have noted.

One standard work-around is to create a new relation that holds the keys to all of the others. But that's not a very good solution in this case, since it creates a point of contention if lots of inserts are happening at once.

The way I would handle this is to create a value—let’s call it a Comment-Anchor—that you can put into every table that is to have comments. This value (unlike all the other keys in a well-designed database) should be a GUID. Then each comment can have a Comment-Anchor that indicates which value it is in reference to.

By making it a GUID, you can always insert unique values in your blog or tutorial or whatever, without contention. You do not have to maintain a master-list of Comment-Anchors anywhere, and no section contends with or is blocked by any other section.

This will work well for the normal use-case of finding all the comments for a single blog entry, for example. To go the other way, from comment to the thing that is being commented on, you could put a flag in the comment table identifying which table is being refrenced, but I wouldn't do that. I would just search all the tables, maybe with a view or something. The reverse query would be rare enough, that I don't see much point in maintaining infrastructure for it, and the flag would be redundant data, which is the bane of RDBMSs.

One additional benifit of this system is that it is easily extensible. If you create a new type of data, or decide to add comments to an existing type of data, then you need only add the Comment-Anchor column to the table. No additional work must be done on the database side. And even the middleware portion that handles the comments does not need to be modified in any way, since it has no knowledge of what sorts of things take comments.

迷乱花海 2024-11-08 22:40:39

对于表设计,我会尽可能接近本例中的类结构。根据您所说的,这就是它的样子(大致):

Section <- Post <- Comment

因此,您将拥有:

  1. 一个部分表(例如博客、文章、教程)等)
  2. 一个帖子表(用于每个部分中的各个帖子)
  3. 一个评论表(用于每个帖子的评论)

每个帖子都会有对其所在部分的引用,并且每个评论都会有对其帖子的引用。数据库可以将引用作为良好、干净的外键,并且类可以根据应用程序的需要在关系的一侧或两侧都有列表。

对我来说,这似乎是一个很好、简单、灵活的结构,它不会使事情变得复杂,并且仍然允许您挂起额外的内容,例如编辑和投票。

For a table design, I would model it as closely as possible to what the class structure seems to be in this case. From what you have said, this is what it looks like (roughly):

Section <- Post <- Comment

So, you'd have:

  1. a Section table (eg. blog, articles, tutorials, etc.)
  2. a Post table (for the individual posts in each section)
  3. a Comment table (for the comments on each post)

Each post would have a reference to it's section, and each comment would have a reference to it's post. The DB could have the references as nice, clean foreign keys, and the classes could have lists on one or both sides of the relationships as your app needs them.

To me, that seems like a nice, simple, flexible structure that doesn't complicate things and still allows you to hang extra bits like edits and votes off of it.

鸩远一方 2024-11-08 22:40:39

我会避免创建一个 id 列,该列根据同一个表中的另一列定义不同的关系。例如,在您的示例中,SectionIdentifier 可以表示任意数量的外键引用,具体取决于 Section 的值。这让我从一般原则上被排除在外。它还保留了现代 RDBMS 平台的一些优点,因为它不受支持。

这些不同部分的总体架构是如何布局的?我使用过一些 CMS,它们要求每个部分共享一个公共基本实体,将其称为“模块”或“插件”。给定模块的每个实例都有自己的 id,用于映射到该特定实例所需的任何内容。

如果这对您来说是可行的架构方向,您还可以使用该 ModuleInstanceID 作为评论的外键。您只需决定如何将给定类型的模块/插件注册为有效的注释目标。

不管怎样,你能透露一下你的各个部分是如何在引擎盖下组合在一起的吗?

I would steer clear of creating an id column that defines a different relationship depending on another column in the same table. For instance, in your example SectionIdentifier could represent any number of foreign key references depending on the value of Section. That skeeves me out on general principle. It also leaves several benefits of modern RDBMS platforms on the table since it's not supported.

How is your general architecture for these different sections layed out? I've worked with a few CMS's that would require each of your sections to share a common base entity, calling it a "module" or "plug in". Each instance of a given module then has it's own id, which is used to map to any content required by that specific instance.

If this is a viable architecture direction for you, you could also use that ModuleInstanceID as the foreign key for your comments. You'd just have to decide how you register a given type of module/plug in as being a valid target for comments.

Anyway, can you shed a little light on how your sections are put together under the hood?

顾北清歌寒 2024-11-08 22:40:39

看来是这样。您的评论系统由多种评论组成(tblBlogComments、tblTutorialComments...等)。我建议你采用策略设计模式。

这么说吧。您有一个 IComment 界面。所有类型的评论类都实现了 IComment 接口。

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

class BlogComment : IComment
{
    ....
}

class TutorialComment : IComment
{
    ....
}

和一个只知道如何处理 IComment 的 WebControl

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);
    ........
}

这样您的 Web 控件就可以以相同的方式处理所有类型的评论。不管具体是什么样的评论。您也可以只维护CommentCreater来正确构建各种评论类。

It seems that. Your comment system consists of many kind of comment (tblBlogComments, tblTutorialComments..... etc). I would like to suggest you to adopt strategy design pattern.

Let's say. You have a IComment interface. And All kind of comment class implements IComment interface.

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

class BlogComment : IComment
{
    ....
}

class TutorialComment : IComment
{
    ....
}

And a WebControl which only knows how to deal with IComment

class WebControl
{
    IComment _comment = null;

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

Of course you need a CommentCreater to loads comment data from database and builds the comment object.

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);
    ........
}

That way your web control can just treats all kind of comment in the same way. No matter exactly what kind of comment it is. and you can also just maintain the CommentCreater to build each kind of comment class correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文