lara-pkg/laravel-binary-uuid

Laravel 中 UUID 的二进制支持

1.3.0 2018-09-24 07:07 UTC

This package is auto-updated.

Last update: 2024-09-15 05:08:00 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 的模型。

想要测试您系统上的性能改进?没问题,我们已经包含了基准测试

该包目前仅支持 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();

运行基准测试

该包包含基准测试,证明将 uuid 存储为调整后的二进制形式确实性能更高。

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

要运行测试,请发出此命令。

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

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

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

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

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

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

Comparing different methods

测试

composer test

变更日志

有关最近更改的更多信息,请参阅 CHANGELOG

贡献

有关详细信息,请参阅 CONTRIBUTING

安全性

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

明信片软件

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

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

我们在我们的公司网站上发布所有收到的明信片 在这里

致谢

支持我们

Spatie 是一家总部位于比利时的安特卫普的网页设计公司。您可以在我们的网站上找到我们所有开源项目的概述 这里

您的业务依赖于我们的贡献吗?联系我们在 Patreon 上支持我们。所有承诺都将专门用于分配人员维护和新奇事物。

许可证

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