生成数百个随机唯一优惠券代码并插入数据库
Generate hundreds of random unique coupon codes and insert in database
我正在使用 PHP laravel 7
我有一张优惠券 table,其中有一个名为代码的字段,这个代码是 8 个字符(数字和字符)
此代码在优惠券记录中应该是唯一的,
在管理面板中,我有一个供管理员用户使用的按钮,他可以单击该按钮并生成任意数量的优惠券。
我将与您分享我想到的最佳解决方案,并询问您是否有更好、更高性能的解决方案。
我将使用以下函数在我的 php 代码中生成唯一字符串:
substr(uniqid(), 0, 8)
然后我将执行查询以检查我的 table 中是否有任何优惠券,它的代码等于我新生成的代码之一
$model->newQuery()->whereIn('code', $generated_codes)->get();
如果结果列表为空,那很好,我会将我的所有代码插入数据库。如果列表不为空,我将从我生成的代码中删除重复代码,并且再次根据重复代码的数量再次生成新代码并再次重复该过程,只要 none 的生成代码存在于数据库中
然后我将它们插入数据库。
我的问题与这个问题不同:
PHP: How to generate a random, unique, alphanumeric string?
因为我要生成很多独特的代码,而不仅仅是代码,然后我要把这些代码插入数据库,我需要有最少数量的查询。
您可以使用此类功能来获取唯一的优惠券代码。
function generateCode(){
$code = substr(uniqid(), 0, 8);
$exists = YourModel::where('code', $code)->count();
if($exists > 0){
$this->generateCode();
}
return $code;
}
你可以使用firstOrCreate(),但实际上它可能会执行很多查询。希望它能帮助你找到好的解决方案
public function initCoupon()
{
$code = substr(uniqid(), 0, 8);
$new = false;
do {
$coupon = CouponModel::firstOrCreate(compact('code'));
$new = $coupon->wasRecentlyCreated
} while(!$new);
return $coupon;
}
比你可以设置额外的优惠券数据
这里有一些可能有用的东西:
function generateRandomCodes($number) {
$codes = Collection::times($number, function () { Str::random(8); });
$affected = DB::table('your_table')
->insertOrIgnore($codes->map(function ($code) {
return [ 'code' => $code, /* more fields? */ ];
});
if ($affected < $number) {
generateRandomCodes($number-$affected);
}
}
insertOrIgnore
会在插入和覆盖数据时忽略重复键。这很有用,因为它避免了插入之前的查找,这可能是昂贵的,这个 shouldreturn affected 行的数量,即新创建的行。如果它没有设法插入所有需要的代码,那么它 应该 运行 再次插入剩余的代码。这一切都假设 code
是主键。
我自己没有对此进行测试,因此我建议您在将其用于任何生产代码之前对其进行测试。
一些补充说明:
Str::random
在内部使用来自 random_bytes
的 base64 编码字符串,它在密码学上是安全的(尽管不确定它的 base64 版本在技术上是否算作安全的,也不确定最终结果是否真的安全) .这意味着有 62^8 = 2*10^14 种组合可以得到字符(+、= 和 / 被删除)。这是一个非常高的数字,在您生成这些数字的大约 10%(大约 2*10^13)之前,您不应该真正期望发生碰撞 然而 这假设您是将它们存储在数据库的 区分大小写 列中,默认情况下,字符串列 不 区分大小写,这会将您的独特组合减少大约三分之二(这仍然是一个相当大的数字)意味着你真的不需要多次调用这个函数,除非你真的是 "lucky"
我正在使用 PHP laravel 7 我有一张优惠券 table,其中有一个名为代码的字段,这个代码是 8 个字符(数字和字符) 此代码在优惠券记录中应该是唯一的, 在管理面板中,我有一个供管理员用户使用的按钮,他可以单击该按钮并生成任意数量的优惠券。 我将与您分享我想到的最佳解决方案,并询问您是否有更好、更高性能的解决方案。
我将使用以下函数在我的 php 代码中生成唯一字符串:
substr(uniqid(), 0, 8)
然后我将执行查询以检查我的 table 中是否有任何优惠券,它的代码等于我新生成的代码之一
$model->newQuery()->whereIn('code', $generated_codes)->get();
如果结果列表为空,那很好,我会将我的所有代码插入数据库。如果列表不为空,我将从我生成的代码中删除重复代码,并且再次根据重复代码的数量再次生成新代码并再次重复该过程,只要 none 的生成代码存在于数据库中 然后我将它们插入数据库。
我的问题与这个问题不同: PHP: How to generate a random, unique, alphanumeric string?
因为我要生成很多独特的代码,而不仅仅是代码,然后我要把这些代码插入数据库,我需要有最少数量的查询。
您可以使用此类功能来获取唯一的优惠券代码。
function generateCode(){
$code = substr(uniqid(), 0, 8);
$exists = YourModel::where('code', $code)->count();
if($exists > 0){
$this->generateCode();
}
return $code;
}
你可以使用firstOrCreate(),但实际上它可能会执行很多查询。希望它能帮助你找到好的解决方案
public function initCoupon()
{
$code = substr(uniqid(), 0, 8);
$new = false;
do {
$coupon = CouponModel::firstOrCreate(compact('code'));
$new = $coupon->wasRecentlyCreated
} while(!$new);
return $coupon;
}
比你可以设置额外的优惠券数据
这里有一些可能有用的东西:
function generateRandomCodes($number) {
$codes = Collection::times($number, function () { Str::random(8); });
$affected = DB::table('your_table')
->insertOrIgnore($codes->map(function ($code) {
return [ 'code' => $code, /* more fields? */ ];
});
if ($affected < $number) {
generateRandomCodes($number-$affected);
}
}
insertOrIgnore
会在插入和覆盖数据时忽略重复键。这很有用,因为它避免了插入之前的查找,这可能是昂贵的,这个 shouldreturn affected 行的数量,即新创建的行。如果它没有设法插入所有需要的代码,那么它 应该 运行 再次插入剩余的代码。这一切都假设 code
是主键。
我自己没有对此进行测试,因此我建议您在将其用于任何生产代码之前对其进行测试。
一些补充说明:
Str::random
在内部使用来自 random_bytes
的 base64 编码字符串,它在密码学上是安全的(尽管不确定它的 base64 版本在技术上是否算作安全的,也不确定最终结果是否真的安全) .这意味着有 62^8 = 2*10^14 种组合可以得到字符(+、= 和 / 被删除)。这是一个非常高的数字,在您生成这些数字的大约 10%(大约 2*10^13)之前,您不应该真正期望发生碰撞 然而 这假设您是将它们存储在数据库的 区分大小写 列中,默认情况下,字符串列 不 区分大小写,这会将您的独特组合减少大约三分之二(这仍然是一个相当大的数字)意味着你真的不需要多次调用这个函数,除非你真的是 "lucky"