Laravel框架数据库迁移操作实例详解


Posted in PHP onApril 06, 2020

很多人可能在学习Laravel框架的时候,对Laravel的数据库迁移(以下简称Migrations)存在着疑惑:

1. 什么是 Migrations?

2. 为什么要用 Migrations?

3. Migrations 到底方便在哪里?

好了,抱着这些问题,我们今天就一起来学习Migrations。

什么是 Migrations?

我们先来看一下Laravel官方文档怎么写的:

Migrations are like version control for your database, allowing your team to easily modify and share the application's database schema. Migrations are typically paired with Laravel's schema builder to easily build your application's database schema. If you have ever had to tell a teammate to manually add a column to their local database schema, you've faced the problem that database migrations solve.

简单概括起来,就是我们可以将Migrations看作一种数据库的VCS(Version Control System),即版本控制系统。

可以通过Laravel的artisan命令快速创建、修改或还原数据库结构。

为什么要用 Migrations?

使用Migrations可以有效地对数据库进行版本控制,并且遵从了Single Responsibility Principle(单一职责原则),更加方便数据库的操控。

举个例子来说,假设我们已经设计并创建好了数据库,数据已经填充进数据库了,现在我们发现需要在其中一张表里增加一个名为name的栏目(column),需要在另一张表中将author栏目的名字改为user,那么我现在进入数据库里,进行了操作。刚刚操作完,公司老板突然找我面谈。面谈完了之后,我忘记了将我在数据库里的操作记录下来或者告知给其他开发人员,那么随之而来的很可能是灾难性的结果。

如果我们使用了Migrations,并且只通过Migrations进行数据库的操作,那么所有开发人员都可以看到数据库进行了哪些操作,而不会发生上述的情况。

Migrations 到底方便在哪里?

除了上述提到的版本控制功能外,我们几乎不需要写SQL代码就能简单快速地组建起数据库结构,并且可以迅速迁移(migrate)或者回滚(Rollback),省去了大量人工操作的繁琐。

讲解完了概念,我们现在来看一下具体怎么使用Migrations。

要创建一个迁移文件,我们可以用以下artisan命令:

$ php artisan make:migration create_samples_table --create=samples

注意php artisan命令需要在项目根目录下运行。--create==samples这个选项表明我们想要建立一个名为samples的数据库表,所以artisan会自动在database\migrations目录下建立一个叫2017_03_13_061422_create_samples_table.php的文件(其中前缀是创建该文件的日期和时间,用于区分迁移文件的时间先后顺序),并且会自动填充好Schema::create这个方法,方便我们创建更多的column:

<?php        
  
use Illuminate\Support\Facades\Schema;        
use Illuminate\Database\Schema\Blueprint;        
use Illuminate\Database\Migrations\Migration;        
  
class CreateSamplesTable extends Migration        
{        
  /**        
   * Run the migrations.        
   *        
   * @return void        
   */        
  public function up()        
  {        
    Schema::create('samples', function (Blueprint $table) {        
      $table->increments('id');        
      $table->timestamps();        
    });        
  }        
  
  /**        
   * Reverse the migrations.        
   *        
   * @return void        
   */        
  public function down()        
  {        
    Schema::dropIfExists('samples');        
  }        
}

我们看到,这个类中有up和down两个方法。up中我们需要添加创建数据表的函数,以及添加各个栏目的名称及属性。而down方法中我们需要添加在回滚该迁移文件时应该有什么样的结果(这里我们直接删除这张表)。

可以看出,up和down中的操作是对应的,在up中进行了什么操作,down中就需要撤销这些操作。

现在我们详细来看一下up方法。我们看到,Schema::create这个方法是用来创建我们数据表的,在方法中,我们看到Laravel已经为我们填充了几个columns。

$table->increments('id')将创建一个名为id的column,并赋予PRIMARY KEY、UNSIGNED及AUTO INCREMENT属性。

$table->timestamps()将创建created_at和updated_at两个column(类型是DATETIME)。

注意:Laravel默认认为每个table都会存在一个id栏目,并且要求每个table都要有created_at和updated_at这两个栏目。

现在,我们要在samples表里增加一个名为name的VARCHAR类型的栏目,该怎么做呢?

很简单,只需要加上这行:

$table->string('name');

如果我们想限制VARCHAR的长度,可以在第二个参数中进行注明:

$table->string('name', 100);

好了,我们暂时就只需要这些栏目。现在我们已经有了迁移文件了,怎么样才能在数据库里建立起我们的表呢?

很简单,输入

$ php artisan migrate

等待命令完成就可以了。

现在我们在数据库里,就能看到我们的samples表了。

注意:运行php artisan migrate之前请检查你的.env文件中DB_DATABASE,DB_USERNAME,DB_PASSWORD 几项配置是否正确。如果你在Homestead下进行Laravel开发,那么DB_USERNAME默认为homestead,DB_PASSWORD默认为secret,DB_DATABASE请根据你的项目具体填入你的数据库名称。

现在问题来了,我们突然想在samples表里,添加一个名为url的栏目,该怎么做呢?我们分情况讨论。

1. 我们处于本地开发阶段,数据使用种子(Seed)文件进行填充。

对于本地开发,如果想省事,可以直接在samples表的迁移文件中,添加上我们需要的栏目:

$table->string('url', 200)->nullable();

然后我们重置数据库并做种:

$ php artisan migrate:refresh --seed

这样就完成了。打开samples表,我们会发现新的栏目已经被创建。

注意,php artisan migrate:refresh命令相当于

$ php artisan migrate:reset       

$ php artisan migrate

所以我们经常会使用到。

2. 另一种情况,我们需要详细记录每一个数据库操作,例如在production环境下进行数据库修改。

首先我们需要添加一个package:

$ composer require doctrine/dbal

要进行表的修改必须添加以上包裹。

完成后我们需要创建一个新的迁移文件:

$ php artisan make:migration add_url_field_to_samples_table --table=samples

我们想要添加一个url栏目,并且让它在name之后,我们在Schema::table函数中填入以下代码:

<?php      
  
use Illuminate\Support\Facades\Schema;      
use Illuminate\Database\Schema\Blueprint;      
use Illuminate\Database\Migrations\Migration;      
  
class ModifySamplesTable extends Migration      
{      
  /**      
   * Run the migrations.      
   *      
   * @return void      
   */      
  public function up()      
  {      
    Schema::table('samples', function (Blueprint $table) {      
      $table->string('url', 200)->after('name');   
    });      
  }      
  
  /**      
   * Reverse the migrations.      
   *      
   * @return void      
   */      
  public function down()      
  {      
    Schema::table('samples', function (Blueprint $table) {      
      $table->dropColumn('url');     
    });      
  }      
}

完成后,我们运行migrate:

$ php artisan migrate

这样,url就被添加进了sample表中,并且位置处于name之后。

我们在samples表中插入了新的url栏目,那么现在如果我们想把name这个栏目长度限制从100修改为50,该怎么做呢?

同理,我们需要先创建一个migration:

$ php artisan make:migration modify_name_column_in_samples_table --table=samples

在migration文件中,我们添加以下代码:

<?php      
  
use Illuminate\Support\Facades\Schema;      
use Illuminate\Database\Schema\Blueprint;      
use Illuminate\Database\Migrations\Migration;      
  
class ModifyNameColumnInSamplesTable extends Migration      
{      
  /**      
   * Run the migrations.      
   *      
   * @return void      
   */      
  public function up()      
  {      
    Schema::table('samples', function (Blueprint $table) {      
      $table->string('name', 50)->change();       
    });      
  }      
  
  /**      
   * Reverse the migrations.      
   *      
   * @return void      
   */      
  public function down()      
  {      
    Schema::table('samples', function (Blueprint $table) {      
      $table->string('name', 100)->change();      
    });      
  }      
}

完成后,我们再次运行migrate:

$ php artisan migrate

这样一来就完成了栏目的修改,非常的直观。

注意:如果我们想把某个栏目改成其他类型,可以采用以下语法

$table->text('name')->change();

完成之后,再次运行php artisan migrate,我们就可以看到name已经从VARCHAR变为了TEXT类型了。

好了,本文主要讲解了Laravel框架中数据库迁移操作的方法实例,更多关于Laravel框架的使用技巧请查看下面的相关链接

PHP 相关文章推荐
如何在PHP中使用Oracle数据库(4)
Oct 09 PHP
第三章 php操作符与控制结构代码
Dec 30 PHP
php class中public,private,protected的区别以及实例分析
Jun 18 PHP
Php output buffering缓存及程序缓存深入解析
Jul 15 PHP
php实现图形显示Ip地址的代码及注释
Jan 20 PHP
PHP实现文件下载详解
Nov 27 PHP
PHP实现的带超时功能get_headers函数
Feb 10 PHP
PHP爬虫之百万级别知乎用户数据爬取与分析
Jan 22 PHP
php版微信公众平台之微信网页登陆授权示例
Sep 23 PHP
PHP+JS实现的商品秒杀倒计时用法示例
Nov 15 PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
Jul 27 PHP
解决Laravel5.5下的toArray问题
Oct 15 PHP
Laravel框架中队列和工作(Queues、Jobs)操作实例详解
Apr 06 #PHP
Laravel实现批量更新多条数据
Apr 06 #PHP
PHP正则之正向预查与反向预查讲解与实例
Apr 06 #PHP
TP5框架安全机制实例分析
Apr 05 #PHP
TP5框架实现自定义分页样式的方法示例
Apr 05 #PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
Apr 05 #PHP
TP5框架实现签到功能的方法分析
Apr 05 #PHP
You might like
DC动画很好看?新作烂得令人发指,名叫《红色之子》
2020/04/09 欧美动漫
PHP 选项及相关信息函数库
2006/12/04 PHP
php下过滤HTML代码的函数
2007/12/10 PHP
php使用codebase生成随机数
2014/03/25 PHP
destoon后台网站设置变成空白的解决方法
2014/06/21 PHP
迪菲-赫尔曼密钥交换(Diffie?Hellman)算法原理和PHP实现版
2015/05/12 PHP
PHP Class SoapClient not found解决方法
2018/01/20 PHP
PHP类的自动加载与命名空间用法实例分析
2020/06/05 PHP
javascript实现动态模态绑定grid过程代码
2014/09/22 Javascript
2014年最火的Node.JS后端框架推荐
2014/10/27 Javascript
深入理解JavaScript系列(46):代码复用模式(推荐篇)详解
2015/03/04 Javascript
jQuery实现将页面上HTML标签换成另外标签的方法
2015/06/09 Javascript
js数组如何添加json数据及js数组与json的区别
2015/10/27 Javascript
jQuery使用$.ajax进行即时验证实例详解
2015/12/11 Javascript
深入理解jQuery事件绑定
2016/06/02 Javascript
JavaScript实现图片拖曳效果
2017/09/08 Javascript
JS库 Highlightjs 添加代码行号的实现代码
2017/09/13 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
2018/11/08 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
Vue配置marked链接添加target=&quot;_blank&quot;的方法
2019/07/19 Javascript
js利用iframe实现选项卡效果
2020/08/09 Javascript
跟老齐学Python之集合的关系
2014/09/24 Python
Python基于动态规划算法计算单词距离
2015/07/25 Python
解决在Python编辑器pycharm中程序run正常debug错误的问题
2019/01/17 Python
在Python中预先初始化列表内容和长度的实现
2019/11/28 Python
详解CSS3中@media的实际使用
2015/08/04 HTML / CSS
定制iPhone和Macbook保护壳:Slick Case
2018/11/21 全球购物
马来西亚最大的在线隐形眼镜商店:MrLens
2019/03/27 全球购物
高三自我鉴定
2013/10/23 职场文书
好家长事迹材料
2014/01/23 职场文书
我的画教学反思
2014/04/28 职场文书
大学学雷锋活动总结
2014/06/26 职场文书
金融管理专业求职信
2014/07/10 职场文书
企业百日安全活动总结
2015/05/07 职场文书
酒桌上的开场白
2015/06/01 职场文书
springboot 多数据源配置不生效遇到的坑及解决
2021/11/17 Java/Android