我有两个表,images 和 image_data,这里是我的 image_data 表的示例。
image_id | slide_id | language_id | type |
101 | 1 | 1 | CQ |
101 | 2 | NULL | NULL |
56 | 5 | 1 | TN |
56 | NULL | 2 | NULL |
所以基本上,每个图像都会有不同的选项,我想知道实现它的最佳方法.. 因为我觉得我做错了。
有了这个,我可以运行查询以使用 GROUP_CONCAT()
将多行中的值转换为单个串联字符串。
image_id | slide_id | language_id | type |
101 | 1,2 | 1 | CQ |
56 | 5 | 1,2 | TN |
这很好,但我现在这样做的问题是..似乎很难用我的后端系统更新行。
因此,对于我的查询,我可以根据数据库确定要检查哪些查询,因为自从我将它连接起来后,我将所有查询都放在一行中。但现在就像……当我点击“保存”并更新行时,我应该更新哪一个?同一图像 ID 可能不止 1 行,因此我将如何更新正确的图像 ID,等等。
如果我在另一张幻灯片上勾选了image #101,那么我需要为其创建一个新行。如果在那之后我想向它添加另一个 language_id,那么我需要确保不添加新行,因为存在一个 NULL 值,并且只用新的语言 ID 替换 NULL 值。
这看起来真的很复杂,而且有很多因素,使用这种方法真的很难编程。
执行此操作的最佳方法是什么?非常感谢任何建议。
谢谢!
最佳答案
您需要做的是在您的图像
和幻灯片
/语言
/之间实现N:M(多对多)关系类型
表格,以便您的设计更加规范化(一个地方一个事实)。
这样想:一个image
可以有多个slides
,一个slide
可能是一个多个图像
的选项。 -- 这是一个 N:M 关系。语言和类型也是如此。
你需要做的是摆脱你的 image_data
表,它包含 ALL entities 之间的选项,并具有三个独立的交叉引用表代替。以下是您将如何建模:
基表:
images(image_id [PK], ...)
slides(slide_id [PK], slide_name, ...)
languages(language_id [PK], language_name, ...)
types(type_name [PK], ...)
交叉引用表:
images_has_slides(image_id [PK], slide_id [PK])
images_has_languages(image_id [PK], language_id [PK])
images_has_types(image_id [PK], type_name [PK])
它在 ER 中的样子:
使用这种类型的设计,您不必处理 NULL
值或确定要更新哪一行,因为您现在一个地方只有一个事实 .要获得所有选项,您仍然需要像这样执行 GROUP_CONCAT()
:
SELECT
a.*,
GROUP_CONCAT(c.slide_name) AS slides,
GROUP_CONCAT(e.language_name) AS languages,
GROUP_CONCAT(f.type_name) AS types
FROM
images a
LEFT JOIN
images_has_slides b ON a.image_id = b.image_id
LEFT JOIN
slides c ON b.slide_id = c.slide_id
LEFT JOIN
images_has_languages d ON a.image_id = d.image_id
LEFT JOIN
languages e ON d.language_id = e.language_id
LEFT JOIN
images_has_types f ON a.image_id = f.image_id
GROUP BY
a.image_id
然后要更新图像选项,您可以在交叉引用表上使用 INSERT
和 DELETE
:
假设您想在一张图片中添加两种语言,您会这样做
INSERT INTO images_has_languages (image_id, language_id)
VALUES (101, 4), (101, 5);
上述查询将 ID 为 4
和 5
的语言添加到 ID 为 101
的图像中。
要删除选项(取消选中表单)- 假设您想从图像中删除 2 张幻灯片
DELETE FROM images_has_slides WHERE image_id = 101 AND slide_id IN (3,6)
这将从 ID 为 101
的图像中删除 ID 为 3
和 6
的幻灯片。
因此,在您的应用程序中,您可以根据用户是未选中还是选中图像表单中的值来确定是否需要执行插入/删除查询。
关于php - 用于图像选项关系的 MySQL 数据库设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11279587/