设计目的

  • 减少各种状态值字段
  • 减少数据库冗余和存储空间
  • 增加状态值时可灵活调整,无需增加额外字段

运用场景

例子1:管理用户的支付方式

比如针对不同用户组设置了不同的支付方式支持,假设支付方式有支付宝微信银联借条等。A用户支持支付宝、微信;B用户支持支付宝、微信、借条。一般用户支付方式数据库设计为:

ID name alipay weixin union iou
1 A 1 1 0 0
2 B 1 1 0 1

这时如果后续多了其它支付方式后,就需要调整表结构增加字段,如快钱、货到付款等。这种设计方式明显不符合数据库设计第一范式,增加了很多冗余字段和存储空间。

例子2:设置用户的操作权限

比如有一组权限列表,查看编辑发布删除,数据库可能会是这样:

ID name is_visible is_editble is_publishable is_deleteable
1 A 1 1 0 0
2 B 1 1 1 1

上面只是举些例子来说明一个问题,当一张表的字段里包含很多这些状态值01时,我们可以使用二进制的方式来表示,而且只需要一个字段就好了。

设计思路

比如例1中的支付方式,假设我们最多可设计有10种支付方式。

字段仍设为int整形,A支持支付宝、微信,则值为12(1100);B支持支付宝、微信、借条,则值为13(1101),表结构如下:

ID name pay_flag
1 A 12
2 B 13

如果增加了货到付款,可再赋值给二进制的第五位,其它位还是保持不变。

这时候会涉及到数据库查询问题,比如上面的值12、13都支持支付宝、微信,还有14(1110)、15(1111)也支持,如果增加了二进制第五位,那么会有更多匹配值,如30(11110)、28(11100)等...

如果要查询支持支付宝、微信的数据怎么办?这时只需要通过“位”的与运算,就能简单的查询出想要数据:

select * from user_pay where pay_flag & b'1100';
# 或者:
select * from user_pay where pay_flag & 12;

php简单实现

class PayFlag {
const ALIPAY = 8; //01000
const WEIXIN = 4; //00100
const UNION = 2; //00010
const IOU = 1; //00001 function 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);

数据库状态标识位flag设计的更多相关文章

  1. Java秒杀简单设计二:数据库表和Dao层设计

    Java秒杀简单设计二:数据库表Dao层设计 上一篇中搭建springboot项目环境和设计数据库表  https://www.cnblogs.com/taiguyiba/p/9791431.html ...

  2. verilog实现的16位CPU设计

    verilog实现的16位CPU设计 整体电路图 CPU状态图 idle代表没有工作,exec代表在工作 实验设计思路 五级流水线,增加硬件消耗换取时间的做法. 具体每一部分写什么将由代码部分指明. ...

  3. SQL切换真假状态标识字段

    需求:用一条SQL(SQL SERVER)语句,实现反向更改状态标识字段(类型为bit)的值.即是从true变false,或从false到true. 方案: 一.判断原来这个字段值,然后UPDATE为 ...

  4. 4. SQL Server数据库状态监控 - 作业状态

    原文:4. SQL Server数据库状态监控 - 作业状态 有很多地方可以设置定时任务,比如:Windows的计划任务,Linux下的crontab,各种开发工具里的timer组件.SQL Serv ...

  5. 执行时关闭标识位 FD_CLOEXEC 的作用

    首先先回顾 apue 中对它的描述: ① 表示描述符在通过一个 exec 时仍保持有效(书P63,3.14节 fcntl 函数,在讲 F_DUPFD 时顺便提到) ② 对打开文件的处理与每个描述符的执 ...

  6. SQL SERVER数据库状态(脱机,联机,可疑)及SQL设置语句详解

      首先我们应该知道数据库总是处于一个特定的状态中,下面先来了解一下数据库的常见的三种状态:1,脱机:我们可以在Microsoft SQL Server Management中看到该数据库,但该数据库 ...

  7. 2. SQL Server数据库状态监控 - 错误日志

    原文:2. SQL Server数据库状态监控 - 错误日志 无论是操作系统 (Unix 或者Windows),还是应用程序 (Web 服务,数据库系统等等) ,通常都有自身的日志机制,以便故障时追溯 ...

  8. 3. SQL Server数据库状态监控 - 可用空间

    原文:3. SQL Server数据库状态监控 - 可用空间 数据库用来存放数据,那么肯定需要存储空间,所以对磁盘空间的监视自然就很有必要了. 一. 磁盘可用空间 1. 操作系统命令或脚本.接口或工具 ...

  9. SQLSERVER 运维日记-数据库状态

    背景 新年伊始,小伙伴是不是还处于假期综合症的状态.我们在日常运维数据库的时候,会时常查看数据库的状态,检查数据库是否正常运行.对于这些状态的熟悉对于我们处理数据库无法访问的 问题非常重要.当数据库突 ...

随机推荐

  1. [5.19 线下活动]Docker Meetup杭州站—拥抱Kubernetes,容器深度实践

    对本次线下活动感兴趣的朋友,欢迎点击此处报名,领取免费票. 今年3月,Docker刚刚过完5岁生日,五年期间,Docker也逐渐在技术和实践方面趋于成熟,更是在去年年底主动拥抱Kubernetes. ...

  2. 程序媛计划——python数据库

    #实例:用数据库存储日记,实现日记本功能 #流程 #创建数据库 #coding:utf-8 import sqlite3 connect=sqlite3.connect('test.db') conn ...

  3. jzoj3519

    我們考慮將一個節點x的所有兒子的數都改成y 記lcm[x]表示一個點的所有子節點的lcm值 那麼我們會發現y*deg[x] 要被lcm[x]整除 那麼x就會比x所有子節點最小的數小,記為z 那麼x就是 ...

  4. 了解ORACLE培训OCA-OCP-OCM课程表

    了解ORACLE培训OCA-OCP-OCM课程表考试号: OCA    1Z0-007$125    Oracle Database 10g:SQL Fundamentals 本课程培养学生必要的SQ ...

  5. execvp php-fpm reload使用的函数

    php重启 本质上是调用 execvp("/usr/local/php/sbin/php-fpm"); execvp就是用一个新的进程把自己替换掉,一个进程一旦调用exec类函数, ...

  6. 一文详解python的类方法,普通方法和静态方法

    首先形式上的区别,实例方法隐含的参数为类实例self,而类方法隐含的参数为类本身cls. 静态方法无隐含参数,主要为了类实例也可以直接调用静态方法. 所以逻辑上,类方法被类调用,实例方法被实例调用,静 ...

  7. 前端必备:FastStoneCapture 和 Licecap &&& mingw c++ 编译执行

    端必备:FastStoneCapture 和 Licecap FastStoneCapture这个软件非常小,只有2M多,并且其功能很强大,包括截图,录制视频,量尺,取色等等,对于前端工程师绝对是必备 ...

  8. centos7上安装redis

    关闭防火墙:systemctl stop firewalld.service #停止firewallsystemctl disable firewalld.service #禁止firewall开机启 ...

  9. 【链表】Rotate List(三个指针)

    题目: Given a list, rotate the list to the right by k places, where k is non-negative. For example:Giv ...

  10. Python&Appium实现安卓手机图形解锁

    首先,在解锁状态下,建立一个Session,打开APP.然后,调用press_keycode()方法传入整型数值"26",锁定屏幕.通过implicitly_wait()方法等待两 ...