我想建立一个图片数据库。每张图片可能包含一个或多个标签,例如:Paris
,April 2010
,David
。
您如何存储此信息?
我想有一个Files
表,每个文件有1行,其中一列是标记ID,用逗号分隔,例如:2,4,14,15
在另一个名为Tags
的表中,我认为每个标记有一行,如下所示:
Tag ID Tag Name
------ --------
1 April
2 David
3 Paris
您认为管理这样的标签是个好主意吗? 例如,如何轻松获取特定图片的所有标签名称?
答案 0 :(得分:11)
你应该有3张桌子。文件,标签和文件标签。
FileTags应具有文件ID和标签ID。一行标记分配一行。
然后,您可以轻松查询具有特定标记的所有文件:
select distinct f.* from Files f
join FileTags ft on f.FileID = ft.FileID
join Tags t on ft.TagID = t.TagID
where t.TagName = 'Paris'
或任何文件的所有标签:
select distinct t.* from Files f
join FileTags ft on f.FileID = ft.FileID
join Tags t on ft.TagID = t.TagID
where f.FileID = 7
答案 1 :(得分:4)
对于大多数关系数据库设计,您所建议的内容(标记ID以逗号分隔)被认为是禁忌,因为这不是normalized。
您应该有一个包含TagId和FileId列的额外多对多表。
这意味着您可以存储单个标记(例如Paris
),并将其与许多图片相关联。对于每张图片,您将能够存储许多标签。
答案 2 :(得分:2)
在我看来,如果你用逗号分隔列中的值,你将来会非常努力地进行搜索,例如“用给定的标签获取所有图片”我确信有很多方法,但是处理此问题的一种标准方法是使用一个中间多对多映射表来存储PhotoID和TagID,该映射关联哪个标记属于哪个图片。
答案 3 :(得分:1)
我可能有一张表用于图片,一张用于标签,而不是使用多对多表将它们绑定在一起。通过这种方式,可以轻松查找图片的所有标签或标签的所有图片。
答案 4 :(得分:1)
Mysql让你可以很容易地获得所有标签,甚至是标准格式
SELECT f.FileID, group_concat(t.tag_name)
FROM Files f
JOIN FileTags ft ON f.FileID = ft.FileID
JOIN Tags t on ft.TagID = t.TagID
GROUP BY f.FileID
详见here。
如果你正在追逐最后一点表现,并准备签署你不会反对缺点,你可以考虑使用set types。
警告:这两个选项都将您锁定为特定RDBMS实现(此处为mysql)的细节,因为其他RBMS可能不会使用相同的语法甚至具有上述功能(因此在完美世界中,以上建议都不是很好)请务必阅读有关设置数据类型的limitations,例如,由于您意识到必须拥有更多64个标签,因此必须对应用程序进行大量重新设计并不是一件非常有趣的事情。
答案 5 :(得分:1)
我会有3张桌子:
然后我会创建外键:
当然,实施细节取决于您选择的RDBMS。