数据库状态标识位flag设计
设计目的
- 减少各种状态值字段
- 减少数据库冗余和存储空间
- 增加状态值时可灵活调整,无需增加额外字段
运用场景
例子1:管理用户的支付方式
比如针对不同用户组设置了不同的支付方式支持,假设支付方式有支付宝、微信、银联、借条等。A用户支持支付宝、微信;B用户支持支付宝、微信、借条。一般用户支付方式数据库设计为:
| 1 | A | 1 | 1 | 0 | 0 |
| 2 | B | 1 | 1 | 0 | 1 |
这时如果后续多了其它支付方式后,就需要调整表结构增加字段,如快钱、货到付款等。这种设计方式明显不符合数据库设计第一范式,增加了很多冗余字段和存储空间。
例子2:设置用户的操作权限
比如有一组权限列表,查看,编辑,发布,删除,数据库可能会是这样:
| 1 | A | 1 | 1 | 0 | 0 |
| 2 | B | 1 | 1 | 1 | 1 |
上面只是举些例子来说明一个问题,当一张表的字段里包含很多这些状态值01时,我们可以使用二进制位的方式来表示,而且只需要一个字段就好了。
设计思路
比如例1中的支付方式,假设我们最多可设计有10种支付方式。
字段仍设为int整形,A支持支付宝、微信,则值为12(1100);B支持支付宝、微信、借条,则值为13(1101),表结构如下:
| 1 | A | 12 |
| 2 | B | 13 |
如果增加了货到付款,可再赋值给二进制的第五位,其它位还是保持不变。
这时候会涉及到数据库查询问题,比如上面的值12、13都支持支付宝、微信,还有14(1110)、15(1111)也支持,如果增加了二进制第五位,那么会有更多匹配值,如30(11110)、28(11100)等...
如果要查询支持支付宝、微信的数据怎么办?这时只需要通过“位”的与运算,就能简单的查询出想要数据:
php简单实现
class PayFlag {const ALIPAY = 8; //01000const WEIXIN = 4; //00100const UNION = 2; //00010const IOU = 1; //00001function addFlag($old_flag, $flag) {return $old_flag | $flag;}function delFlag($old_flag, $flag) {return $old_flag ^ $flag;} }$old_flag = 6; //00110 $PayFlag = new PayFlag;//原有值 - 输出 6:110 echo($old_flag . ":" . decbin($old_flag) . PHP_EOL);//增加ALIPAY - 输出 14:1110 $new_flag = $PayFlag->addFlag($old_flag, PayFlag::ALIPAY); echo($new_flag . ":" . decbin($new_flag) . PHP_EOL);//移除ALIPAY - 输出 6:110 $new_flag = $PayFlag->delFlag($new_flag, PayFlag::ALIPAY); echo($new_flag . ":" . decbin($new_flag) . PHP_EOL);//移除UNION - 输出 4:100 $new_flag = $PayFlag->delFlag($new_flag, PayFlag::UNION); echo($new_flag . ":" . decbin($new_flag) . PHP_EOL);//增加IOU - 输出 5:101 $new_flag = $PayFlag->delFlag($new_flag, PayFlag::IOU); echo($new_flag . ":" . decbin($new_flag) . PHP_EOL);转载于:https://www.cnblogs.com/gouyg/p/mysql-flag-php.html
总结
以上是生活随笔为你收集整理的数据库状态标识位flag设计的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Leetcode643.Maximum
- 下一篇: pymysql 模块 使用目录