数据库:结构和种子

Introduction

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

迁移结构

迁移文件应该定义一个扩展类Winter\Storm\Database\Updates\Migration 类并包含两个方法:updown.这up 方法用于向数据库添加新表、列或索引,而down 方法应该简单地反转由执行的操作up 方法。在这两种方法中,您都可以使用模式构建器 表达性地创建和修改表。例如,让我们看一个示例迁移,它创建了一个winter_blog_posts 桌子:

<?php namespace Acme\Blog\Updates;

use Schema;
use Winter\Storm\Database\Updates\Migration;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('winter_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('winter_blog_posts');
    }
}

创建表

要创建新的数据库表,请使用create 上的方法Schema 正面。这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);

要删除现有表,您可以使用drop 或者dropIfExists 方法:

Schema::drop('users');

Schema::dropIfExists('users');

创建列

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

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

可用的列类型

当然,架构构建器包含多种列类型,您可以在构建表时使用它们:

Command Description
$table->bigIncrements('id'); 使用等效的“UNSIGNED BIG INTEGER”递增 ID(主键)。
$table->bigInteger('votes'); 数据库的 BIGINT 等价物。
$table->binary('data'); 数据库的 BLOB 等价物。
$table->boolean('confirmed'); 数据库的 BOOLEAN 等价物。
$table->char('name', 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'); 加整数taggable_id 和STRINGtaggable_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 等同于一个长度。
$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();
});

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

Modifier Description
->nullable() 允许将 NULL 值插入到列中
->default($value) 为列指定一个“默认”值
->unsigned() integer 列到UNSIGNED
->first() 将列“first”放在表中(仅限 MySQL)
->after('column') 将列放在另一列“之后”(仅限 MySQL)
->comment('my comment') 向列添加注释(仅限 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();
});

重命名列

要重命名列,您可以使用renameColumn 架构生成器上的方法:

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

NOTE: 重命名表中的列enum 当前不支持列。

删除列

要删除列,请使用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');

可用索引类型

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

删除索引

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

Command Description
$table->dropPrimary('users_id_primary'); 从“用户”表中删除一个主键。
$table->dropUnique('users_email_unique'); 从“用户”表中删除一个唯一索引。
$table->dropIndex('geo_state_index'); 从“geo”表中删除一个基本索引。

外键约束

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

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

您还可以为约束的“删除时”和“更新时”属性指定所需的操作:

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

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

$table->dropForeign('posts_user_id_foreign');

播种机结构

与迁移文件一样,播种器类默认只包含一个方法:run并且应该延长Seeder 班级。这run 执行更新过程时调用方法。在此方法中,您可以根据需要将数据插入数据库。您可以使用查询生成器 手动插入数据,或者您可以使用您的模型类.在下面的示例中,我们将使用User 里面的模型run 方法:

<?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 方法允许您将数据库播种分解为多个文件,这样单个播种器类就不会变得非常大。只需传递您希望运行的播种器类的名称:

/**
 * Run the database seeds.
 *
 * @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');
}
豫ICP备18041297号-2