假设您有一个允许用户附加tag
的任意数字表。例如,Stackoverflow允许我们标记问题,但也许它也可以让我们标记答案,工作,用户配置文件等。
实施它的最佳方式是什么,以及做出此决定需要哪些信息?
tag
表 +----<tag_foo>----foo
|
tag
|
+----<tag_bar>----bar
找到所有标记为&#39; rdbms&#39;
的FoosSELECT foo.*
FROM tag JOIN tag_foo ON (tag.id = tag_foo.tag_id)
JOIN foo ON (tag_foo.foo_id = foo.id)
WHERE tag.name = 'rdbms';
在此方法中,我们制作了一个taggable
表格,每个要标记的表格的FK都返回taggable
,1:1
表格为taggable
。 tag
表的M:N
带有`taggable。
+-------foo
|
tag----<tag_taggable>----taggable
|
+-------bar
找到所有带标签的Foos =&#39; rbdms&#39;
SELECT foo.*
FROM tag JOIN tag_taggable ON (tag.id = tag_taggable.id)
JOIN taggable ON (tag_taggable.taggable_id = taggable.id)
JOIN foo ON (taggable.id = foo.id)
WHERE tag = 'rdbms';
以下是taggable
:
CREATE TABLE taggable (
id INTEGER PRIMARY KEY,
type VARCHAR NOT NULL CHECK (type IN ('foo', 'bar'))
)
答案 0 :(得分:1)
我会选择第一个选项。第二个选项将强制您使用相同的列作为所有可标记表的主键,并强制您为插入foo或bar的每个记录插入记录到可标记表。这将使插入物更加繁琐,并且对于多对多表没有实际益处。当然,它在系统中的表格较少,但每条记录的工作量更多。
当您需要存储具有不同属性的多个项目时,1:1关系非常有用,但它们共享一些共同的属性。 例如,与猫,狗,狮子和斑马有关的动物。
它在标记系统中不太有用,因为所有可标记实体必须具有的唯一共同点是它们是可标记的。