本文介绍一种避免重复冲突、无需循环重试的 laravel 唯一编号生成方案:利用自增主键 id 与随机前缀组合,确保全局唯一、高性能且无限可扩展。
在 Laravel 应用中,为模型(如 Ticket)生成唯一、人类可读且具备业务意义的编号时,直接依赖 mt_rand() 配合数据库查重(如 where('number', $rand)->exists())存在严重隐患:随着数据量增长,碰撞概率上升,递归重试可能引发栈溢出、性能陡降,甚至死循环。更关键的是,该方式违背了“唯一性应由设计保障,而非概率试探”的工程原则。
✅ 推荐方案:ID 衍生 + 随机前缀(非随机全量)
利用 Eloquent 的 created 模型事件(在记录已成功写入数据库、ID 已确定后触发),将不可变的自增主键 id 作为唯一性基石,再拼接可控范围的随机前缀,既保证绝对唯一,又兼顾可读性与扩展性。
// app/Providers/AppServiceProvider.php 或专用模型观察者中注册
use App\Models\Ticket;
public function boot()
{
Ticket::created(function (Ticket $ticket) {
// 生成 4 位随机前缀(1000–9999),拼接 3 位左补零的 ID(如 id=7 → "007")
$prefix = rand(1000, 9999);
$suffix = str_pad($ticket->id, 3, '0', STR_PAD_LEFT);
$ticket->number = $prefix . $suffix;
// 注意:此时模型已入库,需显式 save() 更新 number 字段
$ticket->save();
});
}? 为什么这比纯随机更优?
⚠️ 注意事项

综上,放弃“随机→查重→重试”的低效模式,转向“确定性 ID + 可控扰动”的设计思维,是构建高可用编号系统的正确起点。