bucket-sort logo bucket-sort

プログラミングとインフラエンジニアリングの覚え書き

  • Posts
  • About
  • Contact
  1. Home
  2. All Posts
  3. Laravel ObjectId - Laravelモデル用のMongoDBスタイルの高速ID

Laravel ObjectId - Laravelモデル用のMongoDBスタイルの高速ID

Mar 2, 2026 Laravel bucket-sort

DynamoDB には MySQL のような自動インクリメントの整数 ID がありません。

それに代わるものを探して見つけた以下の記事が大変興味深かったので、 拾い読みして自分用の覚え書きとしてまとめます。

Introducing Laravel ObjectId — The Fastest MongoDB-Style Identifier for Laravel Models | by Hamada Habib | Nov, 2025 | Medium
https://medium.com/@ihfbib/introducing-laravel-objectid-the-fastest-mongodb-style-identifier-for-laravel-models-3802814324d9

背景と目的

  • 通常、Laravel のモデルではデフォルトで自動インクリメントの整数 ID を使うことが多い。だが、アプリが成長して分散システム/マイクロサービス化/API連携などを行うようになると、そのような整数 ID は制約になる場合がある。
  • そこで、Laravel ObjectId というパッケージが登場。MongoDB の ObjectId に着想を得た、グローバルに一意かつ高速で生成できる識別子を、MySQL・MariaDB・PostgreSQL などの標準 SQL データベース上で使えるようにする仕組み。MongoDB を使っていなくても使える。

Laravel ObjectId の概要

12 バイトのコンパクトな ID

  • ObjectId は 12 バイト(96 ビット)、16 進で表すと 24 文字の文字列。
  • 内部構造は以下の通り:
    • タイムスタンプ(4 バイト) UNIX epoch 秒 — 生成時間を含み、生成順ソート可能
    • マシン識別子(5 バイト) ホストごとランダム・一意
    • プロセス ID(2 バイト) プロセス識別
    • カウンタ(3 バイト) プロセス内でのインクリメントカウンタ
  • この構造により、集中管理なしで一意性を保証しつつ、生成時刻順のソート性も自然に持てる。

対応するデータベース & ライブラリ

  • Laravel ObjectId は MySQL / MariaDB / PostgreSQL にネイティブに対応。MongoDB ドライバ/拡張は不要。
  • コア PHP 実装のライブラリ wooserv/php-objectid に加えて、Laravel 向け統合パッケージ wooserv/laravel-objectid が用意されており、Eloquent モデルとの親和性が高い。

使い方(例)

use WooServ\LaravelObjectId\Concerns\HasObjectIds;
use Illuminate\Database\Eloquent\Model;

class Post extends Model {
    use HasObjectIds;
}
  • これで新規レコード作成時に、ID が自動で ObjectId に。

マイグレーションでは:

Schema::create('posts', function (Blueprint $table) {
    $table->objectId();  // 24 文字の主キーカラムを作成
    // ...
});
  • また、どこでも objectid() ヘルパーで ID を生成可能。例:6730b6a0d8a28f890b7c9f40 のような文字列。

パフォーマンスと利点

記事ではベンチマーク結果を提示:

  • 10,000 回の ID 生成ベンチマークでは、
    • ObjectId:約 0.412 µs / ID
    • UUID:1.283 µs / ID
    • ULID:1.147 µs / ID → ObjectId が最速。約 3 倍速い。
  • データベースへの挿入(1,000 レコード)では、
    • ObjectId:合計約 14.78 ms
    • UUID:15.48 ms
    • ULID:15.17 ms → 実質的に差は小さいが、生成オーバーヘッドは ObjectId が有利。

比較表で示すと:

特性 ObjectId UUID ULID
文字列長 24 文字 36 文字 26 文字
バイト長 12 16 16
ソート可能(生成順) ✅ タイムスタンプ付き ❌ ✅
ランダム性 ✅ ✅ ✅
対応 DB MySQL/MariaDB/PostgreSQL 同様 同様
MongoDB 必要か ❌ ❌ ❌

なぜ「ObjectId」が選ばれるか

  • 自動割当・マイグレーション用マクロで導入が簡単。開発者にとって導入のハードルが低い。
  • インデックスやストレージのサイズを抑えられ、データベースの効率性が向上。
  • タイムスタンプを持つことで、生成順にソート可能 → ログ/イベント/分散トランザクションなど、順序が重要な用途で有利。
  • MongoDB など NoSQL に移行する必要なく、既存の SQL DB をそのまま活かせる ― Laravel の既存アプリにも導入しやすい。

こんな状況に向いている

  • Laravel を使っていて、将来的にマイクロサービスや複数 DB/複数インスタンス構成を考えている。
  • UUID のような長くてインデックス負荷が高い識別子を使いたくない。
  • レコードの生成時間順でソートが必要/便利なログ・イベント管理用途。
  • MongoDB を導入せず、既存の MySQL / PostgreSQL をそのまま使いたい。

「文字列 ID が整数より有利だから」ではなく、 「ObjectId は分散環境でも衝突しない一意性と時系列ソート性を同時に持てる」という点がメリットです。

なぜ整数ではダメになる場面があるのか

ID 方式 特徴 問題が起きる状況
整数(auto increment) 小さく高速。シンプル。 1台のDBに依存 → 分散環境でIDの衝突リスク
UUID(v4) 衝突ほぼなし 長く重い、時系列順に並ばない、索引負荷↑
ObjectId 衝突回避+時系列ソート可能+比較的短い NoSQL Mongo風の利点をSQLで使える

ObjectIdの特に大きいメリットはこの2つ

① 生成した瞬間に一意性が保証される(DBに依存しない)

整数IDはこうなる:

DB が発番 → INSERT → ID決定

なので DBが1台で管理する必要がある。 スケールアウトやマイクロサービス化すると衝突が起きやすい。

ObjectIdなら:

DBに触らなくてもIDが生成できる(衝突ほぼなし)
  • 複数サーバーが同時に INSERT しても安全
  • 非同期バッチ・分散アプリ・キュー処理に強い

② IDを見ただけで「いつ生成されたかがわかる」

ObjectIdの先頭4byteはUNIXタイムスタンプ。

6730b6a0d8a28f890b7c9f40
↑ここがtimestamp → 生成順にソートできる
  • orderBy(‘id’)だけで作成順に並ぶ
  • ログ、イベント履歴、データストリームに向く
  • UUIDにはこの特性がない

マシンごとに閉じたIDではなく、数マシン・複数プロセスが同時にIDを生成しても重複しない。 これは DBに依存せず自律的に生成できる点が重要で、整数の auto increment ではできないことです。

なぜ重複しないのか(内部構造が理由)

| 時刻(4byte) | マシン識別子(5byte) | プロセスID(2byte) | カウンタ(3byte) |
  • マシン/プロセス単位で識別が入る
  • さらにカウンタで連番が加わる
  • 作成時刻の分まで情報が組み込まれている

→ 全マシン独立にIDを生成しても衝突しない仕組み

auto increment の危険な例

サーバーAとサーバーBが同時 INSERT

サーバ 生成ID 競合?
A 1001 DBが発番するから順番待ち必要
B 1001 同じ数字を使おうとする

DBがひとつならなんとかなるが、

  • アプリケーションサーバーを増やす
  • マイクロサービス間で非同期に生成したい
  • オフラインで一旦生成→後で集約したい

こうなると整数IDは破綻しやすい。

ObjectId なら

server A → 6730b6a0d8a28f890b7c9f40
server B → 6730b6a0f4828c1112a0c954
  • 発番の待ち合わせ無し
  • 中央DB不要
  • 重複リスク極小
  • 完全に分散してIDを生成できる。

まとめ

方式 複数マシンで安全? ID生成にDB必要?
auto increment (int) 衝突しやすい 必須
UUID ◎ 衝突ほぼ無し 不要
ObjectId ◎ 衝突ほぼ無し+時系列で並ぶ 不要

つまり ObjectId は「自律分散ID」+「時系列で見れるID」の両立が強みです。

Laravel MySQL NoSQL
← RDBのつもりでlaravel-dynamodbを使うとハマりそうなポイントを整理する 監査ログをDynamoDBに保存するlaravel-dynamodb-auditingパッケージの概要まとめ →

Related Posts

  • 監査ログをDynamoDBに保存するlaravel-dynamodb-auditingパッケージの概要まとめ Mar 3, 2026
  • RDBのつもりでlaravel-dynamodbを使うとハマりそうなポイントを整理する Mar 1, 2026
  • データベースの種類まとめ:Relational / Time-Series / NoSQL / Vector / NewSQL の特徴と代表例 Mar 4, 2026
  • RDBMS経験者がDynamoDBを理解するための整理メモ Jan 5, 2026

Table of Contents

  • 背景と目的
  • Laravel ObjectId の概要
  • 対応するデータベース & ライブラリ
  • 使い方(例)
  • パフォーマンスと利点
  • なぜ「ObjectId」が選ばれるか
  • こんな状況に向いている
  • なぜ整数ではダメになる場面があるのか
    • ① 生成した瞬間に一意性が保証される(DBに依存しない)
    • ② IDを見ただけで「いつ生成されたかがわかる」
  • なぜ重複しないのか(内部構造が理由)
  • auto increment の危険な例
  • まとめ

Recent Posts

  • Laravel の Event / Listener で Pub/Sub を実装する Apr 2, 2026
  • [C#] delegate と event の仕組みを整理する Apr 1, 2026
  • Pub/Sub パターンとは何か Mar 31, 2026
  • PHP/Laravel で値の状態を判定するヘルパ関数まとめ Mar 30, 2026
  • Filament の dehydrated メソッドとは何か Mar 29, 2026

Categories

  • AWS27
  • C#22
  • .NET20
  • Laravel16
  • Linux12
  • Apache8
  • MySQL8
  • PHP8
  • DynamoDB6
  • Nginx5
  • WordPress4
  • インフラ4
  • Hugo3
  • セキュリティ3
  • .NET Framework1
  • Aurora1
  • Filament1
  • Git1
  • SQS1

Tags

  • AWS
  • C#
  • .NET
  • Laravel
  • PHP
  • MySQL
  • セキュリティ
  • Linux
  • Apache
  • Code Snippet
  • DynamoDB
  • NoSQL
  • PHP-FPM
  • RDS
  • DoS
  • Nginx
  • Windows
  • WordPress
  • パフォーマンス
  • 監視
  • Amazon Linux 2023
  • CMS
  • Docker
  • Ipset
  • Iptables
  • OPCache
  • Webサーバー
  • 認可
  • Aurora
  • Blade
Powered by Hugo & Explore Theme.