2013-03-27
シェルスクリプトとかユニケージとかフラットファイルとDBとか
こんばんはこんばんは。
僕のこの blog は github pages を使っています。ですので、blog 記事書くだけで、github のアクティビティ増えて、なんか「オープンソース活動に貢献してる」風に見えてかっちょいいので、今日も記事を書いてみようと思います。トップ記事がいつまでもアレなのもどうかと思いますしね。(ミルキィホームズのベストアルバムはホントにお勧めなので、みんな買ってね!)
この記事読んで、思ったこととかそんな感じの話です。
ユニケージ開発手法、なんかよく分からないんで、よく分からないからカジュアルにこんな感じでつぶやいてみたんですが。。。
うーん、コレどうなんだろ。こういうので十分な環境はあるのだろうけど、業務拡大してある一定の規模超えたら死にそう。 / “シェルスクリプトでビッグデータ処理~ユニケージ開発手法とは~(1/4):企業のIT・経営・ビジネスをつなぐ情報…” htn.to/Tu3sQe
— tsucchi(@tsucchi) 2013年3月27日
そしたら、
会長@友の会 :~$ echo これは逆で、会社で扱う案件の多くは、DBがぐちゃぐちゃになったのをファイルシステムにデータを整理する仕事です。 > @tsucchi
— 【シェル芸】USP友の会【演芸場】さん (@usptomo) 2013年3月27日
まあこんな感じで、USP の方からリプいただいたのですが、ちょうど昼飯やら打ち合わせやらで長いこと席外してたりしたし、ちゃんとした僕の意見を書くには twitter はしんどいなー、と思ったので記事書いてみた次第です。
まずはじめに、僕の立場的な話をすると、僕はシェルスクリプトは結構書きます。まあインフラあつかったりしますので当然です。DB はいろいろ高説たれてる気がするけど、実はあんま好きじゃなかったりして、サーバ側のセットアップだるいし、ドライバのインストールしてアレコレしてってのもだるいので、データ構造シンプルなら CSV とか TSV でいいじゃん、とか思ってたりして、実際小規模なシステムでは結構使います。
あと Software Design で、USP の方がシェルスクリプトの良記事を書いてるのも拝見してますので、ユーザ騙して変な手法を勧めてるんじゃなくて、ちゃんとしたシェルスクリプトを書いたり書かせたりしてるのであろう、ってのも一応分かってるつもりです。
その上であえて書かなきゃいけないかな、と思うのは、コレ、ちょっと間違うとあっという間に不幸になりそうだなー、と思ったからです。
まず、300万件5秒って、普通ですよね?遅くはない、というかシェルにしては驚異的な速さですけど、べつに DB + プログラミング言語 でやっても同じオーダーはでると思います。コマンドをパイプでつなげると勝手にマルチコア使えていい、ってのはまあそうだけど、シェル自体の起動が遅いっていうペナルティあるし、処理が遅いときに fork する/thread 使う くらいは僕でもやるので、心ある開発者なら誰でもやると思うんで、正直あんまり差は出ないんじゃないかな、と思います。
で、いちばんまずいと思うのは、
http://enterprisezine.jp/article/detail/4579
join1 key=2 GENKA HANBAI | # 販売データと商品原価ファイルを結合
join1 key=2 BUMON - | # さらに商品部門ファイルを結合
lcalc '$3,$6,$7,$7-$4*$6' | # 部門、売数、売上、粗利を計算
msort -p4 key=1 | # 部門コードでソート
sm2 1 1 2 4 | # 部門単位に、売数、売上、粗利を集計
sm5 1 1 2 5 | # 部門全合計行を付加
lcalc '$0,100*$5/$4' | # 粗利率を計算
marume 6.1 | # 粗利率を小数点1桁に四捨五入
cjoin2 key=1 BUMON_NAME | # 部門名称を付加
divsen 3 4 5 | # 売数、売上、粗利を1000単位にする
divsen 4 5 | # 売上、粗利については100万単位にする
wexcel a1 ExcelBook.xls - > Result.xls # エクセルシートにデータをはめ込む
コレ、読めねーよw。なんだよ、lcalc ‘$3,$6,$7,$7-$4*$6’って、意味わかんねーよ。売上と粗利を入れ替えて計算ミスるとか普通にやっちゃいそう、ってか自分なら絶対やらかす。なので、ファイルの要素が 10個越えたら破綻確定な気がする、ってか僕ならお手上げ。
あと、数百万件のテーブル同士を結合したとき、この join1 は大丈夫なの?ってか、 join1 が大丈夫だとしても、開発者が速いコマンド使わずに JOIN 相当の処理するとえらいことになりそうだけど、大丈夫なのかな?(まあこの問題は DB でインデックス貼り忘れた場合にも起こるけど、DB はスローログとか各種ツールがあるから、検出は容易だと思う)
https://twitter.com/usptomo/status/316763133408575489
これは逆で、会社で扱う案件の多くは、DBがぐちゃぐちゃになったのをファイルシステムにデータを整理する仕事です。
まあこれも分かります。僕も「ユーザが作った Excel とか Access とか桐とかの謎システムで前任者逃亡してメンテ不能で死亡」みたいなのをいくつか見聞きしてますから。そういうシステムをなんとかしなきゃいけない、ってのはそうで、大事なことですよね。
でも、DB がぐちゃぐちゃだから、ファイルにすれば整理できるってホント?整理するんなら、ちゃんとした、綺麗に設計されて正規化された DB にしたほうがいいんじゃね?なぜそこであえてファイル?ってのは思います。
たとえば、僕が今取り扱ってるシステムですと、DB のテーブルが数百くらいで、大きなテーブルだと100万件とか1000万件とかのデータ入っていて、カラムは数えたことないけど、まあ多くて数十くらいかな?僕はコレ、中規模のシステムだと認識してるんだけど、このくらいのシステムが破綻してぐちゃぐちゃになったとして、ファイルに置き換えて、ちゃんと取り扱えるの? DB だと、外部キー(まあ僕は物理的な外部キーあんま貼らないので、論理的な外部キーっていうのかな)で、テーブル間の連携を表現できるけど、「GENKA の 1 と HANBAI の 2で結合」みたいな連携はどうやって表現するの?これ、テーブル数百あっても破綻せずできるの?あと、100万件のファイルでなんかミスったとき、データメンテどうやるの?できるの?
と、まあ疑問ばっかりなのです。
テーブル、というか、テーブルに相当するモノが、10個以下だと、僕もファイルでやるか、SQLite つかうか、DBMS セットアップするか迷います。でも、20越えたら DBMS セットアップするかな。1テーブルでも、件数多かったり、カラム数が多かったり、排他がめんどい場合は SQLite か DBMS 使うかな。
と僕の場合、こんな感じです。小規模ならたしかにファイルとシェルでやることもあります。でも、データの件数や種類が多かったら、DB + プログラミング言語使うのが普通だし、正しいんじゃないかな、と思います。
なんでもかんでもシェルとファイルでできて、「やすく、はやく」ってのはどうなのよ?って思うし、それでユーザが不幸にならなきゃいいんだけど、大丈夫なの?って思ったのでした。
あ、この手法が一番きっちりハマりそうなユースケースも知ってます。「汎用機のバッチで、シーケンシャルファイルがメインのユーザ」ですね。素直にトランスレートするだけだし、絶対速くなります。まあ汎用機でもコピー句あるんで、カラム名相当の情報を失っちゃうけどいいのかな?ってのは思いますけど。