7

可能重复:
mysql 是多列中的数组

我有两张桌子:

帖子表

PostID | Gallery
  1    | 4,7,8,12,13
  2    | 1,2,3,4
  3    | 5,8,9
  4    | 3,6,11,14

Gallery 中的值是 Images 表中的主键:

图像表

ImageID | FileName
   1    | something.jpg
   2    | lorem.jpg
   3    | ipsum.jpg
   4    | what.jpg
   5    | why.jpg

我这样做而不是仅仅将 PostID 键添加到 Images 表的原因是因为这些图像可以与许多不同的帖子相关联。我想我可以为关系添加另一个表,但就我用来添加它的 jQuery 脚本而言,逗号分隔的值更容易使用。

如果我在需要与 PostID 3 关联的图像的页面上,我可以运行什么样的查询来输出它的所有文件名?

4

3 回答 3

26

您可以使用此解决方案:

SELECT b.filename
FROM posts a
INNER JOIN images b ON FIND_IN_SET(b.imageid, a.gallery) > 0
WHERE a.postid = 3

SQLFiddle

但是,您应该真正规范您的设计并在帖子和图像之间使用交叉引用表。这将是表示 N:M(多对多)关系的最佳和最有效的方式。它不仅检索效率更高,而且大大简化了图像关联的更新删除。


...但是就我用来添加它的 jQuery 脚本而言,逗号分隔的值更容易使用。

即使您使用交叉引用表正确表示了 N:M 关系,您仍然可以获得imageidCSV 格式的 's:

假设您有一个posts_has_images包含主键字段 ( postid, imageid) 的表:

您可以使用GROUP_CONCAT()来获取每个 的imageidCSV postid

SELECT postid, GROUP_CONCAT(imageid) AS gallery
FROM posts_has_images
GROUP BY postid
于 2012-07-13T01:57:14.027 回答
1

就正确的 SQL 而言,您绝对应该有另一个表来关联两者,而不是分隔列。

也就是说,您可以这样做:

SELECT * FROM Images i WHERE EXISTS (SELECT 1 FROM Posts p WHERE p.PostID = 3 AND i.ImageID IN (p.Gallery))
于 2012-07-13T02:03:27.220 回答
1

这是你的问题。这是一个糟糕的设计,因为您需要搜索Gallery字段的特定值。您可以使用FIND_IN_SET,但您的查询会很慢。转到 Gallery 的原子值 - 对其进行规范化。

于 2012-07-13T02:04:08.357 回答