处理一对多关系更新的最佳方式

Best way to handle updates for one-to-many relationship

鉴于下面的两个 table,每个球可以有一种或多种颜色。 在 UI 中进行更改时更新 ball_color_mapping table 的最有效方法是什么?

例如,ball_id = 1color_ids1,2,3,更新后应该只有 color_id = 2.

我看到的可能选项:

  1. 删除所有与 ball_id 匹配的行,然后插入新值。
  2. 获取现有 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_idcolor 之间的映射?我会考虑摆脱它。除非有一些不言而喻的原因'normalization',否则我建议它是“over-normalization”。

既然删除和插入任务简单快捷,并且您将拥有适当的索引(您会的,不是吗?),那么做最简单的事情。那可能总是在做这两个步骤:

  1. 删除正在编辑的球的所有颜色
  2. 插入新的颜色集。

你最终会用这些颜色做什么?如果您只是根据要求反省它们,那么它们可以存储在 Balls table 中的一个简单的 VARCHAR(191) 列中。如果您需要“找到所有 'blue' 个球”,最好每种颜色一行。 (再一次,我建议简单地 'blue',而不是 color_id。)

如果您不是在谈论一个球上的数百种颜色或数千个球,那么请考虑 FIND_IN_SET('blue', "red,white,black,blue") 类型测试。 (这将需要检查所有行,但对于一个小数据集,这是可以容忍的。)