我要存储会员信息
业务是多变的,需要存储多种标识。
如:
要标识会员是否是卖家,
要标识会员手机是否已认证
要标识会员是网站还是手机注册
。。。。
这些标识是互相独立,需要支持联合查询
一般的做法是针对每个标识做个字段
tinyint is_sell comment '1:卖家,0:买家'
tinyint mobile_auth comment '1:已认证,0:未认证'
tinyint regist_from comment '1:网站,2:手机'
要查 是卖家,手机已认证的
is_sell = 1 and mobile_auth = 1
问题
标识是随时可能增加的,这意味着字段也要增加,这显然是非常困难的。
解决办法
1.标识以2的次方设置,标识值相加以10进制存储在字段中
如:卖家标识是 2的0次方,1
手机认证是 2的1次方,2
来自手机注册 2的2次方 4
某会员是卖家,来自手机注册,1+4 = 5
存储在数据库标识字段值是:5
2.要查有卖家标识的会员
(5 & 1) == 1 ------> true
二进制与运算,返回值是该标识表明成立
101
001
-----
001
3.要查有卖家标识且手机认证的会员
(5 & (1+2)) == (1+2) ----> false
二进制与运算,返回值是几个标识的和表明成立
101
011
------
001
注意:
1. 在mysql中以long字段存储,可以存储2的64方的值,即最多可存储标识64个
业务是多变的,需要存储多种标识。
如:
要标识会员是否是卖家,
要标识会员手机是否已认证
要标识会员是网站还是手机注册
。。。。
这些标识是互相独立,需要支持联合查询
一般的做法是针对每个标识做个字段
tinyint is_sell comment '1:卖家,0:买家'
tinyint mobile_auth comment '1:已认证,0:未认证'
tinyint regist_from comment '1:网站,2:手机'
要查 是卖家,手机已认证的
is_sell = 1 and mobile_auth = 1
问题
标识是随时可能增加的,这意味着字段也要增加,这显然是非常困难的。
解决办法
1.标识以2的次方设置,标识值相加以10进制存储在字段中
如:卖家标识是 2的0次方,1
手机认证是 2的1次方,2
来自手机注册 2的2次方 4
某会员是卖家,来自手机注册,1+4 = 5
存储在数据库标识字段值是:5
2.要查有卖家标识的会员
(5 & 1) == 1 ------> true
二进制与运算,返回值是该标识表明成立
101
001
-----
001
3.要查有卖家标识且手机认证的会员
(5 & (1+2)) == (1+2) ----> false
二进制与运算,返回值是几个标识的和表明成立
101
011
------
001
注意:
1. 在mysql中以long字段存储,可以存储2的64方的值,即最多可存储标识64个
public class BitUtils {
/**
* 2的几次方
*
* @param position
* @return
*/
public static long pow2(int num) {
return ((Double) Math.pow(2, num)).longValue();
}
/**
* 判断 一个数number的二进制格式的第position位是否为1
*
* @param number
* 十进制数
* @param position
* 第几位 右到左从0开始
* @return
*/
public static boolean isTrue(long number, int position) {
long decimalValue = pow2(position);
return (decimalValue & number) == decimalValue;
}
/**
* 位或 运算
*
* @param m
* @param n
* @return
*/
public static long computeOR(long m, long n) {
return m | n;
}
/**
* 针对一个10进制数的位运算,增加位
*
* @param number
* 10进制数
* @param position
* 位数 从0开始
* @return
*/
public static long addBit(long number, int position) {
if (number < 0 || position < 0)
return 0;
return computeOR(number, pow2(position));
}
/**
* 针对一个10进制数的位运算,删除位
*
* @param number
* 10进制数
* @param position
* 位数 从0开始
* @return
*/
public static long removeBit(long number, int position) {
if (number < 0 || position < 0)
return 0;
if (isTrue(number, position)) {
number = number - pow2(position);
}
return number;
}
public static void main(String[] args) {
// System.out.println(pow2(0));
long a = addBit(0, 5);
System.out.println(a);
}
}