基于关系数据库的纵表、横表及引擎设计(未完)
概念
其实数据库本没有这2个概念,这2个概念是从应用角度、逻辑角度出发诞生的。所谓常见的表都是横表,所以这里重点说下纵表,你就理解这2个概念了。
关系型数据库或者说传统的数据库,建立模型时都需要建立明确模型的属性,而这些属性是作为字段(field)存在的,但是在应用中我们经常面临一个问题就是对象的属性是不确定的,比如我们对客户的属性,我们随着研究关注地深入,需要关注的属性越来越多;再比如淘宝在做商品筛选时,不同的商品种类其属性往往是不同的。传统的解决方案是不停地增加字段,如果一个表的字段太多,则新增表,抽象一下就是表1、表2。。。以此类推。问题光是这样也就算了,这么多表的字段其实很多字段都是null,导致我们修改是需要大量判断,同时浪费了大量的存储空间。
基于这个需求,聪明的工程师抽象出来一个概念即纵表,典型的结构如下:
客户id 属性类型 属性值1 属性值2 属性值3
比如过去存储用户数据,我们可以这样定义字段:
user_id |
name |
sex |
age |
1 |
小明 |
男 |
12 |
换成纵表后:
user_id |
value_type |
value |
1 |
姓名 |
小明 |
1 |
性别 |
男 |
1 |
年纪 |
12 |
我这么解释,估计都懂了,当然它们也很容易转换,具体方法参考:http://blog.csdn.net/zhq651/article/details/52966912,这里不再赘述了。
在此,我认为还可能存在一种表叫二维表,即同时结合了横表和纵表,纵表中除了关键属性为,同时还有字段代表了该属性的属性,举个例子:
User_id |
Value_type |
Value |
真实性 |
权重 |
1 |
姓名 |
小明 |
1 |
2 |
1 |
性别 |
男 |
1 |
2 |
1 |
年纪 |
12 |
0.3 |
3 |
像这种二维码是无法转成一个横表的。
用途
以上链接博文中的这种转换是通过数据库实现的,大家很容易理解,但是如果使用较多或者系统较大时,我不太推荐。首先来讲,数据库是比较宝贵的资源,拿来做这种运算有些可惜且效率不高。其次,按照这种写法,每次不同的内容都还得进行重新编写sql,甚至在增加属性时也得修改sql,或者在外层循环做判断。总结一下,感觉存储、开发、使用效率是一种天然的矛盾体,不能兼得。但是不管你怎么设计纵表,大致的过程又差不多,怎么办?
所以我考虑单独抽象出来一个模块专门做这种转换,前端用户使用时看到的就是普通的横表,不再进行任何的循环,甚至有点像使用nosql一样的舒服,而这种转换由该模块完成,同时要求相关纵表设计只要遵守这种规范就可以去使用该模块。
设计引擎目标
实现过程