mysql

MySQL Users Conference Japan 2007

in

MySQL Users Conference Japan2007

MySQL Users Conference Japan2007に行ってきました。少し早めに行ったら全然人がいなくて少しアセったけれど、Keynoteが始まってみれば会場はほぼ満員。

お目当ての「Performance Tuning and Benchmarks」のセッションは、特に目新しいTIPSの紹介というよりは、当たり前のことをちゃんとやりましょうよってことに尽きるかなぁ。

libmysqlclient.aのUniversal Binary化

今日は、自分用のアプリではなくて仕事用のアプリの作成で一日潰れた。(当たり前か....)そうです。遂に!自席にマックがやってきたんです。PowerMac G4(AGP)と今となってはプアなマシンですがメモリは1Gとたっぷりあるしなにしろ自由に使えるマックが自席にあるのはホントうれしいぃー。

で、早々Universal Binaryと格闘。MySQLサーバにアクセスするアプリケーションを作成しているのですが

libmysqlclient.a archive's cputype (18, architecture ppc) does not match cputype (7) 
 for specified -arch flag: i386 (can't load from it)

などど言われてReleaseモードでうまくリンクができません。

MySQL用makefileサンプル

かつて一緒に働いた友人に、先日書いた1400万行のデータをRubyで扱うと...?(C/C++でリベンジ編)はmakefileまで載せないと役に立たないよ!と言われたので参考までにあげて置きます。といっても大したことはなくて、mysql_configを使えば必要なパラメータを取得できます。

:
(省略)
:
MSQLROOT   = /usr/local/mysql
MSQLINC    = $(MSQLROOT)/include/mysql
CFG        =/usr/local/mysql/bin/mysql_config
MYSQLLIBDIR= $(MSQLROOT)/lib/mysql/
MYSQLLIBS  = `$(CFG) --libs`
CC         = g++
CFLAGS     =  -g -DDEBUG -DULTRA -I$(MYINC) \
              -I$(MSQLINC) -I. `$(CFG) --cflags`
LDFLAGS    = -L$(MYLIB) -L$(MYSQLLIBDIR)
MAKEFILE   = makefile
SHELL      = /bin/sh
$(PROGRAM): $(OBJS) $(MAKEFILE) $(MYLIB)/libmy.a
    $(CC) -o $(PROGRAM) $(LDFLAGS) $(OBJS) $(LIBS) $(COMLIBS) $(MYSQLLIBS)
main.o:$(SRC)/main.cpp
    $(CC) $(CFLAGS) -c $(SRC)/main.cpp
:
(省略)
:

そのままは使えませんが多少は面倒を省いてくれるかもしれません。というわけで、今年こそ多少なりとも人のお役に立つことを書いていきたいと思います。

1400万行のデータをRubyで扱うと...?(C/C++でリベンジ編)

1400万行のデータをRubyで扱うと...?で玉砕したのでここはC/C++で書いてみることにしました。C/C++の場合、使い捨ても業腹なので簡単なベースクラスを作成し派生クラスで対応することにします。ベースクラスでは今回必要なものだけを実装し、再利用するようなことがあれば逐次追加していくつもりです。(サンプルソースからはエラー処理を端折っています。)

static char* server_args[] = {
  "MySQLBase.cpp","--datadir=/usr/local/mysql/var","--key_buffer_size=32M"
};
static char* server_groups[] = {
  "embedded","server","this_program_SERVER",(char *)NULL 
};
class CMySQLBase {
protected:
  MYSQL*  m_db;
  MYSQL_RES* m_res;
public:
  CMySQLBase(void);
  virtual ~CMySQLBase(void);
  virtual int run(int argc,char* argv[]) = 0;
protected:
  int   init(void); // 初期化処理
  int   end(void);   // 終了処理
  bool  conn(const char* dbname); // コネクト処理
  bool  query(const char* query); // クエリ発行
  void  get_result(void); //結果の取得
  MYSQL_ROW get_row(void); //行の取得
  unsigned int get_field(void); //フィールド数の取得
};

このとき、それぞれのメソッドの実装は以下のとおり。

1400万行のデータをRubyで扱うと...?

in

仕事で

id,name,amount,date
:

のような構成のcsvファイルをMySQLのtable foo(id,category,name,price,value)とぶつけて

id,category,name,amount,price,date
:

に変換して出力する必要があったのでちょっとRubyでコードを書いてみました。cvsファイルはid列でソートされています。

require 'mysql'
require 'csv'

id  = nil
category = nil
price = nil
msql = Mysql::new('localhost','mysql','mypass','db')

CSV::Reader.create(File.open(ARGV[0],'r')).each { | row |
  if id != row[0] 
    id = row[0]
    result = msql.query("select * from foo where id = #{id}")
    if result.num_rows == 0
      puts "error! #{id}"
      break;
    end
    result.each do | var |
      category = var[0]
      price = var[1]
    end
  end
  puts "#{id},#{category},#{row[1]},#{row[3]},#{price},#{row[2]}"
}
msql.close();

いえ、動くんですよ。結果も欲しいものが得られました、テストでは。
ただ、本番のCSVファイル....14839193件もあったんですよ。いくら待って終わりませんです。計測無用。というわけで、玉砕しました。(しかも、来月から僕のDaily Workだってさ。マジ!?)

MySQLのインストール

in
install

データベースをインストールするには専用のユーザを作成しておくと、その後の運用が便利。

#>usergrp mysql
#>usradd mysql -g mysql
#>tar zxvf ./mysql-5.0.18.tar.gz -c /usr/local/src
#>cd /usr/local/src/mysql-5.0.18
#>./configure --with-extra-charsets=all --with-charset=utf8 \
   prefix=/usr/local/mysql
#>make
#>make install

configオプションはお好みで。個人的にはキャラクタセットはutf8をデフォルトにしたほうが悩みが少なくなると考えます。インストールディレクトリは指定したほうが何かと便利です。デフォルトだとincludeとlibがそれぞれ別ディレクトリにインストールされます。インストールしたら用意されている設定ファイルとスタートアップスクリプトのコピー。

コンテンツの配信