我有一个图像库,我希望用户可以在其中根据MySQL数据库中的现有图像创建特定主题的板。例如,他们可以创建一个名为"伦敦"的董事会,并将图书馆中已经存在的伦敦照片添加到该董事会中。
在电路板表中,我最初不知道如何存储每个电路板的图像(有效地作为阵列(,但在阅读了一些其他答案后,似乎最好的方法是创建一个额外的表以及boards
表?
目前有涵盖images
和users
的表格(简化如下(:
用户表
+- id --+ username --+-
| 36 | Ted |
| 37 | James |
图像表
+- id ----+ filename -------+- file_extension -+-
| 1038 | bigben | jpeg |
| 1039 | toweroflondon | jpeg |
所以,如果我理解这一点,我首先必须按照下面的创建一个板表
板材表
+- id -+ board_name -+-
| 1 | London |
| 2 | Trees |
然后是一个由纯外键组成的附加表:来自boards
表的id
和board_name
,来自我的图像表的image_filename
和file_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_id
和board_name
映射在一起的表中有CCD_11,则不要在任何其他表中同时有board_id
和board_name
。相反,在其他表中仅使用board_id
。
同时,boards
表将具有board_id
和board_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_id
和image_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