基于 Optimus Id 的数据库自增 id 隐藏方案

目前尝试过 snowflake, uuid, hashids 等形式的方案.

  • snowflake 生成的 id 能满足需求, 但是有个问题是 id 长度太长, 给前端的时候需要转成 string, 如果把这个 string id 在 MySQL 8 下进行查询的时候, 会无法查询到(具体表现为一个为 bigint 且有索引的字段和另一个字段 Where 的时候, 在 PHP PDO 下以 String 类型查询在这个bigint 无法查询到, 水平有限跟踪到 PDO层面, 问题应该出在参数绑定上).

  • uuid 太长, 太丑

  • hashids 包含字母, 也觉得丑

今天在 hashids.org上偶然发现一个 optimus 的推荐, hashids 对它的介绍是:

If you need your ids to consist of only numbers, check out Optimus. It’s based on Knuth’s integer hash method and produces obfuscated integer ids (and does it faster too). There are PHP and G0 implementations.

好家伙, 这不就是我想要的吗.☺️

安装(需要 GMP 扩展支持)

composer require jenssegers/optimus

使用

php vendor/bin/optimus spark

Prime: 1527589457
Inverse: 1570528945
Random: 1457286732
Bit length: 31

    new Optimus(1527589457, 1570528945, 1457286732, 31);

Laravel 中使用

// config/optimus.php
return [
  'prime' => env('OPTIMUS_PRIME', 1831559361),
  'inverse' => env('OPTIMUS_INVERSE', 1091482001),
  'random' => env('OPTIMUS_RANDOM', 95201620),
  'bit_length' => env('OPTIMUS_BIT_LENGTH', 31),
];

// app/Providers/OptimusIdServiceProvider.php
...
public function boot()
{
      $this->app->singleton('OptimusId', fn () => new Optimus(
          config('optimus.prime'),
          config('optimus.inverse'), 
          config('optimus.random'),
          config('optimus.bit_length')
     ));
 }
...

// 
app('OptimusId')->encode(1)
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 9

这个id能保证不重复吗

2年前 评论
sodasix (楼主) 2年前
fatrbaby

看过nanoid吗?

2年前 评论
sodasix (楼主) 2年前

生成的数字挺像一个时间戳的,我觉得hashids更好

2年前 评论
sodasix (楼主) 2年前

个人觉得 uuid 就很好。长就长点丑就丑点,反正不会有人背下来,都是复制粘贴有什么区别。

2年前 评论
sodasix (楼主) 2年前
AbelZou 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!