Laravel 数据迁移的推荐/标准处理

问题描述

Laravel 附带了数据库迁移,用于管理关于数据库结构的 CRUD 操作,但是处理实际数据迁移的合适/推荐/标准化方法是什么?

我的问题是,数据迁移是否应该直接在数据库迁移文件中进行?应该是播种机吗?它应该是从数据库迁移中分派的作业吗?这样的逻辑该何去何从。有时,根据数据库迁移的作用,这些数据迁移会变得异常复杂,本着最大化可读性和保持职责分离的精神,我感觉逻辑属于其他地方。

我想,这个问题更多地归因于 OOP 编程结构和整个实践,而不是 Laravel 特定的,但 Laravel 是我现在正在使用的框架,所以我在这方面提出了我的问题。

解决方法

我已经做过好几次了,我在迁移 up()down() 函数中就这样做了,除非我们谈论的是数百万条记录。我同意你的看法,感觉在迁移中应该有一个明确定义的功能。我们希望在触发表上的另一个迁移之前更改数据,所以我觉得需要立即完成。

使用您的示例,这是将 name 拆分为 first_name 函数中的 last_nameup() 的简单迁移:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

class Test extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users',function (Blueprint $table) {
            $table->string('last_name')->after('name');
            $table->string('first_name')->after('name');
        });

        DB::statement("UPDATE users SET first_name = SUBSTRING_INDEX(name,' ',1),last_name = SUBSTRING(name from instr(name,' ') + 1)");

        Schema::table('users',function (Blueprint $table) {
            $table->dropColumn('name');
        });
    }

...

如果您有复杂的数据更改,请查看 $table->temporary(); 选项以创建临时表以使用 SQL 进行数据操作,和/或制作在使用 Artisan::call() 迁移。

$table->temporary()https://laravel.com/docs/8.x/migrations#database-connection-table-options Artisan::call()https://laravel.com/docs/8.x/artisan#programmatically-executing-commands

,

我更喜欢将数据和结构迁移分开。我认为迁移文件应该只包含与架构相关的查询。

有条件的迁移可能包含数据更改,如果:

  • 数据取决于部署/迁移的时间(实在想不出一个案例,但我确信有一些:))。
  • 我们正在对架构进行直接影响数据的更改。例如:更改列的类型或创建必须在未来迁移之前播种的新键。

我更喜欢在种子文件中包含数据的其他原因:

  • 在产品上运行迁移总是会带来一定的风险。您可以通过测试部署流程和使用一些花哨的 CD 流程来降低丢失数据的风险,但风险始终存在。

  • 您认为永远不会改变的静态数据,会发生变化。例如,您在 2010 年启动了一个新项目,该项目的数据库包含表“countries”,其中包含国家及其属性的列表。但在 2011 年之后,你会得到一个新的国家:南苏丹。您会创建新的迁移还是只是更新播种机?

,

添加到@jon__o 的答案中,您可以找到更多信息here。另外,我会建议您参考这个 link,他们使用基于 hashed_id 的临时表,其中临时表与数据库中的普通表基本相同。它具有许多对迁移有用的功能。

Schema::create('temp_mappings',function (Blueprint $table) {
        $table->temporary(); // thanks,Laravel
        $table->integer('id')->primary();
        $table->string('hash_id');
    });

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...