使用额外的 Table 而不是数组 - MySQL

Using An Extra Table Instead Of Arrays - MySQL

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

在板上 table 我最初无法弄清楚如何为每个板存储图像(有效地作为数组),但阅读了其他一些答案后,似乎最好的方法是解决这个问题创建一个额外的 table 以及 boards table?

目前有 table 个涵盖 imagesusers(以下简化):

用户table

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

图片table

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

所以,如果我理解这一点,我首先必须按照以下内容创建一个看板table

板子table

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

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

images_boards table

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

我正在努力从概念上解决这个问题,table 由纯外键组成感觉很奇怪,尽管这很可能是完全接受table /首选解决方案这样的用例。

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

一个版块可以包含多个图片,一张图片可以添加到多个版块。这是数据模型中 "many-to-many" 关系的典型示例。

所以您的方法很好,但正如 Paul 在他的评论中所写,您不必将 images table 的内容复制到 image_boards 中。您只需要在其中添加一个 image_id 列即可。

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

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

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

  • 要么创建一个新的自动递增列作为此关系的 ID(例如 images_boards_id)。
  • 或者您可以使用现有的列来组成一个唯一的组合,可以用作主键。在您的情况下,如果不能在同一个板上多次添加图像,则 board_idimage_id 的组合可用于构成主键。

构建关系数据库时,通常最好遵循某种程度的规范化。这使得添加更多 table 和重组 table 变得更加容易。在维基百科中阅读更多关于不同规范化级别的信息,例如:https://en.wikipedia.org/wiki/Database_normalization

所以在这种情况下,您只需要 images_boards table.

中的外键

然后你只要加入tables当你想获取数据。如果 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

如果 table 中有 board_idboard_name 将这两者映射在一起,则不要同时有 board_idboard_name其他 table。相反,在其他 table 中仅使用 board_id

与此同时,boards table 将具有 board_idboard_name(每个都有索引),以及关于“板”的任何属性。

images_boards 将有一个 board_idimage_id;不需要其他任何东西。并且在 many-to-many table 上有两个索引:PRIMARY KEY(board_id, image_id)INDEX(image_id, board_id)。 table.

不需要单独的“id”

您还提到user_id -- 它与董事会有关吗?还是配图?或者它真的是协会的另一个维度?如果是后者,则可以(尽管不常见)将其作为第三列。