【发布时间】:2021-08-12 20:19:34
【问题描述】:
我正在尝试创建一个数据库迁移 (MySQL) 以回填所有表中的 uuid(大约 80 个表,其中一些具有 130k+ 行)。要直接在 MySQL 中执行此操作,我可以逐表运行:
UPDATE <TABLE_NAME> SET uuid = (SELECT md5(UUID()))';
它确实为每行添加了一个唯一的 UUID。如果我遍历所有表并为每个表运行一个 DB 外观语句:
class BackfillUuidsIntoAllTables extends Migration
{
protected $dbName;
protected $tables;
public function __construct()
{
$this->dbName = config('database.connections.' . config('database.default') . '.database');
$this->tables = DB::select('SHOW TABLES');
}
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
foreach ($this->tables as $table) {
Schema::table($table->{'Tables_in_' . $this->dbName}, function ($table) {
$tableName = $table->getTable();
DB::statement("UPDATE $tableName SET uuid = (SELECT md5(UUID()))");
}
}
}
它执行速度很快,但对整个表使用相同的 uuid。为了运行它,我是否遗漏了一些东西,所以每一行实际上都有一个唯一的 uuid?
【问题讨论】:
-
是的,没有行约束的
UPDATE语句(如WHERE id = 1等)将使用相同的值更新整个表。您的表是否还有像id这样的主要自动递增列?您可以执行foreach(DB::table($tableName)->get() as $row){ DB::statement("UPDATE $tableName SET uuid = (SELECT md5(UUID())) WHERE id = $row['id']"); }(或类似的)之类的操作来为每行生成一个真正唯一的uuid。 -
我明白你在说什么。我想我很困惑,我可以直接在每个表的数据库中运行它,并使用唯一的 uuid 更新每一行,但它在迁移循环中的工作方式不同......我这样做的主要问题是这样是因为它需要很长时间,以至于它实际上使我的管道(Jenkins 到 Azure VM)崩溃。
-
哦,这很有趣。我希望功能是相同的,因为您只是使用
DB::statement(),但不可否认,我对 MySQL 中的UUID()的了解非常有限。是的,根据被修改的行/表的数量,我可以看到这是一个非常强大的过程。抱歉,除此之外我没有更多的见解...... -
您不能将行的唯一 ID 添加到
md5()吗?另外,我不清楚为什么需要嵌套的SELECT。怎么样:UPDATE <tablename> SET uuid = md5(concat(UUID(),id)),假设主键是id -
@Quasipickle - 将行的 id 添加到 md5() 效果很好!是的,子查询背后的想法是每行唯一的 uuid,但由于它无论如何都不起作用,显然不需要。
标签: php mysql laravel laravel-6 laravel-6.2