如果与不同实体共享标签,如何实现标记?

时间:2010-07-19 12:19:30

标签: database tags

我知道标记内容已被多次提及,但我似乎无法看到任何解决此问题的内容。

来自这个帖子 Recommended SQL database design for tags or tagging

我可以看到设置标签的最佳方式可能是

Item (item_id, item_content)

Tag (tag_id, tag_title)

TagMapping(map_id, tag_id, item_id)

但是,如果我想在两个不同的商品实体之间共享标签呢?例如,博客文章和文章。 (我们不讨论是否应该是单独的实体:)) 你做这样的事情似乎非常错误吗?

 Post (post_id, post_content)
 Article (article_id, article_content)

 Tag (tag_id, tag_title)

 TagMapping(map_id, tag_id, post_id(nullable), article_id(nullable))

3 个答案:

答案 0 :(得分:3)

正统的答案是在Post和Article之间使用表继承策略。让它们成为两种物品。所以(这个SQL可能完全是胡说八道,但你明白了):

create table Item (integer item_id primary key)
create table Post (integer item_id primary key references Item, varchar(2000) post_content)
create table Article (integer item_id primary key references Item, varchar(2000) article_content)
create table Tag (integer tag_id primary key)
create table TagMapping (integer item_id references Item, integer tag_id references Tag, constraint primary key (item_id, tag_id))

所以文章和帖子都存在于项目表中,这就是标签所指的内容。

您可以像现在一样检索帖子和文章。如果要按标记检索它们,可以通过Item进行连接。如果要检索该连接中的详细信息,则必须对Post和Article执行外连接,然后忽略空列。

你经常在父表中有一个列,这里是Item,就像'integer subtype_discriminator not null',如果该项是帖子,则包含1,如果是文章,则包含2,等等如果你想在简单连接之后对它们进行第二次查询,那么可以更容易地知道要忽略哪些列,或者在哪里查找详细信息。

答案 1 :(得分:1)

您可以将标签附加到“标记板”实体,并将其附加到应标记的所有实体:

TagBoard (tagboard_id)

Post (post_id, tagboard_id, post_content)
Article (article_id, tagboard_id, article_content)

Tag (tag_id, tag_title)
TagMapping (map_id, tag_id, tagboard_id)

相反,您可以使用继承来使Post和Article从“Taggable”实体继承(或者,为了更灵活,来自通用“Item”实体)。 Drupal,特别是这样做(在Drupal数据库中有帖子和文章以及几乎所有其他的 nodes )。

答案 2 :(得分:0)

如果你想维护这个模式的关系映射(而不是使用基于文档的解决方案,比如MongoDB,你的标签将被非规范化),那么你可以再创建一个映射级别。

我在这种情况下使用的约定是将同类的每个项目称为'ilktype',并且每个单独的项目称为'rubric',因此ilktype博客帖子有许多规则(帖子) )。

这在架构中的外观如下:

Post(post_id,post_content)
Article(.....)
Foo(.....)
Tag(tag_id,tag_title)
TagMapping(map_id,tag_id,ilktype_id,rubric_id)

然后,您可以维护一个ilktypes列表,作为配置文件或ilktype表中的常量,然后通过将ilktype_id连接到相应的表(post / article / foo)来检索标记映射表中引用的项)。