LoginSignup
13
13

More than 5 years have passed since last update.

MySQLにData::Generator::FromDDLで大量のダミーデータを入れる方法

Last updated at Posted at 2014-06-03

経緯

MySQLのチューニングのため、大量のデータを入れてパフォーマンスを計測する作業が必要となった。

Data::Generator::FromDDLというPerlライブラリがあるので、それを使ってダミーデータを入れることにした。 https://github.com/addsict/Data-Generator-FromDDL

手順

MySQLのmydbデータベースに、すでにcreate tableされているとする。まず、MySQLに付属しているmysqldumpというツールを使って、すでにmydbに作られたテーブルを再現してcreate tableするだけのSQL文であるDDLを取得する。

$ mysqldump -u katryo -p --no-data mydb > dump.sql

で、dump.sqlというDDLを生成する。

で、Data::Generator::FromDDLをシェルから扱えるdatagen_from_ddlを使って、

$ datagen_from_ddl --num=100000 dump.sql | mysql -u katryo -p mydb 

すると、MySQL内のmydbの各テーブルに、100000レコード/1テーブル のデータが入る。

8GBのMacBookAirで、26テーブルで100000レコードで実行すると30秒かかった。

Data::Generator::FromDDLの素晴らしさ

Data::Generator::FromDDLは、DDLをパースして自動的にダミーデータのinsert文を出力してくれる。

さきほどの例を、3レコード/1テーブルで行ってみよう。出力を見やすくするために --pretty のオプションもつけてみる。

$ datagen_from_ddl --num=3 --pretty dump.sql

をすると、以下のような文が出力される。ちなみに、レシピサイトを作っているとする。

INSERT IGNORE INTO `foodstuffs` (`foodstuff_id`,`name`,`created_at`) VALUES (1,'name1',-1429218243),(2,'name2',99576727),(3,'name3',-1565718941);
INSERT IGNORE INTO `request_ids` (`request_id`) VALUES (1),(2),(3);
INSERT IGNORE INTO `tags` (`tag_id`,`name`,`created_at`) VALUES (1,'name1',2542618628),(2,'name2',3291009850),(3,'name3',1095817358);
INSERT IGNORE INTO `users` (`user_id`,`nickname`,`family_name`,`given_name`,`email`,`salt_hashed_password`,`gender`,`created_at`,`updated_at`) VALUES (1,'nickname1','family_name1','given_name1','email1','salt_hashed_password1',-22,2261241673,2135291890),(2,'nickname2','family_name2','given_name2','email2','salt_hashed_password2',114,2162413120,440265079),

...(以下略)

こんな風に、create table文から、適当な値を入れてinsert文を作ってくれる。テーブル同士の関係、制約を守りながら大量のデータを入れるのに便利。

テーブルごとに入れるレコードの数を変えるとき

現実のアプリケーションでは、テーブルごとにレコード数はかなり異なる。なので、ダミーデータもテーブルごとの目的にあわせて、その量を変えるべきだ。Data::Generator::FromDDLにはその仕組みがある。

コマンドラインツールのdatagen_from_ddlではそこまで複雑な仕事をさせられないので、自分でスクリプトを書くといい。

dummy_into_mysql.pl
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use autodie;
use Data::Dumper;
use Data::Generator::FromDDL;

open my $fh, '<', $ARGV[0] or die "Could not open ddl: $!";
my $ddl = '';
foreach my $line (<$fh>) {
    $ddl .= $line;
}
close $fh;

my $generator = Data::Generator::FromDDL->new(
    {   ddl    => $ddl,
        parser => 'mysql',
    }
);

my $num = {
    all    => 1000000,
    tables => {
        followings => 5000000,
        likes => 20000000,
    }
};
$generator->generate($num);

こんな感じに、$ARGV[0]でddlファイル(mysqldump --no-dataで作ったもの)を指定するようなスクリプトを書いて、

$ perl dummy_into_mysql.pl dump.sql | mysql -u katryo -p mydb 

とすると、followingsには5000000件、likesには20000000件、それ以外には1000000件のレコードが入る。

13
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
13