mysql 位运算 一对多_mysql位运算简化简单的一对多关系

记得以前参与的一个房地互联网平台,用户角色只有固定三种。普通用户、经纪人和管理员。每一种角色的系统权限也是固定的,只有数据权限是动态的。这应该是跟大部分erp系统复杂的角色和权限管理所不一样的地方,也是互联网平台和企业系统的区别之一吧。

当时的解决方案是,用一个整型字段存储角色,1代表普通用户,2代表经纪人,4代表管理员。相应的,1+4=5代表普通用户+管理员。换算成位运算就很直观了。

1=1

2=10

4=100

5=101

不过这些操作都是在程序代码里做的判断。现在在数据库层次上,遇到了同样的问题,对于简单的一对多的关系,比如一所学校既有高中又有初中,能否用一个字段表示,同时在数据库层次能高效地查询出来。答案是肯定的,网上搜索到了这篇文章,正是我想要的。

在mysql中,如果某条数据与其它数据存在一对多的关系,一般我们很自然的就会想到建立一个关系表。例如有一个景点信息的数据表,其结构如下:

id

int(主键)

name

varchar(景点名)

province

int(省份)

city

int(城市)

每个景点包含很多属性,例如适合旅游的月份,我们一般的做法可能有两种:一种是增加一个varchar字段,每个月份之间用一个特殊符号分隔保存,例如“1,2,3,11,12”;另一种方法是建立一个关系表,如下:

spots_id

int(景点ID)

month

int(适合月份,取值1-12)

第一种方法,查询极不方便,例如想查出适合2月份旅行的景点,就要使用like语句,效率极其低下。第二种方法,只适合景点属性较少的场合。如果景点还包含其它属性,例如“高山”、“草原”之类的分类属性,还有“美食”、“购物”等的主题属性,就要根据每个属性去建立一个关系表,扩展极其不便,查询的时候可能需要联表查询,也影响效率。

我们知道,PHP当中的错误级别常量,是根据二进制位特性而确定的一个个整数,可以简单的通过位运算定制PHP的错误报告。我们也可以将其应用到mysql当中,还是以上面的景点表为例,我们增加一个字段,其结构如下:

id

int(主键)

name

varchar(景点名)

province

int(省份)

city

int(城市)

month

int(适合旅行月份)

其建表语句为:

1

2

3

4

5

6

7

8

9

10

11

CREATE

TABLE

`

spots

`

(

`

id

`

int

(

10

)

unsigned

NOT

NULL

AUTO_INCREMENT

COMMENT

'景点ID'

,

`

name

`

varchar

(

50

)

NOT

NULL

COMMENT

'景点名称'

,

`

province

`

int

(

5

)

unsigned

NOT

NULL

COMMENT

'景点所在省份'

,

`

city

`

int

(

10

)

unsigned

NOT

NULL

COMMENT

'景点所属城市'

,

`

month

`

int

(

10

)

unsigned

NOT

NULL

DEFAULT

'0'

COMMENT

'适合旅行的月份'

,

PRIMARY

KEY

(

`

id

`

)

,

UNIQUE

KEY

`

name

`

(

`

name

`

)

,

KEY

`

location

`

(

`

province

`

,

`

city

`

)

)

ENGINE

=

InnoDB

DEFAULT

CHARSET

=

utf8

COMMENT

=

'景点信息表'

注意:在这里不能使用1-12的数字来表示月份,而是使用1,2,4,8,16,32,64,128,512,1024,2048,4096来表示。

以下为使用技巧:

1. 当我们需要查询某个月份的景点时,例如查询3月份的景点,可使用以下语句:

1

SELECT *

FROM

`

spots

`

WHERE

`

month

`

&

4

=

4

2. 当设置某个景点适合某个月份时,例如设置4325的景点适合2月份,可使用下面的语句:

1

UPDATE

`

spots

`

SET

`

month

`

=

`

month

`

|

2

WHERE

`

id

`

=

4325

3. 当取消设置某个景点的月份时,可使用下面的语句:

1

UPDATE

`

spots

`

SET

`

month

`

=

`

month

`

^

2

WHERE

`

id

`

=

4325

4. 查询同时适合多个月份的数据,例如需要查询设置了11,12,1月份的景点,将其三个月份对应的数值加起来,结果为6146,然后使用这个数值进行查询:

1

SELECT *

FROM

`

spots

`

WHERE

`

month

`

&

6146

=

614

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值