本章我們來了解下如何進行數據庫的創建和遷移,并著重講解了ThinkPHP5的數據庫遷移擴展的使用,學習內容主要包括:
- 安裝擴展
- 數據遷移
- 創建遷移腳本
- 運行遷移
- 設置斷點
- 回滾遷移
- 遷移方法
- 創建數據表
- 檢查數據表或字段是否存在
- 存儲引擎
- 設置主鍵
- 重命名與刪除數據表
- 可用字段
- 字段修飾
- 特殊字段
- 修改字段
- 移除字段
- 創建索引
- 移除索引
- 外鍵約束
- 總結
安裝擴展
數據遷移是一個擴展包,非核心內置,你需要首先通過composer
安裝擴展(對composer
還不熟悉的朋友可以看云參考官方的快速入門教程中的第一章基礎部分的框架composer
安裝部分):
composer require topthink/think-migration=1.*
指定安裝
1.*
版本是由于最新的2.0
版本只適用于5.1
版本核心框架。
數據遷移
數據遷移就像是數據庫的版本控制,可以確保項目團隊輕松修改并保持應用程序的數據庫結構的一致性。為了避免手動修改數據庫導致的沖突問題,應當盡量避免手動操作數據庫,ThinkPHP5.0
的數據遷移擴展提供了優雅的方式讓你編寫遷移腳本和執行遷移。
編寫數據遷移腳本是一個良好的習慣和團隊協作規范,但并非強制,也不會影響本書后面的章節的學習,如果你感覺暫時用不上可以先略過。
創建遷移腳本
使用下面的命令來創建一個遷移腳本:
php think migrate:create CreateUserTable
如果你對命令行和指令不熟悉,請參考快速入門系列的第一部第十章關于命令行指令的說明。
CreateUserTable
這個腳本名必須為駝峰格式,指令輸入完成后,會在項目根目錄下的database/migrations
目錄下創建一個遷移腳本,里面默認有一個change
方法。
如果你的遷移腳本里只會有以下的操作:
- createTable(創建表)
- renameTable(重命名表)
- addColumn(添加字段)
- renameColumn(重命名字段)
- addIndex(添加索引)
- addForeignKey(添加外鍵)
那么你只需要change
方法就可以了,回滾的時候可以自動根據change里的操作來逆向操作,否則需要定義up
和down
兩個方法,用來表示遷移和回滾兩個具體的操作。
定義了
up
、down
方法后就不要再定義change
方法了,在change
方法里操作數據表的時候,最后只能使用create()
或者update()
來完成操作,而不能使用save()
運行遷移
php think migrate:run
// 指定版本
php think migrate:run -t 20120103083322
設置斷點
php think migrate:breakpoint
//指定版本
php think migrate:breakpoint -t 20120103083322
回滾遷移
可以回滾上一次數據遷移操作(可能包含多個遷移文件)。
php think migrate:rollback
//指定版本
php think migrate:rollback -t 20120103083322
//回滾所有
php think migrate:rollback -t 0
如果設置了斷點,默認最多只可以回滾到斷點處,可以使用--force
參數強制回滾所有
php think migrate:rollback -t 0 -f
遷移方法
遷移腳本中支持大部分的數據庫操作的實現方法,我們陸續給你講述這些用法。
創建數據表
創建數據表使用create
方法,并在之前調用addColumn
方法相關方法進行數據字段定義:
public function change()
{
$this->table('user')
->addColumn(Column::string('name')->setComment('用戶昵稱'))
->addColumn(Column::string('username')->setUnique()->setComment('用戶名'))
->addColumn(Column::string('email')->setUnique()->setComment('郵箱'))
->addColumn(Column::string('password')->setComment('密碼'))
->create();
}
addColumn
方法添加字段傳入一個Column
對象實例,后面會詳細介紹該對象的使用。
或者使用up
和down
public function up()
{
$this->table('user')
->addColumn(Column::string('name')->setComment('用戶昵稱'))
->addColumn(Column::string('username')->setUnique()->setComment('用戶名'))
->addColumn(Column::string('email')->setUnique()->setComment('郵箱'))
->addColumn(Column::string('password')->setComment('密碼'))
->create();
}
/**
* Down Method.
*/
public function down()
{
$this->dropTable('user');
}
檢查數據表或字段是否存在
if($this->hasTable('user')){
//
}
if($this->table('user')->hasColumn('username')){
//
}
存儲引擎
$this->table('user',['engine'=>'MyISAM'])
默認為 InnoDB
設置主鍵
默認會自動添加一個id自增主鍵
$this->table('followers')
->setId(false) //關閉自動設置主鍵
->setPrimaryKey(['user_id','follower_id']) //設置聯合主鍵
->addColumn(Column::integer('user_id'))
->addColumn(Column::integer('follower_id'))
->create();
默認的主鍵是自增的,如果不需要自增可以如下
$this->table('followers')
->setId('user_id')
->addColumn(Column::integer('follower_id'))
->create();
重命名與刪除數據表
//重命名
$this->table('user')->rename('user2');
//刪除
$this->table('user')->drop();
//或者
$this->dropTable('user');
可用字段
數據庫結構構造器包含了許多字段類型,供你構建數據表時使用:
命令 | 描述 |
---|---|
Column::bigInteger('votes'); |
相當于 BIGINT 型態。 |
Column::binary('data'); |
相當于 BLOB 型態。 |
Column::boolean('confirmed'); |
相當于 BOOLEAN 型態。 |
Column::char('name', 4); |
相當于 CHAR 型態,并帶有長度。 |
Column::date('create_time'); |
相當于 DATE 型態。 |
Column::dateTime('create_time'); |
相當于 DATETIME 型態。 |
Column::decimal('amount', 5, 2); |
相當于 DECIMAL 型態,并帶有精度與基數。 |
Column::enum('choices', ['foo', 'bar']); |
相當于 ENUM 型態。 |
Column::float('amount'); |
相當于 FLOAT 型態。 |
Column::integer('votes'); |
相當于 INTEGER 型態。 |
Column::json('options'); |
相當于 JSON 型態。 |
Column::jsonb('options'); |
相當于 JSONB 型態。 |
Column::longText('description'); |
相當于 LONGTEXT 型態。 |
Column::mediumInteger('numbers'); |
相當于 MEDIUMINT 型態。 |
Column::mediumText('description'); |
相當于 MEDIUMTEXT 型態。 |
Column::smallInteger('votes'); |
相當于 SMALLINT 型態。 |
Column::string('email'); |
相當于 VARCHAR 型態。 |
Column::string('name', 100); |
相當于 VARCHAR 型態,并帶有長度。 |
Column::text('description'); |
相當于 TEXT 型態。 |
Column::time('sunrise'); |
相當于 TIME 型態。 |
Column::tinyInteger('numbers'); |
相當于 TINYINT 型態。 |
Column::timestamp('added_on'); |
相當于 TIMESTAMP 型態。 |
Column::uuid('id'); |
相當于 UUID 型態。 |
字段修飾
除了上述的字段類型列表,還有一些其它的字段「修飾」,你可以將它增加到字段中。例如,若要讓字段「nullable」,那么你可以使用 setNullable
方法:
$this->table('user')
->addColumn(Column::string('name')->setNullable())
->create();
以下列表為字段的可用修飾。
修飾 | 描述 |
---|---|
->setAfter('column') |
將此字段放置在其它字段「之后」(僅限 MySQL) |
->setComment('my comment') |
增加注釋 |
->setDefault($value) |
為此字段指定「默認」值 |
->setNullable() |
此字段允許寫入 NULL 值 |
->setUnsigned() |
設置 integer 字段為 UNSIGNED
|
特殊字段
$this->table('user')
->addTimestamps() //添加create_time和update_time兩個字段
->addSoftDelete() //添加delete_time字段
->addMorphs('taggable') //加入整數 taggable_id 與字符串 taggable_type
->create();
修改字段
//重命名字段
$this->table('user')->renameColumn('old_name','new_name');
//修改字段屬性
$this->table('user')->changeColumn(Column::integer('votes')->setNullable());
移除字段
$this->table('user')->removeColumn('name');
創建索引
數據庫結構構造器支持多種類型的索引。首先,讓我們先來看一個示例,其指定了字段的值必須是唯一的。你可以簡單的在字段定義之后鏈式調用 setUnique 方法來創建索引:
$this->table('user')
->addColumn(Column::string('name')->setUnique()->setNullable())
->create();
此外,你也可以在定義完字段之后創建索引。例如:
$this->table('user')
->addColumn(Column::string('name')->setNullable())
->addIndex('name',['unique'=>true])
->create();
你也可以傳遞一個字段的數組至索引方法來創建復合索引:
addIndex(['name','email'])
移除索引
$this->table('user')->removeIndex('name');
$this->table('user')->removeIndex(['name','email']);
外鍵約束
$table = $this->table('tags');
$table->addColumn(Column::integer('tag_name'))
->save();
$this->table('tag_relationships')
->addColumn(Column::integer('tag_id'))
->addForeignKey('tag_id', 'tags', 'id', array('delete'=> 'SET_NULL', 'update'=> 'NO_ACTION'))
->save();
總結
現在我們已經大概了解了數據遷移擴展的使用,沒有搞懂的話暫時無需深究,真正有機會的時候再來深入,我們下一章就要開始學習查詢構造器的使用了。
上一篇:第一章:數據庫架構基礎
下一篇:第三章:查詢構造器