spatie/laravel-binary-uuid

此包已被弃用且不再维护。作者建议使用 https://github.com/michaeldyrynda/laravel-efficient-uuid 包代替。

Laravel中对UUID的二进制支持

1.3.0 2018-09-24 07:07 UTC

This package is auto-updated.

Last update: 2022-02-01 13:11:03 UTC


README

此包不再维护

替代方案: https://github.com/michaeldyrynda/laravel-efficient-uuid & https://github.com/michaeldyrynda/laravel-model-uuid

在Laravel中使用优化后的二进制UUID

Latest Version on Packagist Build Status Code coverage Quality Score StyleCI Total Downloads

将常规uuid用作主键一定会很慢。

此包通过存储略微调整的二进制版本的uuid来解决性能问题。您可以在此处了解更多关于存储机制的信息: http://mysqlserverteam.com/storing-uuid-values-in-mysql-tables/

该包可以生成优化的uuid版本。它还提供了方便的模型作用域,可以轻松检索使用二进制uuid的模型。

想要测试系统上的性能改进吗?没问题,我们已包含 benchmarks

该包目前仅支持MySQL和SQLite。

安装

您可以通过Composer安装此包

composer require spatie/laravel-binary-uuid

用法

要使模型使用优化后的UUID,您必须将表中的“uuid”字段添加为主字段。

Schema::create('table_name', function (Blueprint $table) {
    $table->uuid('uuid');
    $table->primary('uuid');
});

要使模型能够与编码后的UUID(即使用uuid作为主键)一起工作,您必须让模型使用 Spatie\BinaryUuid\HasBinaryUuid 特性。

use Illuminate\Database\Eloquent\Model;
use Spatie\BinaryUuid\HasBinaryUuid;

class TestModel extends Model
{
    use HasBinaryUuid;
}

如果您不喜欢主键名为 uuid,可以手动指定 getKeyName 方法。不要忘记将 $incrementing 设置为 false。

use Illuminate\Database\Eloquent\Model;
use Spatie\BinaryUuid\HasBinaryUuid;

class TestModel extends Model
{
    use HasBinaryUuid;

    public $incrementing = false;
    
    public function getKeyName()
    {
        return 'custom_uuid';
    }
}

如果您尝试使用二进制属性将模型转换为JSON,您将看到错误。通过在您的模型上声明 $uuidAttributes,您将告诉包在转换为数组时将那些UUID转换为文本。这也为每个uuid属性添加了一个动态访问器。

use Illuminate\Database\Eloquent\Model;
use Spatie\BinaryUuid\HasBinaryUuid;

class TestModel extends Model
{
    use HasBinaryUuid;
    
    /**
     * The suffix for the uuid text attribute 
     * by default this is '_text'
     * 
     * @var
     */
    protected $uuidSuffix = '_str';
    
    /**
     * The binary UUID attributes that should be converted to text.
     *
     * @var array
     */
    protected $uuids = [
        'country_uuid' // foreign or related key
    ];
}

在您的JSON中,您将看到以文本形式表示的 uuidcountry_uuid。如果您还使用复合主键,上面的操作也足够好。只需将您的键包含在 $uuids 数组中,或覆盖模型上的 getKeyName() 方法,并返回作为键数组的复合主键。您还可以自定义UUID文本属性后缀名称。在上面的代码中,它不是 '_text',而是 '_str'。

模型中的 $uuids 数组定义了在检索时转换为uuid字符串以及在写入数据库时转换为二进制的字段。您不需要在模型中的 $casts 数组中定义这些字段。

关于 uuid 蓝图方法的说明

Laravel目前不允许添加新的蓝图方法,这些方法可以直接使用。因此,我们决定覆盖 uuid 的行为,这将创建一个 BINARY 列而不是 CHAR(36) 列。

在某些情况下,Laravel 生成的代码也会使用 uuid,但不支持我们的二进制实现。例如,数据库通知。为了让这些通知工作,您需要更改这些通知的迁移以使用 CHAR(36)

// $table->uuid('id')->primary();

$table->char('id', 36)->primary();

创建模型

模型的 UUID 在保存时会自动生成。

$model = MyModel::create();

dump($model->uuid); // b"\x11þ╩ÓB#(ªë\x1FîàÉ\x1EÝ." 

获取可读的 UUID

UUIDs 仅以二进制形式存储在数据库中。但是,您可以使用文本版本,例如用于 URL 生成。

$model = MyModel::create();

dump($model->uuid_text); // "6dae40fa-cae0-11e7-80b6-8c85901eed2e" 

如果您在创建模型之前想设置特定的 UUID,这也是可能的。

但您不太可能想这样做。

$model = new MyModel();

$model->uuid_text = $uuid;

$model->save();

查询模型

查询数据库的最优方式

$uuid = 'ff8683dc-cadd-11e7-9547-8c85901eed2e'; // UUID from eg. the URL.

$model = MyModel::withUuid($uuid)->first();

withUuid 范围会自动将 UUID 字符串编码以查询数据库。手动方法可能如下所示。

$model = MyModel::where('uuid', MyModel::encodeUuid($uuid))->first();

您还可以使用 withUuid 范围查询多个 UUID。

$models = MyModel::withUuid([
    'ff8683dc-cadd-11e7-9547-8c85901eed2e',
    'ff8683ab-cadd-11e7-9547-8c85900eed2t',
])->get();

注意:版本 1.3.0 为使用 uuid 字符串查找数据添加了简化语法。

$uuid = 'ff8683dc-cadd-11e7-9547-8c85901eed2e'; // UUID from eg. the URL.

$model = MyModel::find($uuid);  

$model = MyModel::findOrFail($uuid);

版本 1.3.0 查询多个 UUID。

$uuids = [
    'ff8683dc-cadd-11e7-9547-8c85901eed2e',
    'ff8683ab-cadd-11e7-9547-8c85900eed2t',
];

$model = MyModel::findMany($uuids);

查询关系

您还可以使用 withUuid 范围通过指定查询字段来查询关系字段。

$models = MyModel::withUuid('ff8683dc-cadd-11e7-9547-8c85901eed2e', 'relation_field')->get();

$models = MyModel::withUuid([
    'ff8683dc-cadd-11e7-9547-8c85901eed2e',
    'ff8683ab-cadd-11e7-9547-8c85900eed2t',
], 'relation_field')->get();

运行基准测试

该包包含基准测试,证明以调整后的二进制形式存储 UUIDs 确实性能更优。

在运行测试之前,您应该设置一个 MySQL 数据库并在 phpunit.xml.dist 中指定连接配置。

要运行测试,请执行此命令。

phpunit -d memory_limit=-1 --testsuite=benchmarks

运行基准测试可能需要几分钟时间。您将有时间喝几杯咖啡!

在测试运行时,平均结果将在终端输出。测试完成后,您将在测试文件夹中找到单个查询统计信息的 CSV 文件。

您可以使用这些数据进一步调查本地机器中 UUID 的性能。

以下是我们在机器上运行的基准测试的一些结果。

普通 ID、二进制 UUID 和优化 UUID 方法的比较。优化 UUIDs 在大数据集中优于所有其他方法。

Comparing different methods

测试

composer test

变更日志

请参阅 CHANGELOG 了解最近更改了哪些信息。

贡献

请参阅 CONTRIBUTING 了解详细信息。

安全

如果您发现任何与安全相关的问题,请通过电子邮件 freek@spatie.be 而不是使用问题跟踪器。

明信片软件

您可以使用此包,但如果它进入您的生产环境,我们非常感谢您从家乡给我们寄一张明信片,说明您正在使用我们的哪些包。

我们的地址是:Spatie,Samberstraat 69D,2060 安特卫普,比利时。

我们将在公司网站上发布所有收到的明信片。请点击此处查看

致谢

支持我们

Spatie是一家位于比利时安特卫普的网页设计公司。您可以在我们的网站上找到我们所有开源项目的概览。点击此处查看

您的业务是否依赖于我们的贡献?请通过Patreon联系我们并提供支持。所有承诺都将用于分配人力以维护和开发新功能。

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件