maidomax/laravel-binary-uuid

Laravel中对UUID的二进制支持

3.0 2021-03-16 08:43 UTC

This package is auto-updated.

Last update: 2024-09-16 16:42:38 UTC


README

我从Spatie.be的团队那里fork了这个包,因为他们做得很好。我这样做只是为了使其支持Laravel 5.8,因为我在做的一个项目依赖于这个包,而它卡在5.7版本,因为它。

如果您也使用这个包,我很乐意审查您可能提出的任何pull请求。

在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 maidomax/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

UUID仅在数据库中以二进制形式存储。但是,您可以使用文本版本,例如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

变更日志

有关最近更改的更多信息,请参阅变更日志

贡献

有关详细信息,请参阅贡献指南

安全

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

明信片软件

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

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

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

鸣谢

支持我们

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

您的业务是否依赖于我们的贡献?请与我们联系,并在Patreon上支持我们。所有承诺都将用于分配人力以维护和新奇事物。

许可

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