2011年11月30日水曜日

シェルってなんじゃ?(mysqlに簡単ランダムデータ生成)

DBにランダムな大量データを入れ込みたいけれども、データの内容やテーブル同士の結合などあまり気にしなくて良い場合は、ちゃんとしたジェネレーターなどをインストールするよりもシェルでさくっと書いてしまいたい時があります。

ここではmysqlにシェルからINSERTし続けるシェルを書いてみたいと思います。

例として対象となるテーブルは以下のとおり

CREATE TABLE user (
 id int(11) NOT NULL AUTO_INCREMENT,
 name varchar(50) DEFAULT NULL,
 age int(11) DEFAULT NULL,
 description text,
 created_at datetime DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB

 ここで、idはオートインクリメント、created_atはNOW()を使用するのでいいとして、name, age, descriptionにランダムなデータを入れ込むためにランダム生成をします。


文字列のランダム

mkpasswdというパスワード生成用のランダム文字列の生成ツールで、expectパッケージに含まれています。
たとえば3文字以上の数字と5文字以上の大文字が必ず含まれる50文字のランダム文字列が生成するには以下のようにします
$ mkpasswd -l 50 -d 3 -C 5
kDVoDyxqwd5csu0bfuk8dpoygyhwwersqoazoycvehsovsMjqS


mkpasswdは厳密にランダムさを求めたり使用文字のルールを決めることができるので便利ですが、とても重いので大量に生成するには向かない場合があります。 ほかにもuuidgenというUUIDを作成するコマンドがあります。
これは全世界的に一意なIDを発行するためのツールです。
$ uuidgen
a62f9c8d-9d97-4b5d-a572-d83222837fc2


数値のランダム

数値をランダムに出力するにはexprが便利です。
たとえば1〜8までのランダム数値は以下のようにします。
$ expr 1 + $RANDOM % 8
3

これらをつかってランダムなデータをテーブルに入れるスクリプトを書いてみます。
mysqlへの投入はmysql -e "SQL文"で、コマンドから直にSQL実行できるので、それを利用します。


ランダムデータ生成スクリプト

insert_random.sh
#!/bin/sh

while ((1))
do
name=$(uuidgen | tr -d '-' | cut -c 1-10)
desc=$(mkpasswd -l 50 -s 0)
age=`expr 1 + $RANDOM % 1000`
mysql -u hoge_user cloudpack -phoge_pass -e "INSERT INTO user(name, age, description, created_at) VALUES('${name}', ${age}, '${desc}', NOW());"
echo -n "."
done;

exit 1


これを実行します。
$ sh ./insert_random.sh 
...............................................................................................................................................................................................................................................................................................................................................................................................

進捗がすすんでいるようです。
ちょっと別のターミナルセッションからデータを覗いてみます。

mysql> select * from user;
+----+------------+------+----------------------------------------------------+---------------------+
| id | name       | age  | description                                        | created_at          |
+----+------------+------+----------------------------------------------------+---------------------+
|  1 | 598d056309 |  896 | rkggeRoxaqvmhlcwhon2ordjhafdLoqdrs5ecaplouaqkccdfk | 2011-11-30 03:00:14 |
|  2 | 6ab7bf0029 |  487 | 8iOrolcltandneoxtsmwizx6shtreovoodulnmpjePdqgyrxxa | 2011-11-30 03:00:14 |
|  3 | c62df8dab5 |  464 | oxncixqdamctmeppmohmwkdayxzgw0rxRvwx3vbDhlyndqnlcv | 2011-11-30 03:00:14 |
|  4 | 63a9d01e41 |  609 | ilovfkcskrvdui2nHnumcfarlkn5iVaopabyymiafjiystbyvx | 2011-11-30 03:00:14 |
|  5 | e5abb35d2d |  677 | epkdylnwhlx9kophdOxcvcofqqheuljknsiivgon8cyovyAvaf | 2011-11-30 03:00:15 |
|  6 | 2888a4f6fd |  230 | ywqbCazysbakzweqfohli6oqhjuncohtyxplxp2Frcuhfacyqa | 2011-11-30 03:00:15 |

〜

| 2452 | 2b1e84b98d |  388 | kEheuvccvwusygulkfhig6qvnffxmnveahazmnaclcIbllcz5j | 2011-11-30 03:00:52 |
| 2453 | ea1ef37248 |   44 | feoeumwokgrvtypatzxfyfZg3ltvrnxwdEhzfveveykavitzl9 | 2011-11-30 03:00:52 |
| 2454 | 05a5341597 |  309 | chlpvjttq2axlvkrubjgubfdfhwzoatolbfddo6nqpgWgbkfPh | 2011-11-30 03:00:52 |
| 2455 | 8403fbafe9 |  655 | tdwi2egdtAucxroylarikvqdfhpxnwxeopqxtcufvqsix0Wekz | 2011-11-30 03:00:52 |
| 2456 | 471be293bc |  660 | lnKqpbueti3izbg1orceykiomjqocexezpkulqgkdhzFczyfze | 2011-11-30 03:00:52 |
| 2457 | 05628b4a7c |  180 | ueebrCqwn5brvjUqrkwcpg6qpjpkokkrtxvfczxjtcyqmrfpnf | 2011-11-30 03:00:52 |
| 2458 | 3688ea54b3 |   92 | wrpamv9QmycbccpuwqPnlsjdyiwcl5avyfgytdqllgtiljcwsc | 2011-11-30 03:00:52 |
+------+------------+------+----------------------------------------------------+---------------------+
2458 rows in set (0.01 sec)

おお、順調に投入されています。
このように、気軽に大量のデータをつくれ、また常にデータ投入が行われている状態にすることで開発の最初から負荷を気にすることもできます。
以上です。