设计目的

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

运用场景

例子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. Day 49 CSS样式.

    外部样式 1.元素选择器 /*1. 元素选择器*/p{ color :red} <p>1.我是一个p标签</p> 2.ID选择器 /*2 ID 选择器*/#p{ color : ...

  2. jzoj5843

    给定 n 个正整数序列 ,每个序列长度为m. 选择至少 1 个序列,在每个被选择的序列中选择一个元素,求出所有被选择的元素的 gcd. 求所有方案的结果之和,答案对 1e9+7 取模.两种方案不同,当 ...

  3. [Dart]语法基础

    此页面向您展示如何使用每个主要Dart功能,从变量和运算符到类和库,假设您已经知道如何使用其他语言编程. 要了解有关Dart核心库的更多信息,请参阅 Dart Libraries之旅.无论何时需要有关 ...

  4. day 32 css后续补充以及js 简单入门

    前情提要: 利用html 和css ,js 模拟小米的官网(待做) 一:第一个sj利子 <!DOCTYPE html> <html lang="en"> & ...

  5. Windows下安装MySQL详细教程

    Windows下安装MySQL详细教程 1.安装包下载  2.安装教程 (1)配置环境变量 (2)生成data文件 (3)安装MySQL (4)启动服务 (5)登录MySQL (6)查询用户密码 (7 ...

  6. 全屏背景图的实现及background的相关属性

    今天需要做一个占满设备宽度的轮播图,这里作为demo仅展示一张图,下面分别是要操作的图片(这里做了缩放处理,实际的图比较大),以及要实现的效果图,很明显两者是不成比例的:      (图一)     ...

  7. (转)MySQL的Grant命令

    [MySQL] - MySQL的Grant命令 来源:http://yingxiong.javaeye.com/blog/451208 本文实例,运行于 MySQL 5.0 及以上版本. MySQL ...

  8. Java之集合(二十一)LinkedTransferQueue

    转载请注明源出处:http://www.cnblogs.com/lighten/p/7505355.html 1.前言 本章介绍无界的阻塞队列LinkedTransferQueue,JDK7才提供了这 ...

  9. 【字符串】Reverse Words in a String(两个栈)

    题目: Given an input string, reverse the string word by word. For example,Given s = "the sky is b ...

  10. JDBC链接oracle数据库

    package test; import java.sql.* ; public class JDBC_Test { //orcl为oracle数据库中的数据库名,localhost表示连接本机的or ...