共计 1369 个字符,预计需要花费 4 分钟才能阅读完成。
前言
当咱们数据库变得相对简单时,关联删除变得不切实际,这时咱们想到了应用软删除代替删除,然而软删除并没有删除数据,数据仍旧存在。当咱们表内有惟一字段时,例如用户表中的 username 字段,咱们删除原先的用户,雷同 username 的用户便无奈注册。这是咱们所期待的。最好的解决办法就是,再设置 deleted_at 字段,记录“删除”一条数据的工夫,将以 username 为惟一索引变为 username 与 deleted_at 独特为惟一索引。惟一索引就是不容许呈现 username 与çsername 雷同的数据,当删除数据时,deleted_at 扭转,username 能够再次增加,并能够屡次删除。如何当“删除”数据时扭转 deleted_at 就是用到了咱们的触发器。
触发器
触发器相似与咱们的切面编程。在一个特定的事件执行前后,会触发咱们提前设置好的触发器。
咱们关上 navicat,轻易点击一个数据表,点击设计表
triggers 就是咱们的触发器,点击左上角加号创立一个触发器。
name:轻易起一个名字就好
Time:分为 after 和 before,顾名思义,在什么时候触发。之前或者之后。
事件:前面是一个三选一的选项,insert(减少),update(更新),delete(删除)。由哪一类事件触发。
最上面的是触发的 sql 语句。
new 和 old
该关键字,示意触发了触发器的那一行数据。INSERT
触发器中,NEW 用来示意将要 (BEFORE) 或曾经 (AFTER) 插入的新数据。UPDATE
触发器中,OLD 用来示意将要或曾经被批改的原数据,NEW 用来示意将要或曾经批改为的新数据。DELETE
触发器中,OLD 用来示意将要或曾经被删除的原数据。
另外,OLD 是只读的,而 NEW 则能够在触发器中应用 SET 赋值,这样不会再次触发触发器,造成循环调用。
触发事件
回归咱们的需要,咱们心愿“删除”的时候触发触发器,使得 deleted_at 变为以后工夫。然而,咱们的“删除”并不是真正的删除,而是软删除,也就是更新这条数据的 deleted 字段为 0。所以咱们应该抉择绑定 update 触发器,并抉择在 before 时触发
而后是设置触发 sql 语句。咱们不心愿只有执行更新操作就执行,只有在软删除时执行,所以咱们须要加一个判断语句触发执行。
而后在依据报错提醒批改语法,最初是这样的
BEGIN
IF new.deleted = 1 THEN
SET NEW.deleted_at = CURRENT_TIMESTAMP;
END IF;
END
当 deleted 为 1 的时候触发。
验证成果如下
如果语句这样写
BEGIN
IF new.deleted = 1 THEN
UPDATE `tag` SET `deleted_at` = CURRENT_TIMESTAMP;
END IF;
END
再去执行他会报错。
大略意思就是你不能执行 update 操作因为他正在被触发器调用。这应该是 mysql 的一种爱护机制,避免触发器有限调用。
然而我想用 after 触发器的时候遇到了困惑,两种写法都不行,new 和 old 貌似对于 after 触发器来说不认可。这里没搞懂她的语法是什么。
总结
数据库也蕴含着很大的学识。下学期也要学数据库了。JPA 给了咱们很大便当,这也使得遇到原生的 mysql 就不会了。原本还想写一篇索引来着,然而有个问题始终没有解决,也写不进去什么货色。