mysql - 触发器的实际使用场景, 可能也就是这个了, 一起讨论还有没有别的
ringa_lee
ringa_lee 2017-04-17 16:40:51
0
2
637

触发器的实际使用场景大体说来就是帮你方便的迁移数据, 不过最好不要和业务紧密结合, 因为一个事务的的一部分在java那边, 另另一部分在触发器中是无法很方便的调试/排查/维护的, 唯有一个场景, 就是不想物理删数据的时候

很久以前有个不成文的规定就是, 不要物理删除数据, 所有表都要加上is_delete这个字段来标识某行数据是否被物理删除, 但是当遇到有唯一索引的时候, 这个规则就歇菜了, 因为, 比如name是唯一索引, 当用户添加xiaoming后, 然后删除xiaoming, 这时is_delete = Y,但是再次重新添加xiaoming就不可以了, 因为违反了唯一约束

因此, 这种情况, 就不要更新is_delete了, 而是利用 after delete 类型的触发器将数据迁移到另外的一张表, 比如 user_del 中, 他的字段与user表一致, 只不过多了个记录插入数据时间的字段

大家还有没有其他使用场景呢???????

ringa_lee
ringa_lee

ringa_lee

全部回覆(2)
大家讲道理

首先關於觸發器,很多大公司是禁止使用的,一是可移植性差,二是影響性能,這也是我強烈主張的。

接著著重討論下非實體刪除的情況吧。碰到有唯一鍵約束並且有is_delete這種列的表,確實特別蛋痛的。我在專案中是這麼處理的,假設用戶表user有這麼幾列:

  • id (主鍵)

  • username (唯一鍵)

  • ...

  • is_delete

插入時,如果唯一鍵衝突,那就查一下有沒有被刪除的同名使用者:

SELECT id FROM user WHERE username = ? AND is_delete = 1

有同名的話(並且得到了id)做一個UPDATE操作,就當是恢復刪除了:

UPDATE user SET ..., is_delete = 0 WHERE id = ?

然後蛋痛的問題就來了,既然用戶有刪除的需求(說實話這種需求是不多見的),也就有改用戶名的需求。改用戶名遇到主鍵衝突,而已存在的用戶是已被邏輯刪除的,那麼你到底是讓他改還是不讓他改呢?

權宜之計是把唯一鍵也做成「非物理」的,每次創建用戶前都去查一下,查到沒有被刪除的同名用戶,就允許創建,改名也一樣。不過這種操作可能要做成交易了,因為在並發高的情況下,完全可能SELECT的時候還沒重名,但INSERT就重名了。

大家讲道理

樓上的問題
"改用戶名遇到主鍵衝突,並且已存在的用戶是已被邏輯刪除的,那麼你到底是讓他改還是不讓他改呢?"
有個辦法以前在小項目使用過,不知道大的項目可不可行。
每個表都使用自增ID,主鍵的約束使用 主鍵+"is_delete" 的約束。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!