我有人在我的网站上上传艺术品。他们输入标题,标签和文件。
一旦上传,我就会标记标题,用逗号分隔的标签和转换后的图像文件的文件路径。
我现在想通过标签找到最接近的相关艺术品。所以为了找到最接近的匹配,我必须爆炸标签并搜索每个标签?它似乎在服务器上做了很多工作。我想知道有人能告诉我存储标签和数据的正确方法是什么以及我必须进行哪些搜索?
我是否必须拥有一个包含标题的表,文件路径和另一个表来保存艺术品的ID和其中一个标签的列。如果我有“铅笔,动物,野生动物”这意味着我在标签表中有三行具有相同的艺术ID?
答案 0 :(得分:1)
只需按照它们的含义和含义来分离您的数据实体。对于title
,tags
和file
,听起来您有两个实体:
Picture
----------
ID
Title
File
Tag
----------
ID
Name
也就是说,title
和file
(在你的情况下,我猜你将它存储为文件系统上文件的路径,这很好)是一个实体,并且tag
是它自己独立的实体。由于每个Picture
可以包含多个tag
,并且每个tag
可以与多个Picture
相关联,因此它是多对多关系。因此,通常会创建一个支持的非实体表来将它们链接到数据库中:
PictureTagRelationship
----------
PictureID
TagID
有了这个,您可以获得Picture
:
SELECT Picture.Title, Picture.File FROM Picture WHERE Picture.ID = ?id
及其标签:
SELECT Tag.ID, Tag.Name FROM Tag
INNER JOIN PictureTagRelationship ON Tag.ID = PictureTagRelationship.TagID
WHERE PictureTagRelationship.PictureID = ?id
(您也可以通过几种方式在单个查询中执行此操作,为简单起见,我将其拆分为两个。两个查询不应该是一个大问题,但如果您需要高度优化数据库访问开销或者如果你真的希望它是一个单一的查询,那么我确信可以做一些事情。)
或者您可以获取特定标签的所有照片:
SELECT Picture.ID, Picture.Title, Picture.File FROM Picture
INNER JOIN PictureTagRelationship ON Picture.ID = PictureTagRelationship.PictureID
WHERE PictureTagRelationship.TagID = ?id
可以对此设计进行其他调整,还有许多其他方法可以查看和报告数据。但所有这一切都是关键点:
不要使用逗号分隔的列表来存储数据。将每个数据实体规范化为自己的结构并相应地存储它。关系数据库非常适合这类事情。但是,只要将单独的数据元素存储为分隔字符串,就会丢失这些元素的分离。这使得报告数据变得更加困难,更难以与之交互,更难以更新批次,并且对于需要支持它的任何其他人来说都不那么直观。
请记住,数据库中的任何一个字段都应该存储一条信息而仅一条信息。如果您必须将多条信息填充到一个字段中,那么您就不会正确使用关系数据库。