schema free 是mongodb裡的一個重要的特性,很适合業務系統對某些非重點字段的維護,但是mongodb在運維上比mysql代價高,是以dba也不會推薦使用。一般業務系統都預設使用成熟而又穩定的mysql。
但是,<b>如何在mysql上實作schema free呢?</b>
業務系統最常見的是橫縱表方案
橫表存儲主要字段(用于查詢、排序的字段)
縱表用 key-value的形式存儲非主要字段
而當業務需要擷取一個實體時,需要在業務代碼中這樣處理
1.查詢主表
select * from main_table where id=?
2.查詢縱表
select key,value from vertical_table where obj_id=?
3.然後将這個kv結果集合塞回到實體中,然後傳回
這樣做當然可以滿足要求,但是,邏輯的複雜度增加了,不但是查詢,建立、更新、删除都需要操作2張表去完成。
當我看到了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
這樣可以查詢table1表中的memo字段裡中間的内容
可以更新table1 表中memo字段中的中間的内容為fff
我們需要做的,隻需要縱表的表中增加一個大字段(varchar(1000)?大小自己預估),然後在這個大字段存儲非主要資訊
事情到這裡是不是完成了呢?
寫這樣繁瑣的sql是不是有點複雜啊?
于是我寫了一個myibatis的攔截器,封裝的xml的操作,讓使用方感覺是在<b>操作橫表一樣去操作大字段</b>
比如:
id,title 和橫表字段,大字段是memo,author是xml節點
查詢時隻要輸入sql
就可以完成查詢,當然,在攔截器中将它轉換成了
通過myibatis的orm可以将大字段中的節點直接映射到對象屬性上
insert操作也一樣
author節點如果不存在,會在xml中新加,如果存在,會修改
下面這個是jar包
隻需要在myibatis攔截器清單中增加攔截器
1、攔截器不作用在prepare階段,改到 executor 接口
2、sql解析在第一次注冊為sqlmap,以後直接調用
3、對象不在需要memo屬性,通過cglib動态添加
4、加入 處理特殊字元
修複了如果更新字段為空時,更新不成功bug