我建议使用触发器来检查回答此问题的交叉表完整性约束。评论中已经建议它可能会导致问题:
执行跨行检查的触发器很少在大多数数据库上工作......因为它们无法从其他事务中读取未提交的行
不过,我还没有找到任何支持这一说法的消息来源。官方 文档没有提及任何内容。我发现的其他问题在 SO 上有所介绍- 它主要批评潜在的隐藏复杂性,因为触发器在第一眼中不可见。但即使是评分最高的答案也承认它们用于完整性问题。
所以我的问题是:数据库触发器对于跨表完整性约束是否安全?具体来说,下面的解决方案会起作用吗?
总结一下原来的问题。我们有桌子
- 玩家 - PlayerID, PlayerName
- 投注 - BetID、BetName
- play_in - 投注ID,玩家ID
约束是 BetName 和 PlayerID 的组合应该是唯一的。建议触发器的定义:
CREATE TRIGGER check_bet_name BEFORE INSERT ON plays_in
FOR EACH ROW BEGIN
DECLARE bet_exists INT DEFAULT 0;
DECLARE msg VARCHAR(255);
SELECT 1 INTO bet_exists
FROM Bet AS b1
WHERE b1.BetID = NEW.BetID
AND EXISTS (SELECT *
FROM plays_in AS p JOIN Bet AS b2 USING (BetID)
WHERE p.PlayerID = NEW.PlayerID AND b2.BetName = b1.BetName
)
LIMIT 1;
IF bet_exists THEN
SET msg = "Bet name already exists...";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
END IF;
END//