lara-pkg / laravel-binary-uuid
Laravel 中 UUID 的二进制支持
Requires
- php: ^7.1
- illuminate/queue: ~5.5.28|~5.6.0|~5.7.0
- ramsey/uuid: ^3.7
Requires (Dev)
- orchestra/testbench: ^3.5|~3.6.0|~3.7.0
- phpunit/phpunit: ^6.5|^7.0
README
此包不再维护
替代方案: https://github.com/michaeldyrynda/laravel-efficient-uuid & https://github.com/michaeldyrynda/laravel-model-uuid
在 Laravel 中使用优化的二进制 UUID
将常规 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 中,您将看到以文本形式表示的 uuid
和 country_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 在大型数据集中优于其他所有方法。
测试
composer test
变更日志
有关最近更改的更多信息,请参阅 CHANGELOG。
贡献
有关详细信息,请参阅 CONTRIBUTING。
安全性
如果您发现任何与安全相关的问题,请通过电子邮件 freek@spatie.be 而不是使用问题跟踪器。
明信片软件
您可以使用此包,但如果它进入您的生产环境,我们非常感谢您从家乡寄给我们一张明信片,说明您正在使用我们哪些包。
我们的地址是:Spatie,Samberstraat 69D,2060 安特卫普,比利时。
我们在我们的公司网站上发布所有收到的明信片 在这里。
致谢
支持我们
Spatie 是一家总部位于比利时的安特卫普的网页设计公司。您可以在我们的网站上找到我们所有开源项目的概述 这里。
您的业务依赖于我们的贡献吗?联系我们在 Patreon 上支持我们。所有承诺都将专门用于分配人员维护和新奇事物。
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件。