我目前正在研究具有可空外键的模式。 基本上,这就是我想要实现的目标:
假设:
表1:
game:
id
observer_id
starts_on
ends_on
type
表2:
observer:
id
game_id DEFAULT NULL
starts_on
ends_on
type
FOREIGN KEY (`game_id`) REFERENCES `game`(`id`) ON DELETE SET NULL
现在,我想做什么 - 我希望复制为初始值,并在starts_on
表中的级联ends_on
,type
和observer
字段进行更新,如果我引用了game
,但是如果game_id
为null,我想为上述字段提供一个独立的值。在mysql中使用IF
可能是这样的,或者我应该在模型文件中实现逻辑吗?
答案 0 :(得分:2)
考虑在数据检索(SELECT)而不是数据操作(INSERT / UPDATE / DELETE)时解决您的问题。
select
o.id,
o.game_id,
coalesce(g.starts_on, o.starts_on) as starts_on,
coalesce(g.ends_on, o.ends_on) as ends_on,
coalesce(g.type, o.type) as type
from observer o
left join game g on g.id = o.game_id
在此查询中,如果o.game_id
为NULL
,则LEFT JOIN将在game
表中找不到匹配项,其所有列也将为NULL
。然后,COALESCE()
将负责选择game
表中的值(如果存在)或observer
。
您可以在VIEW中使用该查询(如果您愿意),但我无法判断它在任何用例中是否表现良好。
通过这种方式,您可以存储"独立的"如果game id
未设置,则无需担心,因为只有在game_id
不是NULL
的情况下才会使用它们。
请注意,您的问题可能会在更多" clean"改变架构的方式。对于列game.observer_id
和observer.game_id
,它看起来像循环关系,可以视为"设计气味" 。但是,如果不了解您的数据逻辑,我无法提出更好的方法。
答案 1 :(得分:0)
FOREIGN KEYs
做了有限的事情。一旦超越它们,您应该在应用程序代码(或存储过程或......)中构建自己的事务来执行更复杂的事务。
我觉得这是更安全的路线,因为你确切地知道你需要什么,而且不必试图穿着FK来做这件事。