以前の記事で、Snowflake IDsについて話しました。それらは素晴らしいですが、「Worker IDs」を管理するための設定が必要なので少し手間がかかります。
もっとシンプルで同じ利点(セキュアなURLと高速なデータベースソート)を提供するものが必要な場合は、ULIDs(Universally Unique Lexicographically Sortable Identifiers)を検討してください。
なぜ UUID を使わないのですか?
大多数の開発者は自動増分整数から UUID に切り替えます。彼らは自分のビジネスの規模を隠したいからです。あなたの注文 ID が order/550e8400-e29b... であれば、あなたが 1 人の顧客を持っているか 100 万人の顧客を持っているか誰も知りません.
しかし UUID には大きな問題があります: 彼らは完全にランダムです。
数百万のランダムUUIDをデータベースに挿入すると、「B-Tree」インデックスがフラグメント化して遅くなります。あなたのデータベースは新しいデータを置く場所を見つけるためにハードドライブのあちこちを飛び回らなければなりません.
ULIDsはこれを解決します.
ULIDは128ビット(UUIDと同じように)、ただしIDの最初の部分はタイムスタンプです これは ULIDs が時系列順であることを意味します。UUID のようにユニークですが、整数のようにソートされます。
Rails 8 アプリで ULIDs を実装する方法は以下の 4 つの簡単なステップです。
ステップ 1:Gem のインストール
ULIDs の文字列を生成するために ulid gem を使用します。Gemfile に次を追加します。
gem "ulid"
走るbundle installターミナルで。
ステップ2:ULIDの懸念
ULIDsを任意のモデルに簡単に追加できるようにしたい。これを行う最良の方法は、心配このコードにより、新しいレコードを作成するたびにULIDが生成され、IDに割り当てられます。
新しいファイルを作成してapp/models/concerns/has_ulid.rb:
# app/models/concerns/has_ulid.rb
module HasUlid
extend ActiveSupport::Concern
included do
# Before we save to the DB, generate the ULID
before_create :set_ulid
end
private
def set_ulid
# ULID.generate creates a string like: 01ARZ3NDEKTSV4RRFFQ69G5FAV
self.id ||= ULID.generate
end
end
ステップ3:マイグレーション
新しいモデルを作成すると、Railsにidがstringであることを伝える必要があり、デフォルトの自動増分ロジックを無効にする必要があります
rails g model Product name:string
マイグレーションファイルを開き、このように編集します:
# db/migrate/XXXXXXXXXXXXXX_create_products.rb
class CreateProducts < ActiveRecord::Migration[8.0]
def change
# id: false stops the automatic integer ID
create_table :products, id: false do |t|
# We use string for ULID primary key
t.string :id, primary_key: true
t.string :name
t.timestamps
end
end
end
ステップ4:モデルを更新
今、ステップ2で書いた懸念を含めます。
# app/models/product.rb
class Product < ApplicationRecord
include HasUlid
end
ステップ5:実際に確認する
あなたのRailsコンソールを開きますbin/rails c と数件の製品を作成します:
Product.create(name: "Laptop")
Product.create(name: "Monitor")
Product.create(name: "Keyboard")
# Check the IDs
Product.pluck(:id)
# => ["01HQV...", "01HQV...", "01HQV..."]
よく見ると、ID はすべて同じ文字で始まります。同じ分に作成されたからです。ソート可能なので、Product.order(:id) を実行して、正しい時系列順序になります!
なぜ私は Rails に ULIDs を好むのか
- より良いパフォーマンス: IDがソート可能であるため、PostgreSQL(またはSQLite)はそれらをインデックスの末尾に追加できます。これは「書き込み重視」アプリケーションにとってランダムなUUIDよりもずっと速くなります。
- 読みやすさ: ULIDsは「I」、「L」、「O」のような混乱を招く文字を含まない特別なアルファベット(CrockfordのBase32)を使用しており、ユーザーがタイプする必要がある場合に読みやすくなります。
- 設定不要: Snowflake IDとは異なり、サーバーIDやワーカーノードを設定する必要はありません。ゲムをインストールして使うだけです.
それだけです。アプリケーションがよりプロフェッショナルでスケーラブルに感じられる小さなアーキテクチャの変更です。












