データベースの主キーの生成方法について比較してみた

はじめまして、ecbeing入社3年目のヤマコフです。

配属から今年の3月まではレビューサービスReviCoの開発に携わっていましたが、 4月から予約管理システムRESOMOの開発チームに参画しています。

いずれもecbeing社で作られた製品といっても作りが全く違うため、 はじめは慣れないシステム構成に苦戦していましたが、 2か月ほど経ってRESOMOの開発にも慣れてきました。

この記事ではその中で気になった違いの一つである、 データベースの主キーの生成方法の違いについて紹介します。

はじめに

データベースにおいて、主キーは各レコードを一意に識別するための項目です。
主キーは適切に設定しないと、データベースのパフォーマンスや整合性に大きな影響を与えます。
主キーの生成にはいろいろな方法があり、ReviCoとRESOMOでも異なる生成方法を使用しています。
今回は主キー生成の代表的な方法であるIDENTITY列、シーケンス、およびGUIDについて 利点と欠点、使用例を説明し、それぞれの方法の比較をしようと思います。

主キーの生成方法

今回比較する主キーの生成方法について、簡単に特徴をまとめると以下のようになります。

  • IDENTITY列: テーブル定義内で自動的に増加する数値を生成する列。
  • シーケンス: 連続した数値を生成するデータベースオブジェクト。
  • GUID: グローバルに一意な識別子。

ここからはそれぞれの主キーの生成方法について詳しく見ていきます。
IDENTITY列はSQL Server固有の方法、他の2つは一般的な方法ですが、 今回はいずれもSQL Serverを例に挙げて説明します。

IDENTITY列

IDENTITY列は、SQL Serverで連番の主キーを自動生成するために使用されます。 テーブル定義内で設定でき、行が追加されるたびに自動的に連続した数値が生成されます。 テーブル内で一意な値になることが保証され、設定も非常に簡単なため、 単一テーブルでのシンプルな主キーの生成方法としてよく利用されます。

IDENTITY列の利点と欠点

利点:

  • 設定の簡単さ: テーブル定義内で簡単に設定できる。
  • 自動管理: 値の生成と管理が自動的に行われるため、外部の管理が不要。

欠点:

  • 初期設定後の変更が困難: テーブル定義内で一度設定すると変更が難しい。
  • 再利用が困難: 一度使用した値を主キーに再利用するのは困難。
  • 複数テーブルでの一貫性がない: 複数のテーブルで一貫した主キーを生成することが難しい。

IDENTITY列の使用例

IDENTITY列を使用してテーブルにレコードを追加する方法を説明します。
まず、IDENTITY列を使用してテーブルを作成します。 この例では、ID 列が主キーとして設定され、1から始まり1ずつ増加します。

CREATE TABLE MyTable (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(50),
    Age INT
);

作成したテーブルにレコードを挿入します。 IDENTITY列を使用する場合、ID 列の値は自動的に生成されるため、主キーを指定する必要はありません。

INSERT INTO MyTable (Name, Age)
VALUES ('John Doe', 30);

シーケンス

シーケンスはデータベースオブジェクトとして独立して存在し、連続した数値を生成するための仕組みです。 SQL Serverを含む多くのデータベース管理システムでサポートされています。 テーブルとは独立して定義されるため、複数のテーブルやカラムで共有できます。 また、IDENTITY列に比べて柔軟な設定や値の取得が可能です。

シーケンスの利点と欠点

利点:

  • 再利用性: 一度作成したシーケンスを複数のテーブルやカラムで再利用できる。
  • 設定の柔軟性: 増分値や開始値などを自由に設定できる。
  • 複数テーブルで一貫性が保持される: 複数のテーブルで一貫した主キーを生成できる。

欠点:

  • 外部管理が必要: シーケンスの管理や値の取得がテーブルに比べて手間。
  • 設定がやや複雑: 設定項目が多く、理解するまでに時間がかかる場合がある。

シーケンスの使用例

シーケンスを作成し、それを利用してテーブルにレコードを追加する方法を説明します。
まず、シーケンスを作成します。このシーケンスは、10000から始まり、1ずつ増加する整数を生成します。

CREATE SEQUENCE MySequence
    AS INT
    START WITH 10000
    INCREMENT BY 1;

次に、シーケンスを使用するテーブルを作成します。

CREATE TABLE MyTable (
    ID INT PRIMARY KEY,
    Name NVARCHAR(50),
    Age INT
);

シーケンスから値を取得し、その値を主キーとしてレコードを挿入します。 シーケンスから次の値を取得するにはNEXT VALUE FOR関数を使用します。

INSERT INTO MyTable (ID, Name, Age)
VALUES (NEXT VALUE FOR MySequence, 'John Doe', 30);

GUID

GUID (Globally Unique Identifier) は、グローバルに一意の識別子です。 GUIDは128ビットの値で、通常は32桁の16進数で表現されます。(例:f73e77e5-3d51-4bcd-81a7-9f94f8fbc7e2) 値が重複する確率は限りなく低いため、分散システムやクラウド環境などで広く使用されています。 GUIDはデータベースだけでなく、アプリケーション内で生成して使用することも多いです。

GUIDの利点と欠点

利点:

  • グローバルな一意性: 複数のシステム間で一意性を保てる。
  • 分散システムに適している: クライアント側で生成しても一意性を保てるため、分散環境での使用に最適。
  • 推測がほぼ不可能: 複雑な値であるため、連続する値の推測がほぼ不可能。

欠点:

  • サイズが大きい: 128ビットの値であるため、ストレージとインデックスのサイズが大きくなる。
  • 性能の影響: 挿入や検索の性能が、連続した整数よりも劣る場合がある。

GUIDの使用例

GUIDを表現する UNIQUEIDENTIFIER 型を使用して、テーブルにレコードを追加する方法を説明します。
まず、GUIDを主キーとして使用するテーブルを作成します。 この例では、ID 列を UNIQUEIDENTIFIER 型とし、デフォルト値として NEWID() 関数を使用しています。

CREATE TABLE MyTable (
    ID UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
    Name NVARCHAR(50),
    Age INT
);

作成したテーブルにレコードを挿入します。 デフォルト値として NEWID() 関数を使用する場合、ID 列の値は自動的に生成されるため、主キーを指定する必要はありません。

INSERT INTO MyTable (Name, Age)
VALUES ('John Doe', 30);

主キー生成方法の比較

ここまで、主キーを生成するための3つの代表的な方法(IDENTITY列、シーケンス、GUID)について説明してきました。 最後にそれぞれの方法の特徴、利点、欠点を比較し、それぞれの方法がどのようなシチュエーションに向いているかをまとめます。

比較表

特徴 IDENTITY列 シーケンス GUID
概要 テーブル定義内で自動増加 独立したオブジェクト グローバルに一意
利点 簡単な設定、自動管理、効率的 再利用性、設定の柔軟性、複数テーブルで一貫性が保持される グローバルな一意性、分散システムに適している、推測がほぼ不可能
欠点 初期設定後の変更が困難、再利用が困難、複数テーブルでの一貫性がない 外部管理が必要、設定がやや複雑 サイズが大きい、性能の影響

それぞれの方法が向いているシチュエーション

  • IDENTITY列
    IDENTITY列は設定が非常に簡単で、SQL Serverが自動的に一意の値を生成してくれるため、 単一テーブル内で連続した数値の主キーを効率的に生成できます。

  • シーケンス
    シーケンスは独立したオブジェクトとして存在し、複数のテーブルで共有できるため、 一貫性のある主キーを複数のテーブルで生成する必要がある場合に適しています。

  • GUID
    GUIDはグローバルに一意であり、クライアント側で生成しても重複しないため、分散システムやクラウド環境での使用に最適です。 データベース間での一意性を保つ必要がある場合にも有効です。

まとめ

この記事では、データベースの主キーを生成する代表的な方法であるIDENTITY列、シーケンス、GUIDについて比較しました。 それぞれの方法に利点と欠点があり、使用するシチュエーションや要件に応じて最適な方法を選ぶことが必要になります。 プロジェクトの要件に最も適した方法を選択し、適切に実装することで、効率的で信頼性の高いデータ管理を実現しましょう。

ecbeing では、新進気鋭なエンジニアを募集しています! careers.ecbeing.tech