MySQL条件引用外键

时间:2018-06-01 08:20:39

标签: mysql

我目前正在研究具有可空外键的模式。 基本上,这就是我想要实现的目标:

假设:

表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_ontypeobserver字段进行更新,如果我引用了game,但是如果game_id为null,我想为上述字段提供一个独立的值。在mysql中使用IF可能是这样的,或者我应该在模型文件中实现逻辑吗?

2 个答案:

答案 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_idNULL,则LEFT JOIN将在game表中找不到匹配项,其所有列也将为NULL。然后,COALESCE()将负责选择game表中的值(如果存在)或observer

您可以在VIEW中使用该查询(如果您愿意),但我无法判断它在任何用例中是否表现良好。

通过这种方式,您可以存储"独立的"如果game id未设置,则无需担心,因为只有在game_id不是NULL的情况下才会使用它们。

请注意,您的问题可能会在更多" clean"改变架构的方式。对于列game.observer_idobserver.game_id,它看起来像循环关系,可以视为"设计气味" 。但是,如果不了解您的数据逻辑,我无法提出更好的方法。

答案 1 :(得分:0)

FOREIGN KEYs做了有限的事情。一旦超越它们,您应该在应用程序代码(或存储过程或......)中构建自己的事务来执行更复杂的事务。

我觉得这是更安全的路线,因为你确切地知道你需要什么,而且不必试图穿着FK来做这件事。