处理一对多关系更新的最佳方式
Best way to handle updates for one-to-many relationship
鉴于下面的两个 table,每个球可以有一种或多种颜色。
在 UI 中进行更改时更新 ball_color_mapping
table 的最有效方法是什么?
例如,ball_id = 1
有 color_ids
个 1,2,3
,更新后应该只有 color_id = 2
.
我看到的可能选项:
- 删除所有与
ball_id
匹配的行,然后插入新值。
- 获取现有
color_ids
,比较新旧值以及 delete/insert。
选项 1 似乎是最简单的,但如果数据没有更改,也会导致删除和插入。选项 2 会增加更多的操作和复杂性,因为需要根据条件获取然后删除数据,并插入新值(3 个操作 + 逻辑 vs 2 个操作)
对于遇到此问题的其他人,哪个选项更有效?是否有更好的方法?
球table:
ball_id
name
brand_id
1
tennis ball
1
2
pool ball
2
3
ping pong ball
1
ball_color_mapping table:
ball_id
color_id
1
1
1
2
1
3
2
1
3
2
3
3
我会这样做:
DELETE FROM ball_color_mapping WHERE ball_id = ? AND color_id NOT IN (?, ?, ?);
INSERT INTO ball_color_mapping VALUES (?, ?), ...
ON DUPLICATE KEY UPDATE color_id=VALUES(color_id);
处理从球的颜色集中删除颜色的情况,然后在必要时插入,如果颜色已经在数据库中,则执行 no-op 更新。
这假定 ball_color_mapping 中的一对列是其主键,以触发 ON DUPLICATE 子句。
你在某处有 color_id
和 color
之间的映射?我会考虑摆脱它。除非有一些不言而喻的原因'normalization',否则我建议它是“over-normalization”。
既然删除和插入任务简单快捷,并且您将拥有适当的索引(您会的,不是吗?),那么做最简单的事情。那可能总是在做这两个步骤:
- 删除正在编辑的球的所有颜色
- 插入新的颜色集。
你最终会用这些颜色做什么?如果您只是根据要求反省它们,那么它们可以存储在 Balls
table 中的一个简单的 VARCHAR(191)
列中。如果您需要“找到所有 'blue' 个球”,最好每种颜色一行。 (再一次,我建议简单地 'blue',而不是 color_id
。)
如果您不是在谈论一个球上的数百种颜色或数千个球,那么请考虑 FIND_IN_SET('blue', "red,white,black,blue")
类型测试。 (这将需要检查所有行,但对于一个小数据集,这是可以容忍的。)
鉴于下面的两个 table,每个球可以有一种或多种颜色。
在 UI 中进行更改时更新 ball_color_mapping
table 的最有效方法是什么?
例如,ball_id = 1
有 color_ids
个 1,2,3
,更新后应该只有 color_id = 2
.
我看到的可能选项:
- 删除所有与
ball_id
匹配的行,然后插入新值。 - 获取现有
color_ids
,比较新旧值以及 delete/insert。
选项 1 似乎是最简单的,但如果数据没有更改,也会导致删除和插入。选项 2 会增加更多的操作和复杂性,因为需要根据条件获取然后删除数据,并插入新值(3 个操作 + 逻辑 vs 2 个操作)
对于遇到此问题的其他人,哪个选项更有效?是否有更好的方法?
球table:
ball_id | name | brand_id |
---|---|---|
1 | tennis ball | 1 |
2 | pool ball | 2 |
3 | ping pong ball | 1 |
ball_color_mapping table:
ball_id | color_id |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 1 |
3 | 2 |
3 | 3 |
我会这样做:
DELETE FROM ball_color_mapping WHERE ball_id = ? AND color_id NOT IN (?, ?, ?);
INSERT INTO ball_color_mapping VALUES (?, ?), ...
ON DUPLICATE KEY UPDATE color_id=VALUES(color_id);
处理从球的颜色集中删除颜色的情况,然后在必要时插入,如果颜色已经在数据库中,则执行 no-op 更新。
这假定 ball_color_mapping 中的一对列是其主键,以触发 ON DUPLICATE 子句。
你在某处有 color_id
和 color
之间的映射?我会考虑摆脱它。除非有一些不言而喻的原因'normalization',否则我建议它是“over-normalization”。
既然删除和插入任务简单快捷,并且您将拥有适当的索引(您会的,不是吗?),那么做最简单的事情。那可能总是在做这两个步骤:
- 删除正在编辑的球的所有颜色
- 插入新的颜色集。
你最终会用这些颜色做什么?如果您只是根据要求反省它们,那么它们可以存储在 Balls
table 中的一个简单的 VARCHAR(191)
列中。如果您需要“找到所有 'blue' 个球”,最好每种颜色一行。 (再一次,我建议简单地 'blue',而不是 color_id
。)
如果您不是在谈论一个球上的数百种颜色或数千个球,那么请考虑 FIND_IN_SET('blue', "red,white,black,blue")
类型测试。 (这将需要检查所有行,但对于一个小数据集,这是可以容忍的。)