使用mysql的XML Functions让mysql schema free

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、加入<![CDATA[ ]]>处理特殊字符

1.0.3

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

参考资料:

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

时间: 2024-11-02 21:50:41

使用mysql的XML Functions让mysql schema free的相关文章

MySQL易学易用之MYSQL不为人知的特性_Mysql

本文将为你介绍这些不为人知的特性. 以XML格式查看查询结果 通过使用传统-xml 选项调用MySQL命令行客户程序,你可以以XML格式(而不是传统的列表形式)来查看MySQL查询结果.如果你打算将查询输出与其它程序集成在一起,这一技巧非常有用,这里是一个例子: 表A shell> mysql --xml mysql> SELECT * FROM test.stories; 1This is a test2005-07-28 00:14:57 2This is the second test2

【MySQL】如何构建高性能MySQL系统

一 简介     最近在压测新的存储,正好把工作过程中积累的对高性能MySQL相关的知识体系构建起来,做成思维导图的方式.总结乃一家之言,有不妥之处,望给位读者朋友指正. 二 思维导图    构建高性能MySQL系统涵盖从单机 硬件,os ,文件系统,内存,到MySQL 本身的配置,以及schema 设计,索引设计 ,再到数据库架构上的水平和垂直拓展.   说明     1 IO相关的优化可能还不完整,以后会逐步完善.     2 关于数据库系统水平和垂直拆分是一个比较大的命题,这里略过,每个公

MySQL中文参考手册---安装MySQL

安装MySQL 假设你把所有必须的源码或者包都放在了/tmp下.如果你下载的是RPM包的话,那比较简单:如果你下载的是二进制包(你没有rpm程序或者你想自定义的话),那么会稍微麻烦一点. RPM包安装 你必须成为root用户才能使用rpm安装程序,以下是安装过程: $ cd /tmp $ su # rpm -Uvh MySQL*(安装和MySQL相关的所有包) 这将安装你下载的所有3个MySQL包.如果你的系统是RedHat Linux的话,建议使用RPM安装方式,因为所有的工作都由rpm程序帮

MySQL中文参考手册6(MySQL与标准的兼容性) 对ANSI SQL92扩充

mysql|标准|参考|参考手册|中文 MySQL中文参考手册6(MySQL与标准的兼容性)转载 译者:晏子 [返回][转发] q译者:晏子 (clyan@sohu.com)主页:http://linuxdb.yeah.net 5 MySQL与标准的兼容性?5.1   MySQL对ANSI SQL92扩充MySQL包含了一些可能在其他SQL数据库找不到的扩充.要注意如果你使用他们,你的代码将不与其他SQL服务器兼容.在一些情况下,你可以编写包括MySQL扩展的代码,但是仍然是可移植的,通过使用/

MySQL中文参考手册7(MySQL 存取权限系统) grant 设置密码 password

mysql|word|参考|参考手册|中文 MySQL中文参考手册7(MySQL 存取权限系统)转载 译者:晏子 [返回][转发] 译者:晏子 (clyan@sohu.com)主页:http://linuxdb.yeah.net6 MySQL 存取权限系统MySQL有一个先进但非标准的安全/权限系统.本节描述它的工作原理.  6.1 权限系统做什么MySQL权限系统的主要功能是证实连接到一台给定主机的一个用户,并且赋予该用户在一个数据库上select. insert.update和delete的

MySQL小技巧:忘记MySQL密码也不怕

1. 先杀掉mysqld的进程: 2. 使用skip-grant-tables这个选项启动MySQL: 3. 登录修改密码: 4. 关掉MySQL 5. 启动MySQL

Mysql JDBC驱动版本与Mysql版本的对应问题

Connector/J 5.1 支持Mysql 4.1.Mysql 5.0.Mysql 5.1.Mysql 6.0 alpha这些版本. Connector/J 5.0 支持MySQL 4.1.MySQL 5.0 servers.distributed transaction (XA). Connector/J 3.1 支持MySQL 4.1.MySQL 5.0 servers.MySQL 5.0 except distributed transaction (XA) support. Conn

XtraBackup出现 Can&#039;t connect to local MySQL server through socket &#039;/tmp/mysql.sock&#039;

Xtrabackup做备份时遇到下面错误信息MySQL server: Can't connect to local MySQL server through socket '/tmp/mysql.so'(2)   [root@MySQL-DB ~]# innobackupex --defaults-file=/usr/my.cnf --user=root --password=password  /mnt/resource/mysql_backup 160322 22:28:43 innoba

利用Navicat for MySQL工具备份、还原MySQL数据库

我们常规的备份还原网站数据库会采用直接phpMyAdmin导出和导入,或者较为推荐的采用mysqldump命令模式.这不在之前几天看到有网友讨论使用Navicat for MySQL工具进行备份和还原数据库,看到这个工具的信息量还是蛮大的,应该还算用的比较多.   Navicat for MySQL工具的好处就是可视化,我们可以直接在软件界面中进行备份.还原.查询管理等,甚至可以设置定时备份任务.因为老左之前还不认识这个软件,所以更谈不上使用经验,对于基本的备份还原数据库,以及界面的认识,我准备