一個配置表或者一個存儲了多條狀態的表,需要在某個狀態中做切換,而當前是否啟用狀態標記是用0和1來標識的。這個時候通常 1表示正在使用中,0表示不在使用中。通常有些業務會做一些配置的狀態切換,就會出現要求0變1 1變0的情況,從某個狀態的不再使用 到另一個狀態的啟用,就帶來了數學上的互斥性,這樣的情況一般出現在這種狀態之間的存在是平行的,只能選擇一種,是互斥性事件。比如中學中學到的,一個白球一個紅球,兩個球二選一,就會出現選擇紅球還是白球的情況,而選擇結果必然是紅球或者白球中的一個,那么另外一個是必然選不上的,我們稱之為互斥。百度上的解釋為:
事件A和B的交集為空,A與B就是互斥事件,也叫互不相容事件。也可敘述為:不可能同時發生的事件。如A∩B為不可能事件(A∩B=Φ),那么稱事件A與事件B互斥,其含義是:事件A與事件B在任何一次試驗中不會同時發生
在這樣的設計下,違反了第三范式,應該拆分表為一個狀態明細的基礎表,一個選擇了的啟用狀態的記錄表,然而我們的數據庫設計中不可能總是達到第三范式,這樣的設計給我們的查詢帶來了比較大的難度,需要有兩次join才可以
比如我們舉一個簡單的例子,當前游戲的兵器配置表中 系統啟用了某一種兵器作為默認兵器,(游戲途中是可以切換的 系統有多種兵器) 現在狀態如下
該系統現在設置方天畫戟為默認武器,如果在配置中想把兵器默認配置為 如意金箍棒,在以往我們的認知中 需要兩條SQL
如此可完成將兵器配置從方天畫戟切換到如意金箍棒。
我們可以看到 采用兩條SQL進行更新,可以達到效果。根據互斥原理,必須全部更新但是保留新數據的狀態,才能將啟用的信息從id=3切換到id=4
改進的SQL如下
采用if語句完成更新狀態的切換。優點是合並SQL,缺點是采用了if函數,降低可讀性和效率了,當然開發者可以根據自己項目所處條件和環境來決定如何處理。
在上述問題只有兩種狀態可以切換的時候,就出現了AB兩個事件的互斥事件,這個時候,還有其他的辦法來解決上述問題。比如
魔法的使用情況 使用 放棄 兩種互斥事件產生,分別采用了兩行記錄來存儲(而且必須是兩行記錄 思考一下為什么,為何不用一個列字段來存儲呢?挖坑在此,請自己思考),而切換狀態的時候,必然是一個啟用 ,一個不啟用,那么這個時候又該如何高效的處理呢?當然還是可以采用最基本的辦法兩條SQL處理,效果如下
或者是我上面那種if方法來處理,當然我們還有其他辦法,在思考這個問題的時候,我們注意觀察到 狀態形成互斥0 和1 ,不正是數據類型中的布爾型嗎?那么布爾型的轉換如何讓0變1 1變0呢?小學的數學公式告訴我們,加數與加數之間的互換可以有和來解決,所以0和1之間的切換可以有0+1=1的和1來解決,所以SQL如下:
即解決了狀態的啟用在兩種互斥狀態中的切換!