本章我们来了解下如何进行数据库的创建和迁移,并着重讲解了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();
总结
现在我们已经大概了解了数据迁移扩展的使用,没有搞懂的话暂时无需深究,真正有机会的时候再来深入,我们下一章就要开始学习查询构造器的使用了。
上一篇:第一章:数据库架构基础
下一篇:第三章:查询构造器