EC-CUBE 2系用の軽量データベースマイグレーションツール
- フル抽象化: 1つのマイグレーションファイルで MySQL, PostgreSQL, SQLite3 に対応
- 軽量: 依存は
symfony/consoleのみ - EC-CUBE 2 統合: SC_Query をそのまま使用
- CLI ツール: ec-cube2/cli と統合
composer require --dev nobuhiko/ec-cube2-migrationec-cube2/cli 経由でコマンドを実行します:
# マイグレーションの作成
php data/vendor/bin/eccube migrate:create CreateLoginAttemptTable
# 未実行のマイグレーションを全て実行
php data/vendor/bin/eccube migrate
# ステータス確認
php data/vendor/bin/eccube migrate:status
# ロールバック(1つ戻す)
php data/vendor/bin/eccube migrate:rollback
# ロールバック(3つ戻す)
php data/vendor/bin/eccube migrate:rollback --steps=3生成されるファイル: data/migrations/Version20260130123456_CreateLoginAttemptTable.php
<?php
use Eccube2\Migration\Migration;
use Eccube2\Migration\Schema\Table;
class Version20260130000001_CreateLoginAttemptTable extends Migration
{
public function up(): void
{
$this->create('dtb_login_attempt', function (Table $table) {
// serial() は自動的に login_attempt_id を PRIMARY KEY として作成
$table->serial();
$table->text('login_id')->notNull();
$table->text('ip_address')->nullable();
$table->smallint('result')->notNull();
$table->timestamp('create_date')->default('CURRENT_TIMESTAMP');
$table->index(['login_id', 'create_date']);
});
}
public function down(): void
{
$this->drop('dtb_login_attempt');
}
}public function up(): void
{
$this->table('dtb_customer', function (Table $table) {
// カラム追加
$table->addColumn('reset_token', 'text')->nullable();
$table->addColumn('reset_token_expire', 'timestamp')->nullable();
// インデックス追加
$table->addIndex(['reset_token']);
});
}
public function down(): void
{
$this->table('dtb_customer', function (Table $table) {
$table->dropIndex('idx_dtb_customer_reset_token');
$table->dropColumn('reset_token_expire');
$table->dropColumn('reset_token');
});
}public function up(): void
{
// 全DBで同じSQL
$this->sql("UPDATE dtb_baseinfo SET shop_name = 'New Name'");
// DB別に異なるSQL
$this->sql(
"SELECT DATE_ADD(NOW(), INTERVAL 1 DAY)", // MySQL
"SELECT NOW() + INTERVAL '1 day'", // PostgreSQL
"SELECT datetime('now', '+1 day')" // SQLite
);
}serial() はテーブル名から自動的にカラム名を決定します:
$this->create('dtb_customer', function (Table $table) {
$table->serial(); // customer_id が自動作成される
});
$this->create('dtb_login_attempt', function (Table $table) {
$table->serial(); // login_attempt_id が自動作成される
});命名規則: dtb_xxx → xxx_id, mtb_xxx → xxx_id
| 抽象型 | MySQL | PostgreSQL | SQLite |
|---|---|---|---|
serial() |
INT AUTO_INCREMENT + _seq テーブル | SERIAL + SEQUENCE | INTEGER PRIMARY KEY + _seq テーブル |
integer() |
INT | INTEGER | INTEGER |
smallint() |
SMALLINT | SMALLINT | INTEGER |
bigint() |
BIGINT | BIGINT | INTEGER |
text() |
TEXT | TEXT | TEXT |
string($n) |
VARCHAR(n) | VARCHAR(n) | TEXT |
decimal($p,$s) |
DECIMAL(p,s) | NUMERIC(p,s) | REAL |
timestamp() |
DATETIME | TIMESTAMP | TEXT |
boolean() |
SMALLINT | SMALLINT | INTEGER |
blob() |
BLOB | BYTEA | BLOB |
$table->text('name')
->notNull() // NOT NULL
->nullable() // NULL許可(デフォルト)
->default('value'); // デフォルト値
// 主キーは serial() で自動設定されます
$table->serial(); // 自動的に PRIMARY KEY$table->index(['column']); // 通常のインデックス
$table->unique(['column']); // ユニークインデックス
$table->index(['col1', 'col2']); // 複合インデックスMySQLではTEXT型カラムにインデックスを貼る場合、プレフィックス長が必要です。 このツールでは自動的に255が付与されます:
$table->text('memo');
$table->index(['memo']); // MySQL: CREATE INDEX ... ON ... (memo(255))明示的に長さを指定することも可能です:
$table->index(['memo(100)']); // memo(100) を使用LGPL-3.0-or-later