首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >防止种子设定唯一密钥冲突

防止种子设定唯一密钥冲突
EN

Stack Overflow用户
提问于 2015-08-13 00:55:14
回答 3查看 1.1K关注 0票数 2

我的数据库中有两个列的唯一约束。

代码语言:javascript
运行
复制
$table->unique(array("table_a_id", "table_b_id"));

现在我在一个种子类中使用Faker来填充这个数据透视表:

代码语言:javascript
运行
复制
$tableAIds = TableA::all()->lists("id")->toArray();
$tableBIds = TableB::all()->lists("id")->toArray();

foreach(range(1, 20) as $index) {
    $tableAId = $faker->randomElement($tableAIds);
    $tableBId = $faker->randomElement($tableBIds);

    DB::table("table_a_table_b_pivot")->insert([
        "table_a_id" => $tableAId,
        "table_b_id" => $tableBId
    ]);
}

但是,这会创建重复项,并且由于SQL错误而导致种子设定失败。

如何确保不会尝试插入重复项?

EN

回答 3

Stack Overflow用户

发布于 2016-11-27 22:25:26

您可以使用以下命令:

代码语言:javascript
运行
复制
$tableAIds = TableA::all()->lists("id")->toArray();
$tableBIds = TableB::all()->lists("id")->toArray();
foreach (range(1, 20) as $index) {
    repeat:
    $tableAId = $faker->randomElement($tableAIds);
    $tableBId = $faker->randomElement($tableBIds);
    try {
        DB::table("table_a_table_b_pivot")->insert([
            "table_a_id" => $tableAId,
            "table_b_id" => $tableBId,
        ]);
   } catch (\Illuminate\Database\QueryException $e) {
            //look for integrity violation exception (23000)
            if($e->errorInfo[0]==23000)
              goto repeat;
   }
}

Ps:如果TableA和TableB数据从一开始就不一致,这可能不起作用(这意味着不可能从这些数据中形成20个唯一对)

票数 1
EN

Stack Overflow用户

发布于 2017-08-19 06:26:53

代码语言:javascript
运行
复制
$unique = $faker->unique()->regexify('[0-4][0-9][0-4][0-9]');

上面的代码将产生一个由0到49之间的两个数字组成的字符串,该字符串永远不会重复。现在,您可以将其一分为二,并安全地为您的数据库设定种子。

代码语言:javascript
运行
复制
$firstId = ltrim(substr($unique, 0, 2), '0') + 1;
$secondId = ltrim(substr($unique, 2, 2), '0') + 1;

字符串中的两个数字可以相同,但字符串始终是唯一的。不要忘了为每个部分添加一个,因为我们不想(也不能)给我们的数据库添加0种子。

票数 0
EN

Stack Overflow用户

发布于 2015-08-13 01:12:09

不使用faker,而是使用集合的random方法:

代码语言:javascript
运行
复制
$tableAIds = TableA::all()->lists('id')->random(20);
$tableBIds = TableB::all()->lists('id')->random(20);

foreach(range(0, 19) as $index) {
    DB::table("table_a_table_b_pivot")->insert([
        "table_a_id" => $tableAIds[$index],
        "table_b_id" => $tableBIds[$index],
    ]);
}

请根据您的需要进行调整。

例如,这可能是您真正想要的:

代码语言:javascript
运行
复制
$tableAIds = TableA::all()->lists('id');
$tableBIds = TableB::all()->lists('id');

foreach ($tableAIds->random(5) as $tableAId) {
    foreach ($tableBIds->random(2) as $tableBId) {
        DB::table("table_a_table_b_pivot")->insert([
            "table_a_id" => $tableAId,
            "table_b_id" => $tableBId,
        ]);
    }
}

不管它是什么,你自己去玩吧。这里不需要冒牌货。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31971207

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档