Skip to content

Latest commit

 

History

History
333 lines (244 loc) · 13.2 KB

File metadata and controls

333 lines (244 loc) · 13.2 KB

数据库结构和数据填充

介绍

迁移和填充文件允许您构建/修改和填充数据库表。 它们主要由[插件更新文件](../ plugin/updates)使用,并与插件的版本历史配对。 所有类都存储在插件的updates目录中。 迁移应该讲述一个关于您的数据库历史的故事,这个故事可以向前和向后播放,以构建和拆除表格。

迁移结构

迁移文件应该定义一个扩展October\Rain\Database\Updates\Migration类的类,它包含两个方法:updownup方法用于向数据库添加新的表,列或索引,而down方法是up的逆向操作。 在这两种方法中,您可以使用schema builder(表格一整天的人如果生成器) 来表达式创建和修改表。 例如,让我们看一下创建october_blog_posts表的示例迁移:

<?php namespace Acme\Blog\Updates;

use Schema;
use October\Rain\Database\Updates\Migration;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('october_blog_posts', function($table)
        {
            $table->engine = 'InnoDB';
            $table->increments('id');
            $table->string('title');
            $table->string('slug')->index();
            $table->text('excerpt')->nullable();
            $table->text('content');
            $table->timestamp('published_at')->nullable();
            $table->boolean('is_published')->default(false);
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::drop('october_blog_posts');
    }
}

创建表

要创建新的数据库表,请在Schemafacade上使用create方法。 create方法接受两个参数。 第一个是表的名称,而第二个是Closure,它接收用于定义新表的对象:

Schema::create('users', function ($table) {
    $table->increments('id');
});

当然,在创建表时,您可以使用任何模式构建器的列方法 来定义表的列。

重命名/删除表

您可以使用hasTablehasColumn方法轻松检查是否存在表或列:

if (Schema::hasTable('users')) {
    //
}

if (Schema::hasColumn('users', 'email')) {
    //
}

连接和存储引擎

如果要对不是默认连接的数据库连接执行模式操作,请使用connection方法:

Schema::connection('foo')->create('users', function ($table) {
    $table->increments('id');
});

要为表设置存储引擎,请在架构构建器上设置engine属性:

Schema::create('users', function ($table) {
    $table->engine = 'InnoDB';

    $table->increments('id');
});

重命名/删除表

要重命名现有数据库表,请使用rename方法:

Schema::rename($from, $to);

要删除现有表,可以使用dropdropIfExists方法:

Schema::drop('users');

Schema::dropIfExists('users');

创建列

要更新现有表,我们将在Schemafacade上使用table方法。 与create方法一样,table方法接受两个参数,即表的名称和一个Closure,它接收一个我们可以用来向表中添加列的对象:

Schema::table('users', function ($table) {
    $table->string('email');
});

####可用的列类型

当然,schema生成器包含构建表时可能使用的各种列类型:

命令 描述
$table->bigIncrements('id'); 使用“UNSIGNED BIG INTEGER”等效增加ID(主键)。
$table->bigInteger('votes'); 对应数据库中的BIGINT类型
$table->binary('data'); 对应数据库中的BLOB类型。
$table->boolean('confirmed'); 对应数据库中的 BOOLEAN类型。
$table->char('name', 4); 对应数据库中的长度为4的CHAR类型。
$table->date('created_at'); 对应数据库中的DATE类型。
$table->dateTime('created_at'); 对应数据库中的DATETIME类型。
$table->decimal('amount', 5, 2); 对应数据库中的DECIMAL精度和比例。
$table->double('column', 15, 8); 对应数据库中的DOUBLE精度,总共15位,小数点后8位。
$table->enum('choices', ['foo', 'bar']); 对应数据库中的ENUM类型。
$table->float('amount'); 对应数据库中的FLOAT类型。
$table->increments('id'); 使用“UNSIGNED INTEGER”等效增加ID(主键)。
$table->integer('votes'); 对应数据库中的INTEGER类型。
$table->json('options'); 对应数据库中的JSON类型。
$table->jsonb('options'); 对应数据库中的JSONB类型。
$table->longText('description'); 对应数据库中的LONGTEXT类型。
$table->mediumInteger('numbers'); 对应数据库中的MEDIUMINT类型。
$table->mediumText('description'); 对应数据库中的MEDIUMTEXT类型。.
$table->morphs('taggable'); 添加INTEGER类型的taggable_id列和STRING类型的taggable_type列。
$table->nullableTimestamps(); timestamps()相同,但允许NULL。
$table->rememberToken(); remember_token添加为VARCHAR(100)NULL。
$table->smallInteger('votes'); 对应数据库中的SMALLINT类型。
$table->softDeletes(); 为软删除添加deleted_at列。
$table->string('email'); 对应数据库中的VARCHAR类型。
$table->string('name', 100); 对应数据库中的VARCHAR类型长度为100的字符串。
$table->text('description'); 对应数据库中的TEXT类型。
$table->time('sunrise'); 对应数据库中的TIME类型。
$table->tinyInteger('numbers'); 对应数据库中的TINYINT类型。
$table->timestamp('added_on'); 对应数据库中的TIMESTAMP类型。
$table->timestamps(); 添加 created_atupdated_at 列。

列修饰符

除了上面列出的列类型之外,还可以在添加列时使用其他几个列“修饰符”。 例如,要使列“可为空”,您可以使用nullable方法:

Schema::table('users', function ($table) {
    $table->string('email')->nullable();
});

下面是所有可用列修饰符的列表。 此列表不包括索引修饰符

方法 描述
->nullable() 允许将NULL值插入列中
->default($value) 为列指定“默认”值
->unsigned() integer列设置为UNSIGNED
->first() 将列放在表的首列(仅限MySQL)
->after('column') 将列放在某一列之后(仅限MySQL)

修改列

change方法允许您将现有列修改为新类型,或修改列的属性。 例如,您可能希望增加字符串列的大小。 使用change方法,让我们将name列的大小从25增加到50:

Schema::table('users', function ($table) {
    $table->string('name', 50)->change();
});

我们还可以将列修改为可为空:

Schema::table('users', function ($table) {
    $table->string('name', 50)->nullable()->change();
});

重命名列

要重命名列,可以在Schema上使用renameColumn方法:

Schema::table('users', function ($table) {
    $table->renameColumn('from', 'to');
});

注意: 目前不支持使用enum列重命名表中的列。

删除列

要删除列,请使用Schema上的“dropColumn”方法:

Schema::table('users', function ($table) {
    $table->dropColumn('votes');
});

您可以通过将列名组成的数组传递给dropColumn方法从表中删除多个列:

Schema::table('users', function ($table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});

创建索引

架构构建器支持多种类型的索引。 首先,让我们看一个指定列的值应该是唯一的示例。 要创建索引,我们可以简单地将unique方法链接到列定义:

$table->string('email')->unique();

或者,您可以在定义列后创建索引。 例如:

$table->unique('email');

您甚至可以将一组列传递给索引方法以创建复合索引:

$table->index(['account_id', 'created_at']);

在大多数情况下,您应手动指定索引的名称作为第二个参数,以避免系统自动生成太长的索引:

$table->index(['account_id', 'created_at'], 'account_created');

可用的索引类型

命令 描述
$table->primary('id'); 添加主键。
$table->primary(['first', 'last']); 添加复合键。
$table->unique('email'); 添加唯一索引。
$table->index('state'); 添加基本索引。

删除索引

要删除索引,必须指定索引的名称。 如果没有手动指定名称,系统将自动生成一个名称,只需连接表名,索引列的名称和索引类型。 这里有些例子:

命令 描述
$table->dropPrimary('users_id_primary'); 从“users”表中删除主键。
$table->dropUnique('users_email_unique'); 从“users”表中删除唯一索引。
$table->dropIndex('geo_state_index'); 从“geo”表中删除基本索引。

外键约束

还支持创建外键约束,这些约束用于强制数据库级别的引用完整性。 例如,让我们在posts表上定义一个user_id列,引用users表上的id列:

Schema::table('posts', function ($table) {
    $table->integer('user_id')->unsigned();

    $table->foreign('user_id')->references('id')->on('users');
});

和刚才一样,您可以通过将第二个参数传递给foreign方法来手动指定约束的名称:

$table->foreign('user_id', 'user_foreign')
    ->references('id')
    ->on('users');

您还可以为约束的“on delete”和“on update”属性指定所需的操作:

$table->foreign('user_id')
      ->references('id')
      ->on('users')
      ->onDelete('cascade');

要删除外键,可以使用dropForeign方法。 外键约束使用与索引相同的命名约定。 因此,如果没有手动指定,我们将连接表名和约束中的列,然后将名称后缀为“_foreign”:

$table->dropForeign('posts_user_id_foreign');

填充结构

与迁移文件一样,填充类默认只包含一个方法:run并应扩展Seeder类。 执行更新过程时会调用run方法。 在此方法中,您可以根据需要将数据插入数据库。 您可以使用查询构建器手动插入数据,也可以使用model classes。 在下面的示例中,我们将使用run方法中的User模型创建一个新用户:

<?php namespace Acme\Users\Updates;

use Seeder;
use Acme\Users\Models\User;

class SeedUsersTable extends Seeder
{
    public function run()
    {
        $user = User::create([
            'email'                 => 'user@example.com',
            'login'                 => 'user',
            'password'              => 'password123',
            'password_confirmation' => 'password123',
            'first_name'            => 'Actual',
            'last_name'             => 'Person',
            'is_activated'          => true
        ]);
    }
}

或者,使用Db::table 查询构建器 方法可以实现相同的目的:

public function run()
{
    $user = Db::table('users')->insert([
        'email'                 => 'user@example.com',
        'login'                 => 'user',
        [...]
    ]);
}

其他填充器

DatabaseSeeder类中,您可以使用call方法来执行其他填充类。 使用call方法可以将数据库填充分解为多个文件,这样就不会有单个的填充类变得非常大。 只需传递您希望运行的填充类的名称:

/**
 * 执行数据库填充
 *
 * @return void
 */
public function run()
{
    Model::unguard();

    $this->call('Acme\Users\Updates\UserTableSeeder');
    $this->call('Acme\Users\Updates\PostsTableSeeder');
    $this->call('Acme\Users\Updates\CommentsTableSeeder');
}