การย้ายฐานข้อมูล
การย้ายฐานข้อมูลให้การเปลี่ยนแปลงแบบย้อนกลับที่ควบคุมเวอร์ชันได้กับสคีมาฐานข้อมูลของคุณ ช่วยให้มั่นใจถึงสถานะฐานข้อมูลที่สอดคล้องกันทั่วทั้งสภาพแวดล้อมการพัฒนา การจัดเตรียม และการใช้งานจริง
โครงสร้างการย้ายถิ่น
หัวข้อที่มีชื่อว่า “โครงสร้างการย้ายถิ่น”การตั้งชื่อไฟล์
หัวข้อที่มีชื่อว่า “การตั้งชื่อไฟล์”migrations/├── 001_create_articles_table.php├── 002_add_status_column.php├── 003_create_categories_table.php├── 004_add_indexes.php└── 005_add_foreign_keys.phpชั้นการย้ายถิ่นฐาน
หัวข้อที่มีชื่อว่า “ชั้นการย้ายถิ่นฐาน”<?phpdeclare(strict_types=1);
return new class { public function up(\XoopsDatabase $db): void { $table = $db->prefix('mymodule_articles');
$sql = "CREATE TABLE IF NOT EXISTS `{$table}` ( `id` VARCHAR(26) NOT NULL COMMENT 'ULID identifier', `title` VARCHAR(255) NOT NULL, `content` MEDIUMTEXT, `status` ENUM('draft', 'published', 'archived') DEFAULT 'draft', `author_id` INT UNSIGNED NOT NULL, `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_status` (`status`), KEY `idx_author` (`author_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci";
$db->queryF($sql); }
public function down(\XoopsDatabase $db): void { $table = $db->prefix('mymodule_articles'); $db->queryF("DROP TABLE IF EXISTS `{$table}`"); }};การดำเนินงานทั่วไป
หัวข้อที่มีชื่อว่า “การดำเนินงานทั่วไป”การเพิ่มคอลัมน์
หัวข้อที่มีชื่อว่า “การเพิ่มคอลัมน์”public function up(\XoopsDatabase $db): void{ $table = $db->prefix('mymodule_articles');
// Add single column $db->queryF("ALTER TABLE `{$table}` ADD COLUMN `views` INT UNSIGNED DEFAULT 0 AFTER `status`");
// Add multiple columns $db->queryF("ALTER TABLE `{$table}` ADD COLUMN `summary` TEXT AFTER `content`, ADD COLUMN `featured` TINYINT(1) DEFAULT 0 AFTER `views`");}
public function down(\XoopsDatabase $db): void{ $table = $db->prefix('mymodule_articles'); $db->queryF("ALTER TABLE `{$table}` DROP COLUMN `views`, DROP COLUMN `summary`, DROP COLUMN `featured`");}การแก้ไขคอลัมน์
หัวข้อที่มีชื่อว่า “การแก้ไขคอลัมน์”public function up(\XoopsDatabase $db): void{ $table = $db->prefix('mymodule_articles');
// Change column type $db->queryF("ALTER TABLE `{$table}` MODIFY COLUMN `title` VARCHAR(500) NOT NULL");
// Rename column $db->queryF("ALTER TABLE `{$table}` CHANGE `summary` `excerpt` TEXT");}การเพิ่มดัชนี
หัวข้อที่มีชื่อว่า “การเพิ่มดัชนี”public function up(\XoopsDatabase $db): void{ $table = $db->prefix('mymodule_articles');
// Single column index $db->queryF("CREATE INDEX `idx_created` ON `{$table}` (`created_at`)");
// Composite index $db->queryF("CREATE INDEX `idx_status_date` ON `{$table}` (`status`, `created_at`)");
// Unique index $db->queryF("CREATE UNIQUE INDEX `idx_slug` ON `{$table}` (`slug`)");
// Fulltext index $db->queryF("CREATE FULLTEXT INDEX `idx_search` ON `{$table}` (`title`, `content`)");}
public function down(\XoopsDatabase $db): void{ $table = $db->prefix('mymodule_articles'); $db->queryF("DROP INDEX `idx_created` ON `{$table}`"); $db->queryF("DROP INDEX `idx_status_date` ON `{$table}`"); $db->queryF("DROP INDEX `idx_slug` ON `{$table}`"); $db->queryF("DROP INDEX `idx_search` ON `{$table}`");}กุญแจต่างประเทศ
หัวข้อที่มีชื่อว่า “กุญแจต่างประเทศ”public function up(\XoopsDatabase $db): void{ $articles = $db->prefix('mymodule_articles'); $categories = $db->prefix('mymodule_categories');
$db->queryF("ALTER TABLE `{$articles}` ADD CONSTRAINT `fk_article_category` FOREIGN KEY (`category_id`) REFERENCES `{$categories}` (`id`) ON DELETE SET NULL ON UPDATE CASCADE");}
public function down(\XoopsDatabase $db): void{ $articles = $db->prefix('mymodule_articles'); $db->queryF("ALTER TABLE `{$articles}` DROP FOREIGN KEY `fk_article_category`");}นักวิ่งการย้ายถิ่นฐาน
หัวข้อที่มีชื่อว่า “นักวิ่งการย้ายถิ่นฐาน”กำลังดำเนินการย้ายข้อมูล
หัวข้อที่มีชื่อว่า “กำลังดำเนินการย้ายข้อมูล”function xoops_module_update_mymodule(\XoopsModule $module, $previousVersion){ $db = \XoopsDatabaseFactory::getDatabaseConnection(); $migrator = new MigrationRunner($db, $module->dirname());
try { $migrator->migrate(); return true; } catch (\Exception $e) { $module->setErrors($e->getMessage()); return false; }}คลาสนักวิ่งการย้ายถิ่นฐาน
หัวข้อที่มีชื่อว่า “คลาสนักวิ่งการย้ายถิ่นฐาน”class MigrationRunner{ private string $migrationsPath; private string $table;
public function __construct( private \XoopsDatabase $db, private string $moduleName ) { $this->migrationsPath = XOOPS_ROOT_PATH . "/modules/{$moduleName}/migrations"; $this->table = $db->prefix("{$moduleName}_migrations"); }
public function migrate(): void { $this->createMigrationsTable(); $executed = $this->getExecutedMigrations();
foreach ($this->getPendingMigrations($executed) as $file) { $this->runMigration($file); } }
private function runMigration(string $file): void { $migration = require $this->migrationsPath . '/' . $file; $migration->up($this->db);
$this->db->queryF( "INSERT INTO `{$this->table}` (migration, executed_at) VALUES (?, NOW())", [$file] ); }
public function rollback(int $steps = 1): void { $migrations = $this->getExecutedMigrations(); $toRollback = array_slice(array_reverse($migrations), 0, $steps);
foreach ($toRollback as $file) { $migration = require $this->migrationsPath . '/' . $file; $migration->down($this->db);
$this->db->queryF( "DELETE FROM `{$this->table}` WHERE migration = ?", [$file] ); } }}แนวทางปฏิบัติที่ดีที่สุด
หัวข้อที่มีชื่อว่า “แนวทางปฏิบัติที่ดีที่สุด”- การเปลี่ยนแปลงหนึ่งครั้งต่อการโยกย้าย - ให้ความสำคัญกับการโยกย้าย
- จดวิธีการไว้เสมอ - เปิดใช้งานการย้อนกลับ
- ทดสอบทั้งสองทิศทาง - ตรวจสอบ up() และ down()
- ใช้ธุรกรรม - สรุปการโยกย้ายที่ซับซ้อน
- อย่าแก้ไขการย้ายข้อมูลเก่า - สร้างใหม่แทน
- สำรองข้อมูลก่อนใช้งาน - โดยเฉพาะในการผลิต
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- ฐานข้อมูล-สคีมา - การออกแบบสคีมา
- การดำเนินการฐานข้อมูล - การดำเนินการค้นหา
- ../xoops_version.php - รายการโมดูล
- ../../07-XOOPS-4.0/XOOPS-4.0-สถาปัตยกรรม - สถาปัตยกรรมสมัยใหม่