企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 数据表结构 ### 介绍 迁移和种子文件使您可以构建,修改和填充数据库表。它们主要由[插件更新文件](https://octobercms.com/docs/plugin/updates)使用,并与插件的版本历史记录配对。所有类都存储在`updates`插件目录中。迁移过程应该讲述一个有关数据库历史记录的故事,并且可以向前和向后播放该故事以建立和删除表。 ### [](https://octobercms.com/docs/database/structure#migration-structure)迁移结构 迁移文件应定义一个扩展`October\Rain\Database\Updates\Migration`该类的类,并包含两个方法:`up`和`down`。该`up`方法用于向数据库中添加新表,列或索引,而该`down`方法应简单地反转该`up`方法执行的操作。在这两种方法中,您都可以使用[模式构建器](https://octobercms.com/docs/database/structure#creating-tables)来表达性地创建和修改表。例如,让我们看一下创建`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'); } } ~~~ ### [](https://octobercms.com/docs/database/structure#creating-tables)建立表格 若要创建新的数据库表,请使用外观`create`上的方法`Schema`。该`create`方法接受两个参数。第一个是表的名称,第二个是的`Closure`,它接收用于定义新表的对象: ~~~ Schema::create('users', function ($table) { $table->increments('id'); }); ~~~ 当然,在创建表时,您可以使用模式构建器的任何[列方法](https://octobercms.com/docs/database/structure#creating-columns)来定义表的列。 #### 检查表/列是否存在 您可以使用`hasTable`和`hasColumn`方法轻松检查表或列是否存在: ~~~ 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'); }); ~~~ ### [](https://octobercms.com/docs/database/structure#renaming-and-dropping-tables)重命名/删除表 要重命名现有数据库表,请使用以下`rename`方法: ~~~ Schema::rename($from, $to); ~~~ 要删除现有表,可以使用`drop`或`dropIfExists`方法: ~~~ Schema::drop('users'); Schema::dropIfExists('users'); ~~~ ### [](https://octobercms.com/docs/database/structure#creating-columns)创建列 要更新现有表,我们将`table`在`Schema`外观上使用方法。与`create`方法类似,该`table`方法接受两个参数,表的名称和`Closure`,它接收一个可用于向表中添加列的对象: ~~~ Schema::table('users', function ($table) { $table->string('email'); }); ~~~ #### 可用的列类型 当然,架构构建器包含各种在创建表时可以使用的列类型: | 命令 | 描述 | | --- | --- | | `$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');` | 添加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等效于长度。 | | `$table->text('description');` | 等同于数据库的TEXT。 | | `$table->time('sunrise');` | 相当于数据库的TIME。 | | `$table->tinyInteger('numbers');` | 相当于数据库的TINYINT。 | | `$table->timestamp('added_on');` | 相当于数据库的TIMESTAMP。 | | `$table->timestamps();` | 添加`created_at`和`updated_at`列。 | #### 列修饰符 除了上面列出的列类型之外,添加列时还可以使用其他几个列“修饰符”。例如,要使列“可为空”,可以使用以下`nullable`方法: ~~~ Schema::table('users', function ($table) { $table->string('email')->nullable(); }); ~~~ 以下是所有可用的列修饰符的列表。此列表不包括[索引修饰符](https://octobercms.com/docs/database/structure#creating-indexes): | 修饰符 | 描述 | | --- | --- | | `->nullable()` | 允许将NULL值插入到列中 | | `->default($value)` | 为列指定一个“默认”值 | | `->unsigned()` | 将`integer`列设置为`UNSIGNED` | | `->first()` | 将列“ first”放在表中(仅适用于MySQL) | | `->after('column')` | 将列放在另一列“之后”(仅适用于MySQL) | | `->comment('my comment')` | 在列中添加评论(仅适用于MySQL) | ### [](https://octobercms.com/docs/database/structure#modifying-columns)修改列 该`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(); }); ~~~ #### [](https://octobercms.com/docs/database/structure#renaming-columns)重命名列 要重命名列,可以使用`renameColumn`“模式”构建器上的方法: ~~~ Schema::table('users', function ($table) { $table->renameColumn('from', 'to'); }); ~~~ > **注意:**`enum`目前不支持使用列重命名表中的列。 ### [](https://octobercms.com/docs/database/structure#dropping-columns)删除列 要删除列,请使用`dropColumn`“模式”构建器上的方法: ~~~ Schema::table('users', function ($table) { $table->dropColumn('votes'); }); ~~~ 您可以通过将列名称数组传递给`dropColumn`方法来从表中删除多个列: ~~~ Schema::table('users', function ($table) { $table->dropColumn(['votes', 'avatar', 'location']); }); ~~~ ### [](https://octobercms.com/docs/database/structure#creating-indexes)创建索引 模式构建器支持几种类型的索引。首先,让我们看一个示例,该示例指定一列的值应唯一。要创建索引,我们可以简单地将`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');` | 添加基本​​索引。 | ### [](https://octobercms.com/docs/database/structure#dropping-indexes)删除索引 要删除索引,必须指定索引的名称。如果没有手动指定名称,则系统将自动生成一个名称,只需将表名称,索引列的名称和索引类型连接在一起。这里有些例子: | 命令 | 描述 | | --- | --- | | `$table->dropPrimary('users_id_primary');` | 从“用户”表中删除主键。 | | `$table->dropUnique('users_email_unique');` | 从“用户”表中删除唯一索引。 | | `$table->dropIndex('geo_state_index');` | 从“ geo”表中删除基本索引。 | ### [](https://octobercms.com/docs/database/structure#foreign-key-constraints)外键约束 还支持创建外键约束,这些约束用于在数据库级别强制引用完整性。例如,让我们`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'); ~~~ ### [](https://octobercms.com/docs/database/structure#seeder-structure)播种者结构 像迁移文件一样,默认情况下,种子类仅包含一个方法:`run`并且应该扩展`Seeder`该类。`run`执行更新过程时将调用该方法。在这种方法中,您可以根据需要将数据插入数据库中。您可以使用[查询生成器](https://octobercms.com/docs/database/query)手动插入数据,也可以使用[模型类](https://octobercms.com/docs/database/model)。在下面的示例中,我们将使用方法`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`[查询生成器](https://octobercms.com/docs/database/query)方法实现相同的目的: ~~~ public function run() { $user = Db::table('users')->insert([ 'email' => 'user@example.com', 'login' => 'user', [...] ]); } ~~~ ### [](https://octobercms.com/docs/database/structure#calling-additional-seeders)呼叫其他播种机 在`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'); } ~~~