我知道标记内容已被多次提及,但我似乎无法看到任何解决此问题的内容。
来自这个帖子 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))
答案 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)来检索标记映射表中引用的项)。