Advent Calendar 15日目 Perl/Ruby/Python 版 Native Driver ?
かじゅある! (挨拶)
や、それはもういいか。
昨日、 php の mysqlnd について書きましたが、
id:nihen さんから、
【Perl や Ruby でも Native Driver 俺が書いてやんよっていう猛者がいたら面白い】Perl=DBD::mysqlPP, Ruby=>Ruby/MySQL, Python=>oursql
http://b.hatena.ne.jp/nihen/20111214#bookmark-71994389
という反応をいただいたので調べてみました。
Perl - Net::MySQL
DBD::mysqlPP というのは DBI のバックエンドとして動くモジュールです。
DBD::mysqlPP の話 - tsucchiの日記 を見ると、紆余曲折があったようです。
ソースコードを覗いてみたところ、これ、このモジュールが直接やりとりしてる訳ではなくて、 Net::MySQL に全て委譲してました。Net::MySQL もメンテナは同じ方ですが。
んで、こっち見てみると、あぁ、確かに IO::Socket 使って、socket 繋いで直接やりとりしてる。
Ruby - Ruby/MySQL
MySQL/Ruby ではなく、 Ruby/MySQL。 紛らわしい……。
MySQL/Ruby のほうは libmysql を利用したものでした。
これもざっくりソースコード見てみましたが、確かに MySQL Server と直接やりとりしていますね。
そしてこれも、 Ruby 上でのやりとりになります。
Python - oursql
oursql in Launchpad こちらでしょうか。
ただこれは libmysql に依存しているように見えます。ドキュメントにも要件に MySQL C client libraries 入ってますし。 ソースコード見ても API を呼び出している感じ。
Python の C言語拡張は触ったこと無かったので、見落としているかも知れませんが。
余談ながら、oursql は Cython を利用していました。 Cython は、 "Python に似た言語で Python の C言語拡張を書く事が出来る仕組み" です。 そして、 PyPy は Cython の後継という事実を始めて知りました。セルフホスティング目指してるとは!
でもちょと違う
もちろん、他に依存しない Native な Client という意味では、Net::MySQL も Ruby/MySQL も同様なのですが、 mysqlnd とは少々異なるようです。
Graph1. MySQL プロトコル解析部分の違い
Graph.1 は、 その違いを模式的に表した図です。
左側が Net::MySQL Ruby/MySQL で、右側が mysqlnd。
octet が、 MySQL の理解する octet 列です。
LL Value と書いてあるのは、各言語の内部表現という意味です。 Perl ならSV、 Ruby なら VALUE、 PHP なら ZVAL ですね。
Traslation が、それぞれのモジュールの位置を表しています。
緑の矢印が MySQL プロトコルを表しています。
また、青い背景の枠が各言語が管理している部分を表しているので、この枠の境界でも変換が行われています。
mysqlnd が、変換ロスを抑えるように設計されているのが分かりますでしょうか。
とはいえ、実際にどっちが早いか、なんてのは一概には言えませんけどねー。