雪花アルゴリズムsnoflake

3275 ワード

開発されたほとんどのプロジェクトは百万級同時に接触していないが、これまでid生成の葛藤があった.私は普通年月日+乱数で唯一のidを生成して、一般的に1つの予備のランダムなデータを生成して、毎回値を取って翌日再び1つから取ります.解決できるのですが、なんだかこれがややこしく感じて、資料をよく調べて検討してみましたが、ここではuuid、Vesta、Twitter-Snowflakeなどについて言及しています.文章の中からuuidはphpの中ですでに専門的な拡張あるいは書き方があって唯一の文字列を生成して大きい同時データの中で効率を処理するのはやはりよくありません.他のいくつかの方法はデータベースに役立ちます......この雪のアルゴリズムを調べてみると、やはり操作する価値があることがわかりました.
雪のアルゴリズムの基本的な説明
1.       ,   0,   。 
2.41      ,      ,41        69 。                        。
3.10      ,10          1024   。
4.12       ,          id,                ID  ,12                  4096 ID  。

以上の説明と参考雪花アルゴリズムとPHP、phpベースの雪花アルゴリズムなどの内容に基づいて、私のローカルテストコードは以下の通りです.
 $this->max_data_center) {
        throw new Exception('          ,     :0-' . $this->max_data_center);
    }
    if ($unix_id > $this->max_unix) {
        throw new Exception('        ,     :0-' . $this->max_unix);
    }
    $this->data_center_id = $data_center_id;
    $this->unix_id = $unix_id;
}

public function generateId()
{
    $sign = 0;
    $unix_time = $this->getUnixTime();
    //     
    if ($unix_time < $this->last_time) {
        throw new Exception('              !');
    }
    if ($unix_time == $this->last_time) {
        $serial = ++$this->serial;
        if ($serial == $this->max_serial) {
            $unix_time = $this->getUnixTime();
            while ($unix_time <= $this->last_time) {
                $unix_time = $this->getUnixTime();
            }
            $this->serial = 0;
            $serial = ++$this->serial;
        }
    } else {
        $this->serial = 0;
        $serial = ++$this->serial;
    }
    $this->last_time = $unix_time;
    $time = (int)($unix_time - self::EPOCH_OFFSET);
    $id = ($sign << $this->sign_left_shift) | ($time << $this->time_left_shift)
        | ($this->data_center_id << $this->data_center_left_shift)
        | ($this->unix_id << $this->unix_left_shift) | $serial;
    return $id;
}

public function getUnixTime()
{
    return floor(microtime(true) * 1000);
}
}

$data=new snowflake(1,1);
$get_id=$data->generateId();

echo $get_id.PHP_EOL;