Laravelにおけるサロゲートキーと自然キーについて

## 1. はじめに

ふとしたことで自然キーとサロゲートキーについて知る機会がありました。Laravelではどのような扱い方をしているのか気になって調べてみました。

## 2. 対象読者

- Laravel利用者
- テーブル設計者

## 3. 目次

- [1. はじめに](#1-はじめに)
- [2. 対象読者](#2-対象読者)
- [3. 目次](#3-目次)
- [4. 自然キーとは](#4-自然キーとは)
- [5. サロゲートキーとは](#5-サロゲートキーとは)
- [6. Laravelにおけるサロゲートキー](#6-laravelにおけるサロゲートキー)
  - [6-1. カスタムサロゲートキーの設定](#6-1-カスタムサロゲートキーの設定)
  - [6-2. サロゲートキーを使用しない場合の主キーの設定方法](#6-2-サロゲートキーを使用しない場合の主キーの設定方法)
- [7. さいごに](#7-さいごに)
- [8. 参考サイト](#8-参考サイト)

## 4. 自然キーとは

自然キーとは、業務上の意味を持つデータ項目を使用してレコードを一意に識別するためのキーのことです。例えば、ユーザーのメールアドレスや社会保障番号などが自然キーとして使われることがあります。自然キーの利点は、その値自体に意味があるため、データの理解が直感的であることです。しかし、ビジネスロジックの変更によって値や仕様そのものが変わる可能性があるため、細心の注意が必要です。

## 5. サロゲートキーとは

サロゲートキーとは、データベースのテーブルにおいて一意にレコードを識別するための人工的なキーのことです。通常、数値型のオートインクリメントを利用して生成されます。

自然キーと異なり、業務上の意味を持たないため、変更の影響を受けにくいという利点があります。特に大規模なシステムにおいては、自然キーの変更が頻繁に発生するため、その影響を最小限に抑えることができます。サロゲートキーを使用することで、データの一貫性と参照の容易さが向上します。また、数値型のサロゲートキーはインデックスの効率も良く、検索性能の向上にも寄与します。ただし、参考書によってはサロゲートキーはテーブル設計のアンチパターンとして紹介されている場合もあります。

## 6. Laravelにおけるサロゲートキー

Laravelでは、Eloquent ORMを使って簡単にサロゲートキーを設定することができます。デフォルトでは、Laravelのマイグレーションで生成されるテーブルには自動的にサロゲートキー(`id`カラム)が追加されます。このカラムは、主キーとして設定され、自動インクリメントされます。

下記は、Laravelのマイグレーションでサロゲートキーを設定する方法です。

```php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id(); // サロゲートキー
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}
```

### 6-1. カスタムサロゲートキーの設定

`id`というカラム名以外をサロゲートキーに使用することも可能です。その場合、モデルクラスに以下のような設定が必要になります。

```php
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $primaryKey = 'user_id'; // カスタムサロゲートキー
}
```

この設定を行うことで、`user_id`カラムがサロゲートキーとして機能するようになります。

### 6-2. サロゲートキーを使用しない場合の主キーの設定方法

サロゲートキーを使用しない場合は、自然キーを利用します。自然キーは、業務上の意味を持つカラムを主キーとして使用する方法です。例えば、ユーザーのメールアドレスを主キーとする場合は、以下のように設定します。

```php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->string('email')->primary(); // 自然キーとしてemailを設定
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}
```

```php
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $primaryKey = 'email'; // 自然キーを設定
    public $incrementing = false; // 自動インクリメントを無効化
    protected $keyType = 'string'; // キーのデータタイプを指定
}
```

## 7. さいごに

Eloquent ORMを利用する場合は、デフォルトでサロゲートキーを利用することが前提となっています。Eloquent ORMの強力な機能を活用することで、シンプルかつ柔軟にサロゲートキーを設定・管理することが可能です。一方、サロゲートキーを使用しない選択も簡単に構築することができます。それぞれの方法にはメリットがあり、プロジェクトの要件に応じて選択することが重要です。
私が考える簡単な基準を紹介しておきます。

- 自然キー：変更が少なく、業務ロジックが安定している場合はが適していることが多い
- サロゲートキー：変更が頻繁に発生する可能性がある場合や、大規模なシステムでは適していることが多い

## 8. 参考サイト

- [Laravel Documentation - Eloquent](https://readouble.com/laravel/10.x/ja/eloquent.html#primary-keys)