博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
由浅入深laravel教程第3课:玩转数据迁移migration(超详细版)
阅读量:6912 次
发布时间:2019-06-27

本文共 14036 字,大约阅读时间需要 46 分钟。

补充上节课:配置虚拟主机

不用修改nginx的配置文件,减少学习成本,只要在homestead.yaml 和host文件两个文件中做很小的改动就行
D:03www2018homesteadHomestead.yaml

map: myblog.appto: /home/vagrant/abcde/study/myblog/public

C:WindowsSystem32driversetchosts

192.168.10.10 www.myblog.app

D:03www2018studymyblogconfigapp.php

'timezone' => 'Asia/Shanghai',

D:03www2018studymyblog.env.home

DB_PREFIX=study_

D:03www2018studymyblogconfigdatabase.php

'migrations' => 'migrations2017','prefix' => env('DB_PREFIX', ''),

一:数据库配置

  1. 新建连接和数据库
    在navicat for mysql中新建连接,用户名homestead,密码secret,新建数据库myblog,字符集为utf8mb4 -- UTF-8 Unicode,规则排序为utf8mb4_general_ci
  2. 新增加一个用户

GRANT ALL PRIVILEGES ON myblog.* TO daqi@localhost IDENTIFIED BY 'daqi168' WITH GRANT OPTION;

  1. 给应用指定开发环境

有5个地方可以指定开发环境[我们这里使用第1种方法或第2种方法]

  • 在homestead.yaml中
  • 在入口文件的最开始加上 putenv("APP_ENV=home");
  • 修改web服务器的配置文件,如nginx配置文件中加上 env APP_ENV=home;
    apache配置文件中加上SetEnv APP_ENV home
  • 在.htaccess中加上
  • php主配置文件php-fpm.conf来设置

修改homestead.yaml加下

variables:       - key: 'APP_ENV'         value: 'home'       - key: 'APP_DEBUG'         value: 'true'

4.编辑应用配置文件.env.home

先生成应用的key

vagrant@homestead:~/abcde/study/myblog$ php artisan key:generate

Application key [base64:s6Rhb/LhTYIpjXi3x+tN9Yon/iBavjnxO4bjXmrYq1g=] set successfully.
将生成的key放在配置文件.env.home中APP_KEY
有关base64的详细了解参考:
每个laravel必须得生成一个key,它是在加密模块中必须要用到的,

APP_NAME=我的博客APP_ENV=localAPP_KEY= base64:s6Rhb/LhTYIpjXi3x+tN9Yon/iBavjnxO4bjXmrYq1g=APP_DEBUG=trueAPP_LOG_LEVEL=debugAPP_URL=http://localhostDB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=myblogDB_USERNAME=daqiDB_PASSWORD=daqi168DB_PREFIX=study_ //自己加

D:03www2018studymyblogconfigdatabase.php中改

'prefix' => env('DB_PREFIX', ''),'migrations' => 'migrations2017',

安装调试文件(可选)

vagrant@homestead:~/abcde/study/myblog$ composer require advance100/helper

# 二:生成第一个迁移文件

先了解一下有关migrate的所有命令

make:migration 新建一个迁移文件

migrate 运行数据库迁移,这个是安装软件时执行的
migrate:fresh 会删除所有已经生成的表,并重新运行所有的迁移
migrate:install 新建一个迁移仓库,会在homestead数据库中生成一个表migrations
migrate:refresh Reset and re-run all migrations
migrate:reset Rollback all database migrations
migrate:rollback 只回滚最后一条迁移
migrate:status 显示每条迁移的状态

make:migration

参考: IlluminateDatabaseConsoleMigrationsMigrateMakeCommand

文件名格式为: date('Y_m_d_His')的值
文件的保存路径:默认为基本路径/database/migrations/下面,如果指定了--path参数就是基本路径/+指定路径
问题来了?如果我想放在其它路径,如vendor下面的某个模块下面如做操作?
答:这要用到 php artisan vendor:publish

以新建一个用户权限管理为例,建以下几个表

admins
roles
permissons
role_user
permisson_user

生成建表admins的迁移文件

vagrant@homestead:~/abcde/study/myblog$ php artisan make:migration create_admins_tableCreated Migration: 2017_10_31_231348_create_admins_table

注意make:migration有1个必写的参数name, 3个可选的选项 --create,--tabel,--path

  1. --path是指定迁移文件生成的位置,默认是放在 应用根目录/database/migrations下面,如果指定了--path=x/y/x,就会在 应用根目录/x/y/z下面生成迁移文件,注意的是得保证该目录已存在,否则会报错
  2. 新建表时,name的写法可以是 create_表名_table,这种写法,后面的create可以省略,否则不能省,如make:migration wang --create=members
  3. 选项前有两个减号--,新手易写掉一个
  4. --create=表名,新建一个表,表名一般全为小写字母,复数形式
  5. --table=表名,修改现成的表
  6. --create与--tabel是2选1
  7. 在命令行自动生成的迁移文件只能是在当前项目下,如果想在项目外如vendor/包/模块中生成迁移文件,得手工编写,或自动生成后拷贝到指定地方,但要注意的是模块中的服务提供商中得写publish方法
  8. 生成的迁移文件名格式是 yyyy_mm_dd_His_name.php,文件中类名是将name写在大驼峰的格式,如name为create_admins_table变成class CreateAdminsTable extends Migration
  9. 生成的文件名是可以修改的,用来调整顺序,系统的排序是asort(名字名组成的数组,SORT_REGULAR ); 以升序的方式排列的,所以改名时要注意
  10. 没有运行migrate之前,迁移文件是可以手工删除和改名,修改内容的

按上面生成另外几个迁移文件

php artisan make:migration create_roles_tablephp artisan make:migration create_permissions_tablephp artisan make:migration create_role_user_tablephp artisan make:migration create_permission_role_table

三:编辑迁移文件

up是migrate时执行的方法

down是migrate:rollback,migrate:reset,migrate:fresh,migrate:refresh时会执行的方法
Facade(有人翻译成门面,我觉得翻译成表面比较合适些) Schema::方法实际上是执行 \Illuminate\Database\Schema\MySqlBuilder的方法,分下面几种

判断的有 hasTable,hasColumn,hasColumns

读取的有 getAllTables,getColumnListing,getColumnType,getConnection
设置的有 setConnection,blueprintResolver
删除的有 dropAllTables
操作的有 rename,enableForeignKeyConstraints,disableForeignKeyConstraints
迁移常用有 create,table,drop,dropIfExists

Blueprint(翻译成蓝图),其实就是代表一个数据库中的表,它的方法主要有2种,一是针对命令commands的方法,另是针对列columns的方法,命令和列都是一个流Fluent对象,处理命令的方法不多,主要熟悉的是处理列的方法,下面是针对Mysql数据的一些列方法和修饰器

charset='utf8mb4'; $table->collation='utf8mb4_unicode_ci'; $table->engine='innodb'; //$table->temporary(); // 上面四条是演示可以单独给某个表指定以上属性 $table->increments('id'); $table->string('name')->comment("用户名"); $table->string('email')->unique()->comment("邮箱必须唯一"); //unique()为索引命令,comment为修饰 $table->string('password',60)->comment("密码最长为60个字节"); $table->rememberToken()->comment("口令"); $table->text('description')->nullable()->comment("管理员说明"); $table->timestamps(); }); } public function down(){ Schema::dropIfExists('admins'); }}

3.1 列Columns

  • getColumns()获取蓝图Blueprint的所有列,每一列也是一个流Fluent对象,流对象中有type和name两个必须指定
  • addColumn($type, $name, array $parameters = []) 重点讲
  • removeColumn($name)
  • getAddedColumns() 获取所有新加的列
  • getChangedColumns() 获取所有改动了的列

3.1.1 字符串类型

分类 方法 mysql类型 使用说明
字符串01 char(列名, 长度 = null) char 定长字符串
字符串02 string(列名, 长度 = null) varchar 长度可变字符串
字符串03 text(列名) text 支持2^16-1个字节,相当于2.1万个汉字
字符串04 mediumText(列名) mediutext 支持2^24-1个字节,相当于560万个汉字
字符串05 longText(列名) longtext 支持2^32-1个字节,相当于14亿个汉字
实现01: rememberToken() varchar(100) string('remember_token', 100)->nullable()
实现02: uuid(列名) char(36)
实现03: ipAddress(列名) varchar(45)
实现04: macAddress(列名) varchar(17)

说明1: string长度指的是字符长度,不是字节,最大支持2^8-1=255个字符,1个数字,字母,汉字都是算一个字符,string('name',25)表示可以储存25个汉字

说明2: text长度指的是字节,
说明3: char适合等长密码,邮编等,默认为...Builder::$defaultStringLength,这个值是可以在服务提供商中修改的
说明4: text与string有些不一样,在utf8编码下,一个汉字相当于3个字节,最大支持21845个汉字,多一个字就会报错

3.1.2 整数类型

分类 方法 mysql类型 使用说明
整数01 参数(列名, 自增长 = false, 无符号 = false)
tinyIntegert 和 unsignedTinyInteger
tinyint 占1个字节,长度2^8
整数02 integer 和 unsignedInteger int 占2个字节,长度2^16
整数03 smallInteger 和 unsignedSmallInteger smallint 占3个字节,长度2^24
整数04 mediumInteger 和 unsignedMediumInteger mediumint 占4个字节,长度 2^32
整数05 bigInteger 和 unsignedBigInteger bigint 占8个字节,长度2^63
自增长列01 increments(列名) unsignedInteger(列名, true)
自增长列02 tinyIncrements(列名) unsignedTinyInteger(列名, true)
自增长列03 smallIncrements(列名) unsignedSmallInteger(列名, true)
自增长列04 mediumIncrements(列名) unsignedMediumInteger(列名, true)
自增长列05 bigIncrements(列名) unsignedBigInteger(列名, true)
真假 boolean($column) tinyint(1)

说明1: 整数类型都指定不了长度,也指定不了zerofill,不过这没有关系,因为整数实际存储的长度与指定的长度没有关系,只是显示的长度而已

3.1.3 小数类型

分类 方法 mysql类型 使用说明
单精度浮点数 float($column, $total = 8, $places = 2) 弃用 单精度必须要指定M和D
双精度浮点数 double($column, $total = null, $places = null) double(M,D) 或double
正负定点数 decimal($column, $total = 8, $places = 2)
unsignedDecimal
decimal(M,D) 精度和标度必须指定,默认为(8,2)

说明1: float是单精度浮点数,double是双精度浮点数,decimal是定点数

说明2: float占4个字节,double占8个字节
说明3: 这3个类型也可以理解为小数
说明4: 浮点数存在误差问题,定点数精确,对货币等对精度敏感的数据,应该用定点数表示或存储;
说明5: 编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较;
说明6: FLOAT(M,D),DOUBLE(M,D)。表示共M位数,小数点前面为M-D位,小数点后面为D位
说明7: decimal在mysql内存是以字符串存储的

3.1.4 日期时间

分类 方法 mysql类型 使用说明
日期 date($column) date
时间 time($column) time
时间 timeTz($column) time
日期时间 dateTime($column, $precision = 0) datetime(精度)
datetime
日期时间 dateTimeTz($column, $precision = 0) datetime
时间戳 timestamp($column, $precision = 0) timestamp 用使用useCurrent使用当前时间
时间戳 timestampTz($column, $precision = 0) timestamp
时间戳实现 timestamps($precision = 0){...} timestamp('created_at', $precision)->nullable();<br>timestamp('updated_at', $precision)->nullable();
时间戳实现 timestampsTz($precision = 0){...} timestampTz('created_at', $precision)->nullable();<br>timestampTz('updated_at', $precision)->nullable();
时间戳实现 nullableTimestamps($precision = 0) 是timestamps的别名
时间戳实现 softDeletes(列名 = 'deleted_at',精度 = 0)
时间戳实现 softDeletesTz($precision = 0)

说明01: datetime不支持取默认值now(),版本5.6之后的可以默认值CURRENT_TIMESTAMP,它会取当前时间,并转为2017-11-01 23:25:45类的格式,但这种情况不能指定精度,另处写法是new IlluminateDatabaseQueryExpression('CURRENT_TIMESTAMP')才能使用Mysql中的常量

说明02: timestamp('列名',精度),如果指定了精度就不能使用修饰->useCurrent(),框架源代码此处是一个bug,等修正, 只有不指定精度时才可能使用useCurrent
说明03: datetime(3)意思是保留3为毫秒数,timestamp('login',3);的结果如2017-11-02 02:08:34.864,也是保留3位毫秒
说明04: TZ是系统时区的意思,但实际使用中使用非Tz格式就行
说明05: 未提供year的方法,可能是year的范围太小的原因舍弃了,可以使用date获取

日期类型 存储空间 日期格式 日期范围
datetime 8 bytes YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 至 9999-12-31 23:59:59
timestamp 4 bytes YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 至 2038
date 3 bytes YYYY-MM-DD 1000-01-01 至 9999-12-31
year 1 bytes YYYY 1901 至 2155

3.1.5 其它

分类 方法 mysql类型 使用说明
枚举 enum($column, ['市场部','设计部','总裁办']) 生成enum('市场部','设计部','总裁办')
json($column) json 这是5.7.7后才有的功能
jsonb($column) json 这是5.7.7后才有的功能
二进制 binary($column) blob

说明:json很好用,但要看mysql版本支不支持

说明: 没有mediumblob和longblob,这样储存图片声音等文件没有办法,解决办法是在

Schema::create("member", function($table) {    // 这里可以放SchemaBuilder支持的各种方法});DB::statement("ALTER TABLE member ADD imagedata MEDIUMBLOB");

3.1.6 空间

MySQL 5.7 GIS特性

方法 mysql类型 使用说明
geometry($column) geometry
point($column) point
lineString($column) linestring
polygon($column) polygon
geometryCollection($column) geometrycollection
multiPoint($column) multipoint
multiLineString($column) multilinestring
multiPolygon($column) multipolygon

3.1.7 综合实现: 生成索引

morphs($name, $indexName = null){    $this->unsignedInteger("{$name}_id");    $this->string("{$name}_type");    $this->index(["{$name}_id", "{$name}_type"], $indexName);}nullableMorphs($name, $indexName = null){    $this->unsignedInteger("{$name}_id")->nullable();    $this->string("{$name}_type")->nullable();    $this->index(["{$name}_id", "{$name}_type"], $indexName);}

3.2: Blueprint中的列的修饰符

Nullable,Default,Comment,Unsigned,VirtualAs,StoredAs,Charset,Collate,Increment,After,First

3.3 索引

添加索引的命令是

indexCommand($type, $columns, $index, $algorithm = null)

删除索引的命令是

dropIndexCommand($command, $type, $index)

5种索引的单独命令

命令 实际
primary indexCommand('primary', $columns, $name, $algorithm)
unique indexCommand('unique', $columns, $name, $algorithm)
index indexCommand('index', $columns, $name, $algorithm)
spatialIndex indexCommand('spatialIndex', $columns, $name)
foreign indexCommand('foreign', $columns, $name)
dropIndex dropIndexCommand('dropIndex', 'index', $index)
dropPrimary dropIndexCommand('dropPrimary', 'primary', $index)
dropUnique dropIndexCommand('dropUnique', 'unique', $index)
dropForeign dropIndexCommand('dropForeign', 'foreign', $index)

说明:如果将某单列定义为某种索引,可以直接按修饰命令的方式定义,如 $table->string('name')->unique();但这种方式不适合外键

3.4 命令

每一个命令都是一个流(Flent)对象,流对象中name必须指定,比如 create()就是在commands增加一个name为create的流对象

处理命令的有: getCommands获取所有的命令,addCommand,createCommand
判断是否有create命令creating
对表create,drop,dropIfExists,rename
对表中的列,dropColumn,renameColumn

四: 熟悉迁移命令

  1. 生成迁移文件
    php artisan make:migration create_wang04_table --path=database/migrations2

php artisan make:migration create_wang05_table --path=database/migrations2

  1. 运行迁移,凡在指定路径下有的文件名,没有出现在仓库表的migration字段中的,就会执行
    php artisan migrate --database=mysql2 --path=database/migrations2
  2. 撤销上一步迁移,只一步啊,上一次migrate有多少变动,如生成5张表,这一次会全部撤销
    php artisan migrate:rollback --database=mysql2 --path=database/migrations2
  3. 撤销全部,清空仓库表,除了仓库表外,所有的表都删除
    php artisan migrate:reset --database=mysql2 --path=database/migrations2
  4. 删除所有的表,再重新运行一个迁移,它的效率比6要高
    php artisan migrate:fresh --database=mysql2 --path=database/migrations2
  5. 全部撤销并重新运行迁移,与fresh的差别是它是一步一步的撤销,原来假设有78步,那么就一步一步撤,再一步一步运行,它俩有一个共同点是,最后只算一批,也就是所有的迁移是一批,仓库表中的batch值全部为1
    php artisan migrate:refresh --database=mysql2 --path=database/migrations2
  6. 显示当前迁移的状态
    php artisan migrate:status --database=mysql2 --path=database/migrations2
id migration batch
6 2017_11_02_091523_wang01 1
7 2017_11_02_103519_create_json_table 1
8 2017_11_02_142016_create_wang01_table 1
9 2017_11_02_142040_create_wang02_table 1
10 2017_11_02_142103_create_wang03_table 1
11 2017_11_02_142928_create_wang04_table 2
12 2017_11_02_143043_create_wang05_table 3
13 2017_11_02_143104_create_wang06_table 3

migate命令会将没有运行过的迁移文件运行,有几个执行几个

migrate:rollback 只会撤销最后一批,如上面会撤销第3批生成的两个表
migrate:install 用来生成仓库表,不用执行,系统会自动执行,且只会执行一次,该表不会被撤销
migrate:status 显示哪些迁移文件还未运行,N表示还未运行
migrate:reset Rollback all database migrations
migrate:fresh 会删除所有已经生成的表,并重新运行所有的迁移
migrate:refresh Reset and re-run all migrations

Ran? Migration
Y 2017_11_02_091523_wang01
Y 2017_11_02_103519_create_json_table
Y 2017_11_02_142016_create_wang01_table
Y 2017_11_02_142040_create_wang02_table
Y 2017_11_02_142103_create_wang03_table
Y 2017_11_02_142928_create_wang04_table
N 2017_11_02_143043_create_wang05_table
N 2017_11_02_143104_create_wang06_table

五: 迁移文件发布

数据迁移文件一般与模块放在一起,比如你开发了一个模块,有自己的数据表,当别人使用你的模块时,得先将你的数据迁移文件拷贝到应用的指定文件夹下。这样很不方便,所以得在模块的服务提供商文件中写好发布方法

六: 多数据库版

6.1 新建数据库laravel_study

字符集utf8 -- UTF-8 Unicode,排序规则:utf8_general_ci

6.2 配置第二个数据库

D:03www2018studymyblogconfigdatabase.php增加如下

//第2个数据库连接        'mysql2' => [            'driver'    => 'mysql',            'host'      => '127.0.0.1',            'database'  => 'laravel_study',            'username'  => 'zhangxueyou',            'password'  => 'liudehua',            'charset'   => 'utf8',            'collation' => 'utf8_unicode_ci',            'prefix'    => '',        ],

6.3 新增加一个用户

GRANT ALL PRIVILEGES ON study_laravel.* TO zhangxueyou@localhost IDENTIFIED BY 'liudehua' WITH GRANT OPTION;

6.4 重启mysql

vagrant@homestead:~/abcde/study/myblog$ sudo service mysql restart

6.5 新建迁移文件

先建好文件夹migrations2

vagrant@homestead:~/abcde/study/myblog$ php artisan make:migration wang01 --create=study01 --path=database/migrations2

6.6 编辑迁移文件

create('study01', function (Blueprint $table) { $table->increments('id'); $table->string('username',25); $table->dateTime('mydatetime')->default(new \Illuminate\Database\Query\Expression('CURRENT_TIMESTAMP')); $table->timestamp('register_time')->useCurrent(); //$table->timestamp('register_time',3); $table->timestamps(); }); } public function down() { Schema::connection('mysql2')->dropIfExists('study01'); }}

上面要注意默认值为CURRENT_TIMESTAMP的写法,如果不这样写,系统为了安全会加上单引号,另外该msyql常量只在mysql版本高于5.6才有

6.7 迁移和回滚

vagrant@homestead:~/abcde/study/myblog$ php artisan migrate --database=mysql2 --path=database/migrations2vagrant@homestead:~/abcde/study/myblog$ php artisan migrate:rollback --database=mysql2 --path=database/migrations2

转载地址:http://qmicl.baihongyu.com/

你可能感兴趣的文章
android 语言设置
查看>>
QinQ学习笔记
查看>>
httpd六之源码编译lamp并能够实现xcache为php加速
查看>>
Nagios整合cacti部署详解
查看>>
mysql-5.7.21安装和配置方法
查看>>
ppp链路的pap认证与chap认证的基本原理和配置
查看>>
[Java] 练习题004: 将一个正整数分解质因数
查看>>
速战速决---3小时快速搭建Exchange+SFB(2)
查看>>
关于VCPROJ文件的说明
查看>>
FreeBSD完全新手指南
查看>>
经典广域网技术详解
查看>>
升级Exchange Server 2010 到 SP3时报错
查看>>
Redis配置讲解
查看>>
每天看的资料总结
查看>>
【Python2】04、Python程序控制结构
查看>>
我的友情链接
查看>>
Aspect Oriented Programming杂谈
查看>>
拨开云计算迷雾,助力企业业务创新
查看>>
linux系统管理之单机系统管理 - 文件系统
查看>>
MongoDB的安装及PHP扩展安装
查看>>