使用一个额外的表代替数组-MySQL



我有一个图像库,我希望用户可以在其中根据MySQL数据库中的现有图像创建特定主题的板。例如,他们可以创建一个名为"伦敦"的董事会,并将图书馆中已经存在的伦敦照片添加到该董事会中。

在电路板表中,我最初不知道如何存储每个电路板的图像(有效地作为阵列(,但在阅读了一些其他答案后,似乎最好的方法是创建一个额外的表以及boards表?

目前有涵盖imagesusers的表格(简化如下(:

用户表

+- id --+  username --+- 
|  36   |  Ted        |
|  37   |  James      |

图像表

+- id ----+  filename -------+- file_extension -+-
|  1038   |  bigben          |  jpeg            |
|  1039   |  toweroflondon   |  jpeg            |

所以,如果我理解这一点,我首先必须按照下面的创建一个板表

板材表

+- id -+ board_name -+- 
|  1   |  London     |
|  2   |  Trees      |

然后是一个由纯外键组成的附加表:来自boards表的idboard_name,来自我的图像表的image_filenamefile_extension,以及来自用户表的设置板的人的user_id,即id

images_boards表

+- board_id -+ board_name -+- image_filename -+- file_extension -+- user_id -+-
|  1         |  London     |  bigben          |  jpeg            |   36      |
|  1         |  London     |  toweroflondon   |  jpeg            |   36      |

我很难从概念上理解这一点,拥有一个由纯外键组成的表感觉很奇怪,尽管在这种用例中,这可能是完全可以接受/首选的解决方案。

因此,我的问题是——我是否正确地处理了这个问题?

如果在将board_idboard_name映射在一起的表中有CCD_11,则不要在任何其他表中同时有board_idboard_name。相反,在其他表中仅使用board_id

同时,boards表将具有board_idboard_name(每一个都被索引(,加上关于"0"的任何属性;董事会";。

19将具有CCD_ 20和CCD_;不需要其他任何东西。在这个多对多表上有两个索引:PRIMARY KEY(board_id, image_id)INDEX(image_id, board_id)。不需要单独的";id";那张桌子。

你还提到了user_id——它与董事会有关吗?还是用图像?或者这真的是关联的另一个维度吗?如果是后者,那么将其作为第三列也是可以的(尽管不寻常(。

一块板可以包含多个图像,一个图像可以添加到多个板中。这是一个典型的例子;多对多";数据模型中的关系。

因此,您的方法很好,但正如Paul在评论中所写,您不必将images表的内容复制到image_boards表中。您只需要其中有一个image_id列。

这些键仅用于存储所有这些实体之间的关系。然后,您的查询将连接相关的表,以检索每个实体所需的附加信息。

此外,如果将user_id放在该表中,这应该意味着用户创建的板可以由其他用户用图像填充。如果不是这样,那么user_id列应该只在boards表中。在每一个板/图像关系中重复它是没有用的。

最后,您必须为images_boards表的行设置主键。通常有两种方法:

  • 或者创建一个新的自动递增列,该列将是此关系的id(例如images_boards_id(
  • 或者,您可以使用现有列来组成一个唯一的组合,该组合可以用作主键。在您的情况下,如果一个图像不能在同一块板内添加多次,则可以使用board_idimage_id的组合来组成主键

构建关系数据库时,通常最好遵循某种程度的规范化。这样可以更容易地添加更多的表和重组表。在维基百科上阅读更多关于不同规范化水平的信息,例如:https://en.wikipedia.org/wiki/Database_normalization

因此,在这种情况下,您只需要images_boards表中的外键。

然后,当您想要获取数据时,您只需连接这些表。如果images_boards具有以下列,则获取一个板的数据的示例:board_id、image_id和user_id。

SELECT boards.id AS board_id, board_name, images.id AS image_id, image_filename, file_extension, users.id AS user_id, username
FROM your_schema.images_boards
INNER JOIN your_schema.images ON (images_boards.image_id = images.id)
INNER JOIN your_schema.boards ON (images_boards.board_id = boards.id)
INNER JOIN your_schema.users ON (images_boards.user_id = users.id)
WHERE board_id = x

相关内容

  • 没有找到相关文章

最新更新