【问题标题】:Recommended / Standard handling of Laravel Data MigrationsLaravel 数据迁移的推荐/标准处理
【发布时间】:2021-05-28 05:12:54
【问题描述】:

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

我的问题是,data 迁移是否应该直接在 database 迁移文件中进行?应该是播种机吗?它应该是从数据库迁移中分派的工作吗?这样的逻辑应该去哪里。有时这些数据迁移可能会变得异常复杂,具体取决于数据库迁移所做的事情,并且本着最大化可读性和保持职责分离的精神,我感觉逻辑属于其他地方。

我认为,这个问题更多地归因于 OOP 编程结构和整体实践,而不是特定于 laravel,但 Laravel 是我现在正在使用的框架,因此在这方面构建了我的问题。

【问题讨论】:

    标签: laravel database-migration data-migration conceptual


    【解决方案1】:

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

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

    <?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-&gt;temporary(); 选项以创建临时表以使用 SQL 进行数据操作,和/或制作在迁移中调用的命令脚本Artisan::call()

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

    【讨论】:

      【解决方案2】:

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

      在以下情况下,有条件迁移可能包含数据更改:

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

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

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

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

      【讨论】:

        【解决方案3】:

        添加@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');
            });
        

        【讨论】:

          猜你喜欢
          • 2020-12-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-29
          • 2012-09-10
          • 1970-01-01
          • 2014-06-23
          • 1970-01-01
          相关资源
          最近更新 更多