簡介
Snowflake 是 Twitter 内部的一个 ID 演算法,可以通過演算法建立有序且不重複的ID生成過程不需要依賴網路或任何中間件, 能每秒可生成400萬筆左右。

- 第一個部份保留 (基本不用)
- 第二個部分41位時間戳,單位為毫秒,總共可以容納約 69 年的時間。這里的時間戳只是相對於某個時間點的增量。
- 第三個部分由工作機器ID(5位)與資料庫中心ID組成(5位)
- 第四個部分序列號,紀錄同一毫秒內建立的ID,佔12bit,每毫秒可產生4096個ID
每台機器每秒可產生的ID
2^12 * 2^10 = 2^22 = 4194304
優點
- 系統環境ID不重複
- 生成效率高
- 基於時間戳,有基本遞增排序
- 無須依賴中間件。
缺點
- 長度長(18位),要注意語言型別
- ID不連續,是無規則的
基本使用(以laravel為例)
建立專案
composer create-project laravel/laravel snowflake-demo
開啟專案
php artisan serve
引入套件
composer require caneara/snowflake
建立基本設定檔,輸入以下指令
php artisan vendor:publish
會出現以下畫面,選擇要使用的套件

這邊選擇Snowflake\ServiceProvider,後面對應數字是9,就輸入9按enter會在config裡面建立snowflake.php檔案,對於演算法的資料可以進行修改
建立migration、controller等等資料
php artisan make:model SnowFlake --all
直接使用,將以下程式碼複製到snowflakeController
public function getsnowflake()
{
$snowflake = resolve('snowflake')->id();
return response()->json($snowflake);
}
建立路由,將以下程式碼複製到route/api.php
Route::get('snowflake/get',[SnowflakeController::class,'getsnowflake']);
打開瀏覽器輸入http://127.0.0.1:8000/api/snowflake/get
在eloquent中使用
//migration
$table->snowflake()->primary();
$table->string('name');
$table->timestamps();
//factory
'name' => $this->faker->company()
//Snosflakeseeder
Snowflake::factory()->count(1000)->create();
//DatabaseSeeder
$this->call([SnowflakeSeeder::class]);
model 須引入此程式碼
use Snowflake\\Snowflakes;
use Snowflake\\SnowflakeCast;
//model
use Snowflakes;
protected $casts = [
'id'=> SnowflakeCast::class,
'name'
];
$casts模型是可以將id轉為雪花演算法的類型,SnowflakeCast是讓ID在對資料庫進行存取時可以自動將string轉成int,並且確保不支援int64類型的語言不會截斷ID(ex.JavaSctipt)。
資料庫設定,在.env裡面可以看到這個部分,裡面預設mysql,可以直接拿來使用,記得要先將mysql打開,並到資料庫建立名稱為 laravel (對應.env裡面的DB_DATABASE名稱)的資料表
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
設定完成後,輸入以下指令資料表就建立起來了,可以到自己的mysql介面去看資料
php artisan migrate:fresh --seed
測試是否有重複ID(會將重複資料group起來)
SELECT * FROM `snowflakes` GROUP BY id HAVING COUNT(*) > 1;