mattkingshott/snowflake

此包已被废弃,不再维护。作者建议使用 caneara/snowflake 包。

用于创建 Twitter Snowflake 标识符的包

v2.0.6 2022-01-28 10:58 UTC

This package is auto-updated.

Last update: 2023-08-29 12:42:07 UTC


README

此包使 Laravel 应用程序能够创建 Twitter Snowflake 标识符。它是 Godruoyi 创建的优秀的 Snowflake PHP 库的一个非常薄的包装。

什么是 Snowflake?

Snowflake 是 Twitter 设计的一种唯一标识符的形式。在这方面,它们类似于其他唯一标识符算法,例如 UUID 或 ULID。

为什么我应该使用它们?

使用 Snowflake(相对于 UUID 等替代方案)的一些好处包括

  • 它们完全由整数组成。
  • 它们使用的空间更少(16个字符,因此可以放入 BIGINT 中)。
  • 整数的索引速度远快于字符串的索引。
  • 键以时间戳开始,因此可以排序。
  • 键以随机数结束,因此无法猜测表的大小。
  • 数据库比字符串更有效地处理整数。
  • 生成新键的速度更快(小于 1 毫秒)。

安装

使用 Composer 拉取包

composer require caneara/snowflake

配置

Snowflake 包含一个配置文件,其中包含几个你可以用来初始化 Snowflake 服务的设置。你应该首先发布此配置文件

php artisan vendor:publish

分布式架构

此服务允许使用涉及数据中心和工作节点(每个节点负责根据其指定的标识符生成 Snowflakes)的分布式架构设置。为了最大灵活性以及向后兼容性,这是默认配置。

如果你不打算运行分布式架构设置,那么你的第一步应该是将相应的配置值设置为 false

数据中心和工作节点

当使用分布式架构设置时,你需要设置应用程序在生成 Snowflakes 时应使用的数据中心和工作节点。这两个值默认设置为 1,这是一个好的起点,但你可以随着添加更多中心节点来增加这些数字。

这些配置值的最大值是 31。这给你每个数据中心 31 个节点,总共 31 个数据中心。因此,你可以有最多 961 个工作节点,每个节点生成唯一的 Snowflakes。

如果你已经禁用了分布式架构,那么你可以跳过数据中心和工作节点值,因为它们将被服务忽略。

起始时间戳

该服务将Unix纪元与给定的起始时间戳进行比较,作为生成唯一Snowflake的过程的一部分。因此,可以使用任何给定的起始时间戳生成最多69年的Snowflake。

在大多数情况下,您应该使用YYYY-MM-DD格式将该值设置为当前日期。

请不要将时间戳设置为未来的日期,因为这不会产生任何效果。您还应避免使用过去的日期,因为这可能会减少您可以生成时间戳的年数。

序列解析器

为了处理同一毫秒内唯一键的生成,该服务使用序列解析器。有几种选择,但它们各自都有依赖项,例如Redis。您可以使用任何一种,但默认选项是一个不错的选择,因为它没有任何依赖项。

用法

您可以通过从容器中解析服务并调用其id方法来生成Snowflake。

resolve('snowflake')->id(); // (string) "5585066784854016"

警告:请不要创建Snowflake服务的实例,因为这可能导致生成匹配的键/引入冲突。相反,始终从容器中解析Snowflake单例。您还可以使用全局辅助方法(见下文)。

由于这有点繁琐,该包还注册了一个全局的snowflake()辅助方法,您可以在任何地方使用。

snowflake(); // (string) "5585066784854016"

数据库

如果您想在数据库中使用Snowflake,例如用于主键和外键,那么您需要执行几个步骤。

首先,修改您的迁移,使其使用Snowflake迁移方法,例如:

// Before
$table->id();
$table->foreignId('user_id');
$table->foreignIdFor(User::class);

// After
$table->snowflake()->primary();
$table->foreignSnowflake('user_id');
$table->foreignSnowflakeFor(User::class);

以下是一个示例

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function(Blueprint $table) {
            $table->snowflake()->primary();
            $table->foreignSnowflake('user_id')->constrained()->cascadeOnDelete();
            $table->string('title', 100);
            $table->timestamps();
        });
    }
}

接下来,如果您正在使用Eloquent,请将包的Snowflakes特质添加到您的Eloquent模型中。

<?php

namespace App\Models;

use Snowflake\Snowflakes;

class Post extends Model
{
    use Snowflakes;
}

最后,配置模型的$casts数组,使其使用包的SnowflakeCast对所有Snowflake属性进行转换。此转换自动处理从stringinteger以及反之的转换,当在数据库中存储或检索Snowflake时。它还确保不支持64位整数的语言(如JavaScript)不会截断Snowflake。

<?php

namespace App\Models;

use Snowflake\Snowflakes;
use Snowflake\SnowflakeCast;

class Post extends Model
{
    use Snowflakes;

    protected $casts = [
        'id'      => SnowflakeCast::class,
        'user_id' => SnowflakeCast::class,
        'title'   => 'string',
    ];
}

贡献

感谢您考虑为Snowflake做出贡献。您欢迎提交包含改进的PR,但是如果您所做的改进是实质性的,请务必包括测试或测试。

许可

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