数据库结构和数据填充

介绍

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

迁移结构

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

  1. <?php namespace Acme\Blog\Updates;
  2. use Schema;
  3. use October\Rain\Database\Updates\Migration;
  4. class CreatePostsTable extends Migration
  5. {
  6. public function up()
  7. {
  8. Schema::create('october_blog_posts', function($table)
  9. {
  10. $table->engine = 'InnoDB';
  11. $table->increments('id');
  12. $table->string('title');
  13. $table->string('slug')->index();
  14. $table->text('excerpt')->nullable();
  15. $table->text('content');
  16. $table->timestamp('published_at')->nullable();
  17. $table->boolean('is_published')->default(false);
  18. $table->timestamps();
  19. });
  20. }
  21. public function down()
  22. {
  23. Schema::drop('october_blog_posts');
  24. }
  25. }

创建表

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

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

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

重命名/删除表

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

  1. if (Schema::hasTable('users')) {
  2. //
  3. }
  4. if (Schema::hasColumn('users', 'email')) {
  5. //
  6. }

连接和存储引擎

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

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

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

  1. Schema::create('users', function ($table) {
  2. $table->engine = 'InnoDB';
  3. $table->increments('id');
  4. });

重命名/删除表

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

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

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

  1. Schema::drop('users');
  2. Schema::dropIfExists('users');

创建列

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

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

可用的列类型

当然,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方法:

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

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

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

修改列

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

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

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

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

重命名列

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

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

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

删除列

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

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

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

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

创建索引

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

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

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

  1. $table->unique('email');

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

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

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

  1. $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列:

  1. Schema::table('posts', function ($table) {
  2. $table->integer('user_id')->unsigned();
  3. $table->foreign('user_id')->references('id')->on('users');
  4. });

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

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

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

  1. $table->foreign('user_id')
  2. ->references('id')
  3. ->on('users')
  4. ->onDelete('cascade');

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

  1. $table->dropForeign('posts_user_id_foreign');

填充结构

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

  1. <?php namespace Acme\Users\Updates;
  2. use Seeder;
  3. use Acme\Users\Models\User;
  4. class SeedUsersTable extends Seeder
  5. {
  6. public function run()
  7. {
  8. $user = User::create([
  9. 'email' => 'user@example.com',
  10. 'login' => 'user',
  11. 'password' => 'password123',
  12. 'password_confirmation' => 'password123',
  13. 'first_name' => 'Actual',
  14. 'last_name' => 'Person',
  15. 'is_activated' => true
  16. ]);
  17. }
  18. }

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

  1. public function run()
  2. {
  3. $user = Db::table('users')->insert([
  4. 'email' => 'user@example.com',
  5. 'login' => 'user',
  6. [...]
  7. ]);
  8. }

其他填充器

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

  1. /**
  2. * 执行数据库填充
  3. *
  4. * @return void
  5. */
  6. public function run()
  7. {
  8. Model::unguard();
  9. $this->call('Acme\Users\Updates\UserTableSeeder');
  10. $this->call('Acme\Users\Updates\PostsTableSeeder');
  11. $this->call('Acme\Users\Updates\CommentsTableSeeder');
  12. }