当我们在设计数据库的数据表时,经常会遇到一对多的数据结构,如新闻的tag等,比如我们在设计数据表的时候,就碰到了这个问题,
当时涉及楼盘数据表(house)物业性质、楼盘的装修性质等情况的时候,因为一个楼盘可能会涉及多个物业性质,而且物业性质的数量并不是很多。为了便于搜索,如果把所有物业性质的ID用分隔符组合成一个字符串肯定不符合要求。所以一般都是单独使用一个表来存储他们的对应关系,每次修改的时候,还必须先清除所有的对应数据,然后重新插入,非常麻烦,为了保证数据的一致性,还必须用事务。很显然,对于关联数据种类很少的情况下,这两种方法都不好。
在linux里,读写运行权限用421来表示,这就是一个典型的一对多的场景,比如用7就可以表示同时拥有3种权限,7表示读写权限。
//住宅物业类型,数据存储的是值
$dict['house']['hometype'] = array(
1 => "普通住宅",
2 => "公寓",
3 => "别墅",
4 => "写字楼",
5 => "经济适用房",
6 => "Townhouse",
7 => "酒店式公寓",
8 => "商铺",
9 => "商住",
10 => "建筑综合体",
11 => "两限房",
12 => "自住型商品房"
);
如果一个楼盘存在多个物业类型,那么,假如一个楼盘属于普通住宅和别墅,则加起来数字为2^1+2^3 =10 .如果属于普通住宅,别墅,商铺,则为2^1+2^3+2^8=258 .
我们如果要查询普通住宅,则可以:
SELECT site,hid,name,hometype FROM `house` WHERE `hometype` & 2 = 2
如果我们要查既属于普通住宅,又属于别墅,则sql语句为
SELECT site,hid,name,hometype FROM `house` WHERE `hometype` & 10 = 10
假如我们要给第3条记录添加经济适用房,则sql语句为
UPDATE `house` SET `hometype` = `hometype` | 32 WHERE `site` = 'bj' and hid = 3
假如我们要给第3条记录删除普通住宅,则sql语句为
UPDATE `house` SET `hometype` = `hometype` ^ 2 WHERE `site` = 'bj' and hid = 3