Migration คืออะไร
Migration คือการสร้าง versioning ของการทำงานกับฐานข้อมูล เช่น การสร้างตาราง การเพิ่ม field การลบ field เพื่อให้เห็น version ต่างๆ และทราบที่มาที่ไปได้
การ Migration จึงมีความสำคัญกับการพัฒนาระบบที่ทำงานเป็นทีมหลายๆ คน
รูปแบบของ Migration นั้นถูกนำมาใช้ให้เหมือนกับการ Coding ที่ต้องมีการเก็บ Versioning ของ Code เช่น Git โดยจะเห็นว่าประวัติของ Code นั้นมีที่มาที่ไปอย่างไร มีการแก้ไขตรงไหนบ้าง หรือ เพิ่มตรงไหนบ้าง จึงเป็นที่มาของ Migration นั่นเอง
ไฟล์ Migration นั้นจะมี Method หลักๆ อยู่ 2 Method คือ up() และ down() โดยทั้ง 2 Method นี้ทำหน้าที่ตรงกันข้ามกัน เช่น up() คือการสร้างตาราง down() คือการลบตาราง เป็นต้น
เริ่มใช้งาน Migration
ก่อนอื่นเมื่อติดตั้ง Yii Framework 2 เสร็จเรียบร้อยแล้วให้แก้ไขการเชื่อมต่อฐานข้อมูล จากนั้นเปิด CommandPrompt/Terminal แล้วพิมพ์คำสั่งในการสร้างตาราง migration ดังนี้
yii migrate
ก็จะได้ตาราง migration ในฐานข้อมูลเรียบร้อยแล้ว เพื่อเก็บ version ของการเรียกใช้งาน Migration file ต่างๆ
ที่เก็บไฟล์ Migration
ไฟล์ Migration จะถูกเก็บไว้ใน folder console/migrations
ชนิดฟิวด์แบบต่างๆ
ชนิดของฟิวด์แบบต่างๆ ที่ใช้ในการสร้าง
$this->primaryKey() //PRIMARy และ AUTO_INCREMENT
$this->string(255) //VARCHAR(255) 255 คือความยาว
$this->text() //ชนิด TEXT
$this->integer() //จำนวนเต็ม คือ INT
$this->timestamp() //แบบ TIMESTAMP
การสร้างไฟล์ Migration
สำหรับการสร้างไฟล์ migration นั้นเราจะใช้ commandPrompt/Terminal ในการพิมพ์คำสั่งในการสร้าง
การสร้างตาราง
การสร้างตารางจะใช้คำสั่งในการสร้างดังนี้
yii migrate/create create_table_name
ตามธรรมเนียมของ Yii Framework 2 จะให้มีคำว่า create_ชื่อตาราง เช่น
yii migrate/create create_product
ก็จะได้ไฟล์ลักษณะดังนี้
console/migrations/m160221_055928_create_product.php
จากนั้นเราก็สามารถเขียนคำสั่งใน method up() และ down() ได้แล้ว ทดลองเขียนคำสั่งใน method up()
<?php
use yii\db\Migration;
class m160221_055928_create_product extends Migration
{
public function up()
{
$this->createTable('product', [
'id' => $this->primaryKey(),
'name' => $this->string(255),
'description' => $this->text(),
'photo' => $this->string(255),
'cost' => $this->integer(),
'price' => $this->integer(),
'status' => $this->integer(1),
'created_at' => $this->timestamp(),
'updated_at' => $this->timestamp(),
]);
}
public function down()
{
$this->dropTable('product');
}
}
ทดลองเรียกใช้งานด้วยคำสั่ง
yii migrate
จะเห็นว่าในฐานข้อมูลมีตาราง product และมี field ต่างๆ ตามที่เราได้กำหนดขึ้นแล้ว
การเพิ่มคอลัมน์ (Column) ในตาราง
ในบางครั้งการออกแบบตารางไปแล้วและได้สร้าง migration ไปแล้ว หากมีการเพิ่ม field ใหม่โดยมีรูปแบบดังนี้
yii migrate/create add_ชื่อฟิวด์_to_ชื่อตาราง --fields="ชื่อฟิวด์:ชนิด","ชื่อฟิวด์:ชนิด"
ตามธรรมเนียมของ Yii Framework 2 จะให้มีคำว่า add_ชื่อฟิวด์_to_ชื่อตาราง เช่น
yii migrate/create add_note_to_product --fields="note:text"
ก็จะได้ไฟล์ลักษณะดังนี้
m160407_083440_add_note_to_product.php
เมื่อเปิดดูไฟล์ก็จะได้คำสั่งในการเพิ่ม field ดังนี้
<?php
use yii\db\Migration;
class m160407_083440_add_note_to_product extends Migration
{
public function up()
{
$this->addColumn('product', 'note', $this->text());
}
public function down()
{
$this->dropColumn('product', 'note');
}
}
ทดลองเรียกใช้งานด้วยคำสั่ง
yii migrate
จะเห็นว่าในฐานข้อมูลตาราง product มี field note เกิดขึ้น
การลบคอลัมน์ (Column) ในตาราง
และในบางครั้งเช่นกันเมื่อเราสร้างตารางเรียบร้อยแล้ว หากเราไม่ต้องการฟิวด์นั้นอีกต่อไปเราก็สามารถลบออกได้ด้วยคำสั่งรูปแบบนี้
yii migrate/create drop_ชื่อฟิวด์_from_ชื่อตาราง --fields="ชื่อฟิวด์:ชนิด"
ตามธรรมเนียมของ Yii Framework 2 จะให้มีคำว่า drop_ชื่อฟิวด์_from_ชื่อตาราง เช่น
yii migrate/create drop_note_from_product --fields="note:text"
ก็จะได้ไฟล์ลักษณะดังนี้
m160407_085053_drop_note_from_product.php
เมื่อเปิดดูไฟล์ก็จะได้คำสั่งในการเพิ่ม field ดังนี้
<?php
use yii\db\Migration;
class m160407_085242_drop_note_from_product extends Migration
{
public function up()
{
$this->dropColumn('product', 'note');
}
public function down()
{
$this->addColumn('product', 'note', $this->text());
}
}
ทดลองเรียกใช้งานด้วยคำสั่ง
yii migrate
จะเห็นว่าในฐานข้อมูลในตาราง product field note ได้ถูกลบไปแล้ว
การลบตาราง
การสร้างตารางจะใช้คำสั่งในการสร้างดังนี้
yii migrate/create drop_table_name
ตามธรรมเนียมของ Yii Framework 2 จะให้มีคำว่า drop_ชื่อตาราง เช่น
yii migrate/create drop_product
ก็จะได้ไฟล์ลักษณะดังนี้
m160407_082347_drop_product.php
เมื่อเปิดไฟล์ก็จะได้คำสั่งในการลบตารางดังนี้
<?php
use yii\db\Migration;
class m160407_082347_drop_product extends Migration
{
public function up()
{
$this->dropTable('product');
}
public function down()
{
$this->createTable('product', [
'id' => $this->primaryKey()
]);
}
}
ทดลองเรียกใช้งานด้วยคำสั่ง
yii migrate
จะเห็นว่าในฐานข้อมูลตาราง product จะถูกลบไปแล้ว
การใช้งานแบบ batchInsert() ร่วมกับ Facker
Facker เป็น class สำหรับการ generate ข้อมูลทดสอบ เป็นข้อมูลตัวอย่างช่วยให้การทดสอบการใช้งาน Web Application มีความสมจริงมากยิ่งขึ้น ดูรายละเอียดได้ที่
https://github.com/fzaninotto/Faker
รายละเอียด Facker สำหรับ Yii2 Extension
http://www.yiiframework.com/doc-2.0/ext-faker-index.html
ทำการสร้าง migration ใหม่
yii migrate/create create_category
yii migrate/create create_product
yii migrate/create add_foreign_key_to_product
จากนั้นแก้ไข method up() ดังนี้
ไฟล์ console/migrations/xxxxx_create_category.php
<?php
use yii\db\Migration;
use Faker\Factory;
class m160419_160008_create_category extends Migration
{
public function up()
{
$this->createTable('category', [
'id' => $this->primaryKey(),
'name' => $this->string(255),
]);
$columns = array('id',
'name',
);
$values = [];
for($i=1; $i<=10; $i++){
$facker = Factory::create();
$values[] = [
$i,
$facker->sentence,
];
}
$this->batchInsert('category', $columns, $values);
}
public function down()
{
$this->dropTable('category');
}
}
ไฟล์ console/migrations/xxxxx_create_product.php
<?php
use yii\db\Migration;
use Faker\Factory;
class m160419_143143_create_product extends Migration
{
public function up()
{
$this->createTable('product', [
'id' => $this->primaryKey(),
'name' => $this->string(255),
'description' => $this->text(),
'price' => $this->integer(),
'status' => $this->integer(1),
'created_at' => $this->integer(),
'updated_at' => $this->integer(),
]);
$columns = array('id',
'name',
'description',
'price',
'status',
'created_at',
'updated_at'
);
$values = [];
for($i=1; $i<=50; $i++){
$facker = Factory::create();
$values[] = [
$i,
$facker->sentence,
$facker->text,
rand(500,5000),
rand(0,1),
time(),
time(),
];
}
$this->batchInsert('product', $columns, $values);
}
public function down()
{
$this->dropTable('product');
}
}
ไฟล์ console/migrations/xxxxx_add_foreign_key_to_product.php
<?php
use yii\db\Migration;
class m160419_163237_add_foreign_key_to_product extends Migration
{
public function up()
{
// creates index for column `category_id`
$this->createIndex(
'idx-product-category_id',
'product',
'category_id'
);
// add foreign key for table `category`
$this->addForeignKey(
'fk-product-category_id',
'product',
'category_id',
'category',
'id',
'CASCADE'
);
}
public function down()
{
// drops foreign key for table `category`
$this->dropForeignKey(
'fk-product-category_id',
'product'
);
// drops index for column `category_id`
$this->dropIndex(
'idx-product-category_id',
'product'
);
}
}
ทดลองเรียกใช้งานด้วยคำสั่ง
yii migrate
จะเห็นว่าในฐานข้อมูลมีตาราง product และจะมีข้อมูล 50 record ตาราง category มีข้อมูล 10 record เกิดขึ้น
สรุป
สำหรับการทำ Migration นั้นมีความสำคัญในกรณีที่เราต้องการทำ Version ของการทำงานกับฐานข้อมูล ตั้งแต่การสร้างตาราง การลบตาราง การเพิ่มฟิวด์ การลบฟิวด์ และการปรับแก้ไขส่วนต่างๆ โดยการทำงานเป็นทีมจะช่วยให้เราได้เห็นการเปลี่ยนแปลงของสิ่งต่างๆ ในฐานข้อมูลของ Project เราได้ และ Migration ใน Yii Framework 2 เป็นเครื่องมือที่ยอดเยี่ยมจริงๆ ครับ @Programmer Thailand Team
ความคิดเห็น