thinkphp5.0 数据创建和迁移

数据创建和迁移

本章我们来了解下如何进行数据库的创建和迁移,并着重讲解了ThinkPHP5的数据库迁移扩展的使用,学习内容主要包括:

安装扩展

数据迁移是一个扩展包,非核心内置,你需要首先通过composer安装扩展(对composer还不熟悉的朋友可以看云参考官方的快速入门教程中的第一章基础部分的框架composer安装部分):

composer require topthink/think-migration

数据迁移

数据迁移就像是数据库的版本控制,可以确保项目团队轻松修改并保持应用程序的数据库结构的一致性。为了避免手动修改数据库导致的冲突问题,应当尽量避免手动操作数据库,ThinkPHP5.0的数据迁移扩展提供了优雅的方式让你编写迁移脚本和执行迁移。

编写数据迁移脚本是一个良好的习惯和团队协作规范,但并非强制,也不会影响本书后面的章节的学习,如果你感觉学习有难度可以先略过。

创建迁移脚本

使用下面的命令来创建一个迁移脚本:

php think migrate:create CreateUserTable

如果你对命令行和指令不熟悉,请参考快速入门系列的第一部第十章关于命令行指令的说明。

CreateUserTable 这个脚本名必须为驼峰格式,指令输入完成后,会在项目根目录下的database/migrations目录下创建一个迁移脚本,里面默认有一个change方法。

如果你的迁移脚本里只会有以下的操作:

  • createTable(创建表)
  • renameTable(重命名表)
  • addColumn(添加字段)
  • renameColumn(重命名字段)
  • addIndex(添加索引)
  • addForeignKey(添加外键)

那么你只需要change方法就可以了,回滚的时候可以自动根据change里的操作来逆向操作,否则需要定义updown两个方法,用来表示迁移回滚两个具体的操作。

定义了updown方法后就不要再定义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对象实例,后面会详细介绍该对象的使用。

或者使用updown

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')->dropColumn('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();

发表评论

电子邮件地址不会被公开。 必填项已用*标注