存储SQL字符串数组,以及后续查询

时间:2012-04-23 02:03:13

标签: mysql sql database database-design foreign-keys

我想在SQL数据库中存储可变大小的图像标签列表,然后能够根据标签在数据库中搜索图像。我目前正在从数据库中提取标记列表,并检查查询标记是否包含在数组中。有没有什么方法可以将这些格式化为sql查询而不是在我拉出标签后在php中执行它们?

列表存储为以逗号分隔的格式:

“晴天,海滩,棕榈树”-im1

“手掌,下雨,云”-im2

“冬天,下雪,雪人,赃物”-img

我希望能够获得查询标记的联合: 查询“beach,palms”应该返回im1和im2

谢谢

2 个答案:

答案 0 :(得分:12)

您希望避免数据库中的分隔列表 - 正如您所发现的那样,否定了使用数据库存储结构化数据的优势。相反,您应该创建一个每行一个标记的新表,然后使用主图像表中的外键引用该表。

图片

  • ID
  • IMAGE_NAME

代码

  • ID
  • TAG_NAME

Image_Tags

  • image_id(引用图像表主键)
  • tag_id(引用标签表主键)

这样,您就可以运行如下查询:

SELECT t.tag_name, i.image_name FROM image_tags it
    INNER JOIN images i on it.image_id = i.id
    INNER JOIN tags t on it.tag_id = t.id
WHERE t.tag_name in ('beach', 'palms')

答案 1 :(得分:4)

@dbaseman提供了good answer(+1),但可能有点过分。假设您想要了解的唯一标签就是它的名称,只有2个表的模型在实践中可能表现得更好(少一个JOIN和更好的clustering数据):

图片表:

  • id PK
  • IMAGE_NAME

image_tag表:

  • tag_name PK
  • image_id PK,FK - >图像

image_tag的PK中的字段顺序非常重要:如果将其保留为{tag_name, image_id},它将很好地对数据进行聚类(即将具有相同标签的图像保存在一起),完全按照您的需要进行查询:

SELECT DISTINCT image.*
FROM image JOIN image_tag ON (image.id = image_tag.image_id)
WHERE image_tag.tag_name IN ('beach', 'palms') 

另一方面,如果你还需要一个标签描述,标签作者等...,@ dbaseman的模型很好,除了你可以考虑翻转Image_Tags PK中的字段顺序(对于相同的集群)如上所述的原因。)