数据库布尔型状态字段互斥性的SQL更新操作

一个配置表或者一个存储了多条状态的表,需要在某个状态中做切换,而当前是否启用状态标记是用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如下:

即解决了状态的启用在两种互斥状态中的切换!

posted @ 2017-03-13 16:58  李照耀  阅读(1918)  评论(0编辑  收藏  举报