Laravel UUID 及其唯一性?

Laravel UUID's and their uniqueness?

我有两个表,一个用于 lists,另一个存储创建的 listshistory。这些 lists 非常临时,可以通过多种方法删除它们,因此我为此在历史记录中添加了一个 reason 字段。

//Lists table
Schema::create('lists', function (Blueprint $table) {
  $table->increments('id');
  $table->string('name');
  $table->text('message');
  $table->uuid('uuid');
  $table->timestamps();
});

//History table
Schema::create('history', function (Blueprint $table) {
  $table->increments('id');
  $table->string('name');
  $table->text('message');
  $table->string('reason');
  $table->uuid('uuid');
  $table->timestamps();
});

现在两者都有一个 uuid 字段,我可以生成一个实际的字符串来存储 Laravel 的辅助函数 $uuid = (string) Str::uuid();

$list = new List;
$list->name = 'A basic fact of life';
$list->message = 'Pineapple does not belong on pizza.'
$uuid = (string) Str::uuid();
$list->uuid = $uuid;
$list->save();

现在,当我从 Lists 中成功删除一条记录时,我会在历史记录中另外创建一条新记录及其数据。

$list = find($id);
$destroy = List::destroy($id);
if($destroy) {
  $history = new History;
  $history->name = $list->name;
  $history->message $list->message;
  $history->uuid = $list->uuid;
  $history->reason = 'some reason';
  $history->save();
}

所以我的问题是,Laravel 如何知道 我生成的下一个 UUID 实际上是唯一的?

链接的所谓重复问题实际上并没有说明它如何或是否知道下一个 UUID 实际上对于过去创建的 UUID 是唯一的,而是给出了一个概率。

UUID is short for “universal unique identifier” which is a set of 36 characters, containing letters and numbers. Each set should be unique, with there only being a chance for repetition each 100 years, you can read more about it and check out some cool statistics here and here.

来源: What is a UUID

Laravel 实现 UUID v4, defined by RFC 4122 是唯一的。 RFC 声明(强调我的):

Identifier uniqueness considerations:
This document specifies three algorithms to generate UUIDs: the first leverages the unique values of 802 MAC addresses to guarantee uniqueness, the second uses pseudo-random number generators, and the third uses cryptographic hashing and application-provided text strings. As a result, the UUIDs generated according to the mechanisms here will be unique from all other UUIDs that have been or will be assigned.

Laravel 并不太“知道”它是唯一的,而是“相信”它是因为该算法被定义为相对于由该算法生成的所有其他算法而言是唯一的 算法.

这里有一个重要的警告。该算法需要足够的熵源来保证其熵的commonly cited claim that you'd need to create trillions a day for the next 100 years to have a 50/50 chance of a dupe. To that end, Laravel leans on ramsey/uuid to do the actual v4 generation. ramsey/uuid uses, long story short, random_bytes。这是一个强大的加密来源,足以根据 RFC 获得 v4 生成资格。现在是重要的部分:

If none of the aforementioned sources are available, then an Exception will be thrown.

因此,当您的代码无法生成真正随机的全局唯一值时,(string)Str::uuid() 将抛出异常。

根据之前的评论,Laravel 生成的 UUID 很少会重复。您至少可以做的是让数据库检查该 UUID 是否存在。所以当你创建一个新列表时,你可以有这样的东西。

for($i=0; $i<5; $i++)
{

$uuid = (string) Str::uuid();
if(!DB::table('lists')->where('uuid',$uuid)->first())
{
$list = new List;
$list->name = 'A basic fact of life';
$list->message = 'Pineapple does not belong on pizza.'
$uuid = (string) Str::uuid();
$list->uuid = $uuid;
$list->save();

break;
}

}


这将 运行 for 循环一次,它再次 运行ning 的机会与 uuid 重复自身的机会相同,即每秒 1 万亿次,持续 100 年。 ..

这将确保您的 uuid 始终是唯一的,尽管它可能会因为 db 调用而增加一些额外的时间,但如果您乐于在这里和那里牺牲一些 ms,那么这可能是确保每个 uuid 的方法之一是独一无二的。