使用额外的 Table 而不是数组 - MySQL
Using An Extra Table Instead Of Arrays - MySQL
我有一个图像库,我希望用户可以在其中根据特定主题从 MySQL 数据库中的现有图像创建图板。例如,他们可以创建一个名为 'London' 的图板,并将图书馆中已有的伦敦照片添加到该图板。
在板上 table 我最初无法弄清楚如何为每个板存储图像(有效地作为数组),但阅读了其他一些答案后,似乎最好的方法是解决这个问题创建一个额外的 table 以及 boards
table?
目前有 table 个涵盖 images
和 users
(以下简化):
用户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 的 id
和 board_name
,以及来自我的图像 table 的 image_filename
和 file_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_id
和 image_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_id
和 board_name
将这两者映射在一起,则不要同时有 board_id
和 board_name
其他 table。相反,在其他 table 中仅使用 board_id
。
与此同时,boards
table 将具有 board_id
和 board_name
(每个都有索引),以及关于“板”的任何属性。
images_boards
将有一个 board_id
和 image_id
;不需要其他任何东西。并且在 many-to-many table 上有两个索引:PRIMARY KEY(board_id, image_id)
和 INDEX(image_id, board_id)
。 table.
不需要单独的“id”
您还提到user_id
-- 它与董事会有关吗?还是配图?或者它真的是协会的另一个维度?如果是后者,则可以(尽管不常见)将其作为第三列。
我有一个图像库,我希望用户可以在其中根据特定主题从 MySQL 数据库中的现有图像创建图板。例如,他们可以创建一个名为 'London' 的图板,并将图书馆中已有的伦敦照片添加到该图板。
在板上 table 我最初无法弄清楚如何为每个板存储图像(有效地作为数组),但阅读了其他一些答案后,似乎最好的方法是解决这个问题创建一个额外的 table 以及 boards
table?
目前有 table 个涵盖 images
和 users
(以下简化):
用户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 的 id
和 board_name
,以及来自我的图像 table 的 image_filename
和 file_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_id
和image_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_id
和 board_name
将这两者映射在一起,则不要同时有 board_id
和 board_name
其他 table。相反,在其他 table 中仅使用 board_id
。
与此同时,boards
table 将具有 board_id
和 board_name
(每个都有索引),以及关于“板”的任何属性。
images_boards
将有一个 board_id
和 image_id
;不需要其他任何东西。并且在 many-to-many table 上有两个索引:PRIMARY KEY(board_id, image_id)
和 INDEX(image_id, board_id)
。 table.
您还提到user_id
-- 它与董事会有关吗?还是配图?或者它真的是协会的另一个维度?如果是后者,则可以(尽管不常见)将其作为第三列。