ホームページ >php教程 >PHP开发 >PHP で一意の ID を生成するための SnowFlake アルゴリズム

PHP で一意の ID を生成するための SnowFlake アルゴリズム

高洛峰
高洛峰オリジナル
2016-12-28 15:33:501404ブラウズ

前書き: 最近 CMS システムを構築する必要があり、機能が比較的単一で要件が柔軟であるため、WP のような成熟したシステムをあきらめて、比較的単純なシステムを自分で構築しました。記事詳細ページの URL を擬似静的 URL 形式、つまり xxx.html にしたいと考えています。xxx では、自動インクリメントされる主キーを直接使用することを検討していますが、これでは記事数がバレてしまう可能性があると感じています。初期値を高く設定できるとのことですが、それでも可能です。期間内の記事数は ID の差に基づいて計算されるため、固有の ID を生成できるアルゴリズムが必要です。

私が検討した方法には

タイムスタンプを直接使用する方法、またはそこから派生した一連の方法

Mysql独自のuuid

上記の2つの方法は見つけることができるので、多くは説明しません

最後の選択Twitter の SnowFlake アルゴリズム

このアルゴリズムの利点は非常にシンプルで、1 秒あたり約 400 万個の異なる 16 桁の ID (10 進数) を生成できます

ID は 64 ビットで構成されます

最初のビットは Vacancy です。

41ビットはミリ秒レベルのタイムスタンプを保存するために使用されます

10ビットはマシンIDを保存するために使用されます

12ビットは自動インクリメントされたIDを保存するために使用されます

使用不可としてマークされた最上位ビットを除き、ビット位置の残りの3つのグループは使用できますそれは特定のビジネスニーズによって異なります。デフォルトでは、41 ビットのタイムスタンプは 2082 年までこのアルゴリズムの使用をサポートし、10 ビットの作業マシン ID は 1023 台のマシンをサポートし、シリアル番号は 4095 個の自動インクリメント シーケンス ID の生成に 1 ミリ秒をサポートします。

以下はPHPのソースコードです

​​
<?php
namespace App\Services;
 
abstract class Particle {
  const EPOCH = 1479533469598;
  const max12bit = 4095;
  const max41bit = 1099511627775;
 
  static $machineId = null;
 
  public static function machineId($mId = 0) {
    self::$machineId = $mId;
  }
 
  public static function generateParticle() {
    /*
    * Time - 42 bits
    */
    $time = floor(microtime(true) * 1000);
 
    /*
    * Substract custom epoch from current time
    */
    $time -= self::EPOCH;
 
    /*
    * Create a base and add time to it
    */
    $base = decbin(self::max41bit + $time);
 
 
    /*
    * Configured machine id - 10 bits - up to 1024 machines
    */
    if(!self::$machineId) {
      $machineid = self::$machineId;
    } else {
      $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT);
    }
     
    /*
    * sequence number - 12 bits - up to 4096 random numbers per machine
    */
    $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT);
 
    /*
    * Pack
    */
    $base = $base.$machineid.$random;
 
    /*
    * Return unique time id no
    */
    return bindec($base);
  }
 
  public static function timeFromParticle($particle) {
    /*
    * Return time
    */
    return bindec(substr(decbin($particle),0,41)) - self::max41bit + self::EPOCH;
  }
}
 
?>

呼び出しメソッドは以下の通りです

Particle::generateParticle($machineId);//生成ID
Particle::timeFromParticle($particle);//反向计算时间戳

ここで、あまり多くのIDを使用しない場合があるため、マシンIDに0を渡すと10ビットが削除されます

さらに PHP は一意の ID SnowFlake を生成します アルゴリズム関連の記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。