Go语言的MySQL库

jopen 10年前

先介绍一下这个库的由来。

之前在项目中用的MySQL库是从vitess项目里抠出来用的,当初项目刚开始的时候Go才刚正式发布,没太多选择,当时比较不放心用Go重新封 装MySQL通讯协议的库,感觉很容易有BUG,并且代码量很大,一旦出问题自己很难填坑,当时对MySQL的API以及CGO都不了解,也没有太多时间 边看文档边封装,正好朋友推荐了vitess里面用CGO包装的MySQL库,跟纯用Go实现的MySQL库对比了一下,首先是代码非常少(容易驾驭), 其次是加载数据的性能对比中,比纯用Go的库速度快了不少,于是就愉快的决定用它了。再后来因为项目需要,组里的兄弟往里面加了prepare语句的支 持,但是因为项目只用到非查询语句,所以prepare语句也就没支持结果集的返回。

随着自己对CGO和MySQL API的深入了解,发现最初用的vitess库的CGO用法不是很合理,其中CGO调用很琐碎,就像没有调用代价一样,但实际上CGO调用是要比普通函数 调用开销大很多的,其次是MySQL API有要求在不同线程中使用前要先调用mysql_thread_init函数初始化一下,而CGO的特性是每次调用不一定在固定的线程中执行,所以变 成每次CGO调用MySQL API前都要先执行mysql_thread_init,后来我跑去github上看新版vitess的代码,发现他们已经把这两个问题都改善了,首先是 把多次CGO调用包装成一个C函数一次调用,其次是在每个包装好的C函数开头都会调用mysql_thread_init。

于是我就重新把新版vitess库里面的代码抽取出来,再加上之前项目里用到的prepare功能,新做了一个库。详见:http://github.com/funny/mysql

本想这样就好了,但是看着那API越看越别扭,于是上周末在机场等飞机时(延误了将近7个小时。。。)新开了一个库(坑),详见:http://github.com/funny/oursql

新的库(坑)把结果集抽象成了三种:Result(非查询)、DataTable(查询并取回本地)、DataReader(查询并返回游标),感觉API清晰很多,并且去掉了很多用不到的类型转换,代码很少继承关系很清楚,顿时觉得一切皆在掌控之中了。

后来想,prepare只支持非查询的话感觉很low啊,于是继续给自己挖坑(当时还不觉得),往里面加prepare语句的查询结果集返回。这个 坑一挖下去,整个人都要累觉不爱了,prepare的结果集返回原来跟普通语句执行的结果集返回相差非常大,从获取数据的流程到返回的数据类型,都相差很 多。

硬着头皮填了两天,终于算是填上了,结果集还是保持Result、DataTable、DataReader三种,从库的内部隐藏实现细节,调用者(你)就不用管我到底废了多少心机死了多少脑细胞了。

来自:http://1234n.com/?post/rw1w5v