ワダです。今回は、ID値の生成方法について試したことを書いてみます。

主キーについて

(詳しい方はスルーしてください)
主キー=行レコードの一意性が識別できる列の組み合わせ。
DBMSのテーブルに登録するレコードを一意に絞るために、テーブルには「主キー」が必要です。

主キーの生成方法

主キーの設定方法には、以下のような種類があります。テーブルに入れたいデータの用途などによって使い分けます。

  • 1ナチュラルキー(自然キー)
    • 1-1単純キー
      例)都道府県名

       

    • 1-2複合キー
      例)都道府県名+市町村名

  • 2サロゲートキー(代替キー)
    ※連番やランダムな値などの一意の値を格納するカラムを用意し、自然キーの代わりに主キーとするもの。

    • ★2-1 単純代替キー★
      例)「ID」列

       

    • 2-2 複合代替キー
      例)ID列 + 登録日時

ナチュラルキーを使ったテーブルは、結合時に結合条件が多くSQLが複雑になりがちなため、
ナチュラルキーよりもサロゲートキーを用いる方が仕様変更に強かったり、SQLのバグが少ないなど、開発時には有利な場面が多いと思います。

今回試した方法

今回は、上記の「★2-1 単純代替キー」の場合の、ID列に入れる一意な値の生成を試してみました。

試した方法は以下の3つです。
– ①採番テーブルを使う
– ②DBMSのシーケンスを利用する
– ③プログラム内で生成する。(UUID等)

①採番テーブルを使う

採番テーブル「NUMBERING」

以下は採番した番号を入れていく方のテーブル「EMPLOYEE」。

・使用例
以下は実行前の採番テーブルの状態。

以下のように、トランザクションの中で採番テーブルを更新(1000000001→1000000002)し、従業員テーブルにINSERTする。

実行結果

採番テーブルのメリット・デメリット

メリット :どのDBMSでも同じ方法で使える方法である。
デメリット:ほかの方法と比較すると性能があまりよろしくない。採番テーブルを複数人が同時に更新しないよう
トランザクションの期間に気を付ける必要がある。

②DBMSのシーケンスを利用する

シーケンス「EMPLOYEE_SEQ」を作成。10桁のEMPLOYEE_IDに対応するように開始値を「1000000001」に設定。

・シーケンス値を入れるテーブル「EMPLOYEE」は①と同じ。

・使用例
例)新規従業員を登録する。
「EMPLOYEE_SEQ」を利用してEMPLOYEE_IDを取得し、「EMPLOYEE」テーブルに登録する。

実行結果

シーケンスのメリット・デメリット

メリット :設計が楽。実装も楽♪。
デメリット:シーケンスは、DBMSごとに作成方法が異なる。また対応していないDBMSもある(らしいです)。

③プログラム内でID値を生成する

JavaのUUIDを利用してランダムな値を生成する方法を試しました。
SQLServerのテーブルは、UUIDを格納するカラムを「UNIQUEIDENTIFIER」型で作成します。

テーブル「UUIDSample」

プログラム

実行

実行結果

プログラム内でID値を生成するメリット・デメリット

メリット :採番をRDBMSに任せずに行うことができる。乱数を使用するため、重複の可能性は限りなく小さい。
デメリット:連番としては使えない。そのためこの列でのソートはできない。
ソートしたい場合は登録日時等との複合代替キーにするなど工夫が必要。

■あとがき

・個人的には、②のシーケンスに任せられる状況なら、それがベストな気がします。
・ただし社員IDのようにコード体系がきっちりしている状況なら、①の採番テーブルが望ましいと思います。
・(いつものことながら)書く内容が基本的なことにとどまっていますが、、どこかで役立てられれば幸いです。

■環境について

・OS
Windows10 Pro ビルド番号 1903

・DBMS
SQLServer 2012

・SQL Server Management Studio
バージョン4.1.4.21
ビルドMAIN-21.21

・Java
java version “1.8.0_221”

参考サイト

・【データベース設計】採番について

【データベース設計】採番について

・データベースのPRIMARY KEYを自動採番せずにアプリケーション側で生成する

・ソート可能なUUID互換のulidが便利そう
(こちらは今回は試していませんが、ミリ秒単位で時系列ソートができるライブラリがあるようです。)
https://qiita.com/kai_kou/items/b4ac2d316920e08ac75a

以上です。ありがとうございました。

TOP
TOP