慣性聚合 高效追蹤和閱讀你感興趣的部落格、新聞、科技資訊
閱讀原文 在慣性聚合中打開

推薦訂閱源

小众软件
小众软件
博客园 - 叶小钗
有赞技术团队
有赞技术团队
大猫的无限游戏
大猫的无限游戏
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LangChain Blog
Hugging Face - Blog
Hugging Face - Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
aimingoo的专栏
aimingoo的专栏
Blog — PlanetScale
Blog — PlanetScale
爱范儿
爱范儿
T
Tailwind CSS Blog
Jina AI
Jina AI
量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
V
Visual Studio Blog
月光博客
月光博客

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
更好的主鍵:Rails 開發者的 ULIDs 指南
Zil Norvilis · 2026-05-28 · via DEV Community

在前一篇文章中,我談到了Snowflake IDs。它們很棒,但它們需要一些設定,因為你需要管理「Worker IDs」。

如果你想要一個更簡單的選擇,同時能提供相同的優勢——安全連結和快速數據庫排序——你應該看看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 那樣獨一無二,但排序方式像整數。

這裡是如何在四個簡單步驟中將 ULIDs 實現到您的 Rails 8 應用程式中。

步驟 1:安裝 Gem

我們將使用 ulid gem 來生成字串。將這個添加到您的 Gemfile 中:

gem "ulid"

Enter fullscreen mode Exit fullscreen mode

在你的終端運行 bundle install

第 2 步:ULID 的關注

我們希望將 ULIDs 輕鬆添加到任何模型中。這的最佳方法是一個 關注。這段代碼將確保每當我們創建一條新記錄時,都會生成並分配一個 ULID。

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

進入全螢幕模式 離開全螢幕模式

第四步:更新模型

現在,只要包含我們在第二步中寫的內容。

# app/models/product.rb
class Product < ApplicationRecord
  include HasUlid
end

進入全螢幕模式 離開全螢幕模式

第五步:觀察其運作

開啟您的 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..."]

Enter fullscreen mode Exit fullscreen mode

如果你仔細看,所有的ID都以相同的字元開頭,因為它們是在同一分鐘建立的。由於它們可以排序,你仍然可以運行 Product.order(:id),它們將會以正確的時間順序排列!

我為何喜歡 ULIDs for Rails

  1. 表現更佳: 由於 ID 可排序,PostgreSQL (或 SQLite) 可以將它們附加到索引的末尾。這對於「寫入密集型」應用程式比隨機 UUID 快得多。
  2. 易讀性: ULIDs 使用一個特殊字母表 (Crockford's Base32),排除了容易混淆的字母,如 "I"、"L" 和 "O"。這讓它們如果使用者必須輸入時,更易於閱讀。
  3. 無需設定: 與 Snowflake IDs 不同,你不需要設定伺服器 ID 或工作節點。你只需要安裝這個 gem 就可以了.

大概就是這樣。這是一個小型的架構變更,讓你的應用程式感覺更加專業和可擴展。