使用mysql的XML Functions让mysql schema free

简介: schema free 是mongodb里的一个重要的特性,很适合业务系统对某些非重点字段的维护,但是mongodb在运维上比mysql代价高,所以DBA也不会推荐使用。一般业务系统都默认使用成熟而又稳定的mysql。 但是,如何在mysql上实现schema free呢? # 横纵表方案 业务系统最常见的是横纵表方案 横表存储主要字段(用于查询、排序的字段) 纵表用 key-v
+关注继续查看

schema free 是mongodb里的一个重要的特性,很适合业务系统对某些非重点字段的维护,但是mongodb在运维上比mysql代价高,所以DBA也不会推荐使用。一般业务系统都默认使用成熟而又稳定的mysql。

但是,如何在mysql上实现schema free呢?

横纵表方案

业务系统最常见的是横纵表方案
横表存储主要字段(用于查询、排序的字段)
纵表用 key-value的形式存储非主要字段

而当业务需要获取一个实体时,需要在业务代码中这样处理

1.查询主表
select * from main_table where id=?

2.查询纵表
select key,value from vertical_table where obj_id=?

3.然后将这个kv结果集合塞回到实体中,然后返回

这样做当然可以满足要求,但是,逻辑的复杂度增加了,不但是查询,新建、更新、删除都需要操作2张表去完成。

XML Functions方案

当我看到了mysql的XML Functions后,突然感到世界打开了一扇新的窗,完全可以通过它来实现schema free。

XML Functions 的两个函数

Name Description
ExtractValue() Extracts a value from an XML string using XPath notation
UpdateXML() Return replaced XML fragment

用法

SELECT ExtractValue(memo, '/e') AS val1 FROM table1

这样可以查询table1表中的memo字段里中间的内容

update table1 set memo=UpdateXML(memo, '/e', '<e>fff</e>') 

可以更新table1 表中memo字段中的中间的内容为fff

我们需要做的,只需要纵表的表中增加一个大字段(varchar(1000)?大小自己预估),然后在这个大字段存储非主要信息

能再简单一点吗?

事情到这里是不是完成了呢?
写这样繁琐的sql是不是有点复杂啊?

于是我写了一个myibatis的拦截器,封装的xml的操作,让使用方感觉是在操作横表一样去操作大字段

比如:
id,title 和横表字段,大字段是memo,author是xml节点

Select

查询时只要输入sql

select id,title,_memo_author from tb

就可以完成查询,当然,在拦截器中将它转换成了

select id,title,ExtractValue(memo, '/author')from tb

通过myibatis的orm可以将大字段中的节点直接映射到对象属性上

Insert

insert操作也一样

insert into tb (id,title,_memo_author) values(1,'interstellar','buming.pl')

Update

update tb set id=1,title='interstellar',_memo_author='buming.pl'

author节点如果不存在,会在xml中新加,如果存在,会修改

下面这个是jar包

<dependency>
  <groupId>com.taobao</groupId>
  <artifactId>interstellar</artifactId>
  <version>1.1.0</version>
</dependency>

只需要在myibatis拦截器列表中增加拦截器

<property name="plugins">
    <list>
                <bean class="com.taobao.interstellar.InterstellarInterceptor">
                    <property name="properties">
                       <!-- memo:纵表大字段,defaultPrefix:前缀,defaultSuffix:后缀 -->
                        <value>
                            defaultColumn=memo
                            defaultPrefix=_
                            defaultSuffix=_
                        </value>
                    </property>
                </bean>
    </list>
</property>

更新列表

1.1.0

1、拦截器不作用在prepare阶段,改到 Executor 接口
2、sql解析在第一次注册为sqlmap,以后直接调用
3、对象不在需要memo属性,通过cglib动态添加
4、加入 处理特殊字符

1.0.3

修复了如果更新字段为空时,更新不成功bug 

参考资料:

XML Functions 的文档 http://dev.mysql.com/doc/refman/5.1/en/xml-functions.html

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
存储 缓存 关系型数据库
图解MySQL系列(4)-Buffer Pool中的free链表
Buffer Pool中有N多缓存页,每个缓存页还有个描述信息。DB启动后,按BP大小向os申请一块内存区域,作为BP的内存区域。 当内存区域申请完后,DB按默认缓存页及对应描述信息快,在BP中划出一块块内存,当DB把BP划分完后
48 0
|
10月前
|
XML 数据格式 开发者
使用 Schema 的 sax 方式操作 xml(二)| 学习笔记
快速学习使用 Schema 的 sax 方式操作 xml。
52 0
使用 Schema 的 sax 方式操作 xml(二)| 学习笔记
|
XML JavaScript Java
Java学习路线-45:XML快速入门(1)- XML、DTD、JAXP、Schema
Java学习路线-45:XML快速入门(1)- XML、DTD、JAXP、Schema
Java学习路线-45:XML快速入门(1)- XML、DTD、JAXP、Schema
|
XML Dubbo Java
阿里一面如何实现Spring的XML schema 扩展
阿里一面如何实现Spring的XML schema 扩展
119 0
|
XML 存储 JavaScript
Java学习路线-45:XML快速入门(1)- XML、DTD、JAXP、Schema
Java学习路线-45:XML快速入门(1)- XML、DTD、JAXP、Schema
166 0
|
XML Java 数据格式
推荐文章
更多