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

kmd*_*ent 6 mysql sql database database-design foreign-keys

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

该列表存储为表单的逗号分隔值:

"阳光明媚,海滩,棕榈树"-im1

"手掌,下雨,云"-im2

"冬天,雪,雪人,赃物"-img

我希望能够得到查询标签的联合:"海滩,棕榈树"的查询应该返回im1和im2

谢谢

McG*_*gle 13

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

图像

  • ID
  • IMAGE_NAME

标签

  • ID
  • 标签名称

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')
Run Code Online (Sandbox Code Playgroud)


Bra*_*vic 5

@dbaseman 提供了一个很好的答案(+1),但这可能有点矫枉过正。假设你唯一想知道的标签是它的名称,只有 2 个表的模型在实践中可能会表现得更好(少一个 JOIN 和更好的数据聚类):

图像表:

  • 身份证号
  • 图像名称

image_tag 表:

  • 标签名称 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') 
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您还需要标签描述、标签作者等...,@dbaseman 的模型很好,除非您可能考虑翻转 Image_Tags PK 中的字段顺序(出于与上述相同的聚类原因)。