はじめに
今回、SQLiteからMySQLへの移行作業が発生しました。
移行作業にて、Seederを使い、一括でデータを移行するようにしたいと思います。
Seederの役割
1.データの初期化:
*データベースに初期データを投入するために使用されます。
*これにより、開発環境やテスト環境で必要なデータを簡単に準備できます。
2.テストデータの生成
*テストを行う際に必要なデータを自動的に生成することで、手動でデータを入力する手間を省きます。
3.データの一貫性
*一貫したデータセットを提供することで、テスト結果の信頼性を高めます。
Seederの主な書き方
例えばuserテーブルに初期のアカウントを作成する方法
php artisan make:seeder UserSeeder
Seederに以下のコードを記載
use App\Models\User;
User::truncate();
use Illuminate\Support\Facades\Hash;
$user = [
'email' => 'test@example.com',
'password' => Hash::make('password'), // パスワードをハッシュ化
'name' => 'userName',
];
User::create($user);
以下でSeederを実行
php artisan db:seed --class=UserSeeder;
これでuserテーブルに初期データが投入されました!!
SQLiteからMySQLへの移行用作成
本題のSeederをここで作成します!
今回はuserテーブルにある50万件のデータを移行します。
まずはconfigにSQLite、MySQLの情報をそれぞれ記載します。
'sqlite' => [
'driver' => 'sqlite',
... その他必要な設定記載
],
'mysql' => [
'driver' => 'mysql',
... その他必要な設定記載
],
次にSeederに以下コードを記載
use Illuminate\Support\Facades\DB;
DB::connection('mysql')->table('user')->truncate() // MySQLのuserテーブルをきれいにする
$bacthSize = 1000;
$offset = 0; // メモリ不足にしないために設定
while (true) {
$records = DB::connection('sqlite')->table('user')->offset($offset)->limit($batchSize)->get(); // sqliteのuserテーブルの情報を取得
if (empty($records)){
break;
}
$records = array_map(function ($user) {
$user = (array) $user;
return $user;
}, $records);
DB::connection('mysql')->table('user')->insert($records); // mysqlにバルクインサート
$offset += $batchSize;
}
バルクインサートを使用することも大切です。
実行速度に明らかな差が出ました。
バルクインサート未使用時:2,927,279ms
バルクインサート使用時:357,306ms
以上Seederを活用して、SQLiteからMySQLへのデータ移行Seederを作成してみました。
Seederはうまく活用するととても便利なものなので、随時活用していきたいと思います。