数据库:结构和种子
Introduction
迁移和种子文件允许您构建、修改和填充数据库表。它们主要由插件更新文件 并与插件的版本历史配对。所有类都存储在updates
一个插件的目录。迁移应该讲述一个关于您的数据库历史的故事,这个故事可以向前和向后播放以建立和拆除表。
迁移结构
迁移文件应该定义一个扩展类Winter\Storm\Database\Updates\Migration
类并包含两个方法:up
和down
.这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');
});
当然,在创建表时,您可以使用任何模式生成器的列方法 定义表的列。
检查表/列是否存在
您可以使用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');
});
重命名/删除表
要重命名现有的数据库表,请使用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_at 和updated_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');
}