Loading...

We've detected that your browser language is Chinese. Would you like to visit our Chinese website? [ Dismiss ]
By: Emma

SQL制約とは何か

SQL制約とは、データ品質を維持するためデータベースエンジンが直接強制するルールのことです。スキーマ層のガードレールとして機能し、各行がストレージに書き込まれる前に定められた基準を満たしているか検証します。

開発者が制約を活用する理由は、アプリケーション側のバリデーションだけでは完全な信頼性が確保できないからです。手動実行するSQLスクリプト、ミドルウェアの不具合、データベースへの直接接続など、あらゆる経路からアプリロジックを迂回してデータが登録される可能性があります。データベース層に定義した制約は強制的な遮断機構となり、データの流入経路を問わず正しいデータを保ちます。

what are sql database constraints

制約には2つの定義方法があります。

  • テーブル作成時:テーブルを初めて作成するCREATE TABLE構文内に記述します。
  • テーブル作成後:既存テーブルに対しALTER TABLEコマンドを使用して後から追加します。

また制約の適用範囲は2種類に分かれます。

  • 列レベル制約単一のフィールドに紐付き、その列のみに適用されます。
  • テーブルレベル制約特定の列に紐付けず個別に定義し、複数列にまたがる制約を設定可能です。例:employee_idとproject_idの組み合わせが全行で一意となるよう強制する場合など。

SQL制約とインデックスの違い

制約とインデックスは混同されがちですが役割が異なります。制約は値の検証・制限によりデータ整合性を保ち、インデックスはデータ検索を高速化しクエリパフォーマンスを改善します。

簡単に言うと、制約はデータの品質を守り、インデックスはデータへのアクセスを最適化する機能です。

6種類のSQL制約(サンプル付き)

代表的なSQL制約の概要、役割、一般的な利用シナリオを一覧にまとめます。

制約名 役割 代表的な使用例
NOT NULL 値の欠損を禁止 ユーザーメール、注文日時
UNIQUE 重複値を禁止 ユーザー名、個人番号、商品SKU
PRIMARY KEY 行の一意識別子 従業員ID、商品ID
FOREIGN KEY テーブル間の関連性を維持 部門紐付け、顧客注文情報
CHECK 値のルールを強制 給与>0、年齢≧18
DEFAULT デフォルト値を設定 アクティブステータス、作成日時

以降のサンプルでは共通のemployeesテーブル、departmentsテーブルのスキーマを使用し、各制約の実務的な動作を紹介します。

1. NOT NULL

NOT NULL制約は列にNULL値を格納できないようにする制約で、常にデータが存在する状態を保ちます。識別子、ステータス項目、連絡先などアプリロジック上必須の列に適用する重要な制約です。

-- 標準SQL
CREATE TABLE departments (
    dept_id    INT          NOT NULL,
    dept_name  VARCHAR(100) NOT NULL
); 

 

sql database constraints NOT NULL

代表的な利用場面:従業員名、メールアドレス、タイムスタンプ、ステータス項目。

よくあるミスとして外部キー列にNULLを許可する設定が挙げられます。これにより、親テーブルに存在しない・紐付け先のない孤立レコードが作成される恐れがあります。

2. UNIQUE

UNIQUE制約は列内の値がすべて一意になるよう保証します。主キーと異なり1テーブルに複数のUNIQUE制約を定義可能で、NOT NULLと違いNULL値の登録を許可する仕様(データベース製品による細かな差異あり)です。

-- 標準SQL
CREATE TABLE employees (
    employee_id          INT          NOT NULL,
    email                VARCHAR(255) UNIQUE,
    social_security_number VARCHAR(11) CONSTRAINT unq_ssn UNIQUE
); 

 

sql database constraints UNIQUE

複数列を対象にテーブルレベルでUNIQUEを定義し、複数項目の組み合わせの一意性を強制することもできます。例:同一従業員が同一プロジェクトに重複してアサインされないよう制御する場合

-- 複合一意制約
ALTER TABLE project_assignments
ADD CONSTRAINT unq_emp_project UNIQUE (employee_id, project_id); 

sql database constraints UNIQUE 2

3. PRIMARY KEY(主キー)

主キーはテーブル内の各レコードを一意に識別する制約で、NOT NULLとUNIQUEの性質を両方持ち合わせています。対象列には必ず値が存在し、全行で値が重複しません。

適切に設計されたテーブルには必ず1つの主キーを設定するべきです。主キーがないと特定の行を確実に参照・更新する手段が存在しなくなります。

-- 標準SQL
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    first_name  VARCHAR(50) NOT NULL,
    last_name   VARCHAR(50) NOT NULL
); 
sql database constraints PRIMARY KEY
補足:大半のデータベースエンジンは主キーにクラスタードインデックスを自動作成し、行単位の検索速度を大幅に向上させます。

4. FOREIGN KEY(外部キー)

外部キーは一方のテーブルの列を、別テーブルの主キーと紐付ける制約で、参照整合性を保ちます。親テーブルに存在しない値を登録することはできず、既定の設定では子レコードが存在する状態で親レコードを削除することも禁止されます。

-- 標準SQL
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    dept_id     INT,
    FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
        ON DELETE CASCADE
); 

 

sql database constraints FOREIGN KEY

削除時の動作として代表的な2種類を覚えておきましょう。

  • ON DELETE CASCADE:部門を削除すると、配属されている従業員レコードも自動的に削除されます。
  • ON DELETE RESTRICT:対象部門に従業員が存在する場合、親レコードの削除がブロックされます。

データモデルに合わせて選択してください。CASCADEは便利ですが、設定を誤ると意図しないデータ消失が発生するため注意が必要です。

5. CHECK

CHECK制約は列の値を論理式で検証し、条件に違反する行の登録・更新を拒否します。アプリケーションコードに依存せず、データベース層で直接業務ルールを強制できます。

-- 標準SQL
ALTER TABLE employees
ADD CONSTRAINT chk_salary   CHECK (salary > 0);

ALTER TABLE employees
ADD CONSTRAINT chk_hire_date CHECK (hire_date >= '2000-01-01'); 
sql database constraints CHECK
補足:CHECK制約とNULL値の挙動は分かりにくい点があります。列の値がNULLの場合、論理式の判定結果がUNKNOWNとなり、行の登録が許可されます。NULLを拒否したい場合はCHECKとNOT NULLを併用してください。

6. DEFAULT(デフォルト制約)

DEFAULT制約はINSERT文で列の値が省略された際に適用される代替値を定義します。オプション項目の処理をデータベース側に委ね、アプリケーションコードを簡略化できます。

-- 標準SQL
CREATE TABLE employees (
    employee_id INT     PRIMARY KEY,
    is_active   BOOLEAN DEFAULT TRUE,
    country     VARCHAR(50) DEFAULT 'USA'
); 

 

sql database constraints DEFAULT

ステータスフラグや固定の地域名など、予測可能な値に対してDEFAULTを活用しましょう。「1900-01-01」といった仮の日付や任意の数値をデフォルトに設定するのは避けてください。データが真に不明な場合はNULLを使用する方が集計結果に歪みが生じません。

SQL制約の追加・変更・削除方法

データベーススキーマは静的なものではなく、アプリケーションの進化に伴い業務要件に合わせてルールの追加・修正が必要になります。

テーブル作成時に制約を定義

最もクリーンな手法はCREATE TABLE構文内で制約を事前定義することで、テーブル作成当初から不正なデータが登録されることを防ぎます。

-- 標準SQL
CREATE TABLE employees (
    employee_id INT            PRIMARY KEY,
    email       VARCHAR(255)   CONSTRAINT unq_emp_email UNIQUE,
    salary      DECIMAL(10, 2) CONSTRAINT chk_min_wage  CHECK (salary > 0)
); 

adding constraints at table creation

既存テーブルへ制約を追加

本番環境では既にデータが存在するテーブルに新たなルールを追加する場面が多く、ALTER TABLEコマンドを使用します。

既存の行が新しい制約ルールに違反している場合、データベースは処理全体を拒否するため、稼働中のテーブルに制約を追加する前に事前にデータ監査を実施する必要があります。

-- 既存テーブルに外部キーを追加
ALTER TABLE employees
ADD CONSTRAINT fk_employee_dept
FOREIGN KEY (dept_id) REFERENCES departments(dept_id); 

adding a foreign key to an existing table

制約の削除

業務ルールが変更になった際はDROP CONSTRAINTで制約を削除します。制約名を正確に指定する必要があるため、命名規則を統一することが重要な理由の一つです(次のセクションで解説)。

-- 標準SQL
ALTER TABLE employees
DROP CONSTRAINT chk_min_wage; 
dropping constraints
補足:MySQLは制約種別ごとに構文が異なります。例えば外部キーの削除にはDROP CONSTRAINTではなくDROP FOREIGN KEYを使用します。DROP DATABASEは単一制約やテーブルの削除とは異なり、データベース全体を完全に削除するコマンドです。必要な場合は製品別のDROP DATABASEガイドを参照し、一般的なエラーを回避してください。

制約に名前を付けるべき理由

開発者が陥りがちなミスは、データベースに制約名を自動生成させることです。結果としてSYS_C001023のような名前が割り当てられ、エラーログに出力されてもどのルールが違反したか判別できません。

最初から統一した命名規則を使用しましょう。

  • pk_employees:employeesテーブルの主キー
  • fk_employees_dept:employeesからdepartmentsへの外部キー
  • chk_employees_salary:salary列のCHECK制約
  • unq_employees_email:email列のUNIQUE制約

本番環境で「制約違反」エラーが発生した際、可読性の高い制約名からどのテーブルのどのルールが破られたか即座に把握でき、調査の手間を削減します。

各データベースのSQL制約の差異(MySQL、PostgreSQL、SQL Server)

SQL規格で制約の基本的な動作が定められていますが、各エンジンに独自の仕様の癖が存在します。複数製品を運用したり、環境間でマイグレーションを実施する際にこれらの差異が重要になります。

一覧比較:

機能 MySQL (8.0.16以上) PostgreSQL SQL Server
CHECK制約の強制 有効 有効 有効
UNIQUE列への複数NULL登録 許可 許可 不可(1つのみ許可)
遅延可能制約 非対応 対応 非対応
過去データの検証をスキップし制約追加 非対応 NOT VALID WITH NOCHECK
主キーの必須化 InnoDBで必須 任意(推奨) 任意(推奨)

以下に各製品の差異を詳しく解説します。

MySQL:2019年までCHECK制約が無視されていた

長年MySQLはCHECK構文を受け付けるだけで実際の検証を実施しませんでした。構文解析だけ行いエラーを返さず処理を続ける仕様でした。2019年リリースの8.0.16からCHECK制約が正しく強制されるように変更されています。

古いバージョンのMySQLを使用している場合は注意が必要です。バージョンアップ前に登録されたデータは、現在のスキーマのルールに適合していない可能性があります。

PostgreSQL:遅延可能制約に対応

3製品の中でPostgreSQLが最も完全な制約機能を備えており、特徴的な機能が遅延可能制約です。トランザクション実行中は一時的に制約の検証を停止し、COMMIT時に一括で検証する動作が可能です。

大量データの一括インポートや、参照整合性が満たされる順番で行を登録する必要がある処理に有用です。

-- PostgreSQL:遅延可能な外部キーを作成
ALTER TABLE employees
ADD CONSTRAINT fk_employee_dept
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
DEFERRABLE INITIALLY DEFERRED; 

PostgreSQL - create a deferrable foreign key

PostgreSQLはNOT VALIDオプションに対応し、既存テーブルに制約を追加する際に過去の全行を検証しない設定が可能です。大容量の本番テーブルで全行スキャンによる停止時間を回避したい場合に活用します。

-- PostgreSQL:既存データを検証せず制約追加
ALTER TABLE employees
ADD CONSTRAINT chk_salary CHECK (salary > 0) NOT VALID;
-- 負荷の低い時間帯に別途過去データを検証
ALTER TABLE employees VALIDATE CONSTRAINT chk_salary; 

PostgreSQL - add constraint without checking existing rows

SQL Server:UNIQUE制約とNULLの挙動の違い

製品間の切り替え時に混乱しやすいポイントが、UNIQUE制約とNULL値の組み合わせです。

MySQLとPostgreSQLは一意列に複数のNULLを許可します。NULLは不明な値を表し、不明な値同士は同一とみなされないためです。一方SQL ServerのUNIQUE制約はNULLを1つだけ許可し、追加のNULLは重複と判定され登録が拒否されます。

SQL ServerはPostgreSQLのNOT VALIDに相当するWITH NOCHECKに対応し、既存の行を検証せず制約を追加できます。

-- SQL Server:既存データを検証せず制約追加
ALTER TABLE employees
WITH NOCHECK ADD CONSTRAINT chk_salary CHECK (salary > 0); 
SQL Server - add constraint without validating existing data
ヒント:MySQLからPostgreSQLへのマイグレーションを計画している場合、制約の挙動差異は事前に監査すべき最重要項目の一つです。

SQL制約を超えたデータ整合性:i2Streamによる対応

SQL制約は単一のデータベースインスタンス内のデータを保護しますが、サーバー障害、レプリケーションの遅延、複数システムに同一データを保有する際の不整合を防ぐことはできません。

分散データベースやリアルタイム分析パイプラインを運用する企業にとって、スキーマ層のルールは必要ですが十分ではありません。ここで活用するのがi2Streamです。

i2Streamは企業向けデータベースレプリケーションソリューションで、システム間を移動するデータの一貫性を保証します。災害復旧サイトへのレプリケーション、新環境へのマイグレーション、データウェアハウスへのデータ供給など幅広い用途に対応します。

i2Streamの主な機能:

  • ミリ秒レベルの低遅延リアルタイム同期:ソースDBに直接クエリを発行せずログ解析で変更を取得するため、高同時実行環境でも本番システムのパフォーマンスに影響を与えず、サブ秒レベルのレプリケーションを実現します。
  • 40種類以上のデータベース・プラットフォームに対応:Oracle、MySQL、PostgreSQL、SQL Server、DB2、MongoDB、Kafka、Hive、HDFSなど主要ビッグデータ基盤と互換性があります。
  • トランザクション単位の整合性、DDL/DML同期:ソース側のテーブル構造変更は自動的にターゲットにレプリケートされ、スキーマ更新時の手作業が不要です。
  • エージェントレス導入:本番ホストにソフトウェアをインストールする必要がなく、稼働システムへのパフォーマンス負荷がゼロです。
  • 可視化管理画面:Webダッシュボードから同期状況、遅延時間、アラートをリアルタイムで確認可能です。

i2Streamはレプリケーション層をカバーします。より包括的なデータ保護が必要な企業向けに、Info2softは物理・仮想・クラウド環境を統合バックアップするi2Backup、自動フェイルオーバーと高可用性を実現するi2Availabilityも提供しています。

SQL制約は正常なデータの定義を定め、i2Streamは連携するすべてのシステムでデータの状態を維持します。

60日間無料トライアル

よくある質問

Q1:主キーとUNIQUE制約の違いは何か

どちらも一意性を強制しますが2点の違いが存在します。1テーブルに定義できる主キーは1つのみでNULLを許可しません。UNIQUE制約は複数定義可能で、データベース製品によってNULLを1つまたは複数登録できます。

Q2:制約はデータベースのパフォーマンスに影響するか

影響はありますが軽微です。INSERT/UPDATE/DELETE実行時に毎回検証処理が走るため少しのオーバーヘッドが発生します。実運用では不正なデータの後始末にかかる時間と比較すると、このコストは十分に見合います。また主キー・UNIQUE制約は自動的にインデックスを作成するため、読み取りクエリの速度はむしろ高速化されます。

Q3:テーブルに設定されている制約を確認する方法

大半のデータベースではinformation_schema.table_constraintsビューをクエリすることで全ての有効な制約を一覧表示できます。SQL Serverの場合はsp_help ‘テーブル名’を実行すると、テーブルに適用されている全ルールの詳細一覧が出力されます。

Q4:アプリ側でデータ検証を実装している場合でも制約を使用すべきか

はい、必ず使用してください。アプリ側のバリデーションはユーザー操作性を向上させますが、データベースへの直接接続、手動SQLスクリプト、コードの不具合などで迂回される可能性があります。データベース層に定義した制約は、どの経路からデータが登録されてもデータを守る最後の防衛線となります。

Q5:既にデータが存在する列にNOT NULL制約を追加できるか

列内にNULL値が1つも存在しない場合のみ追加可能です。NULLが残っているとALTER TABLEコマンドが失敗するため、事前にUPDATE文でNULLを有効な値に置き換えてから制約を追加してください。

まとめ

SQL制約はデータベース設計で活用されにくい便利な機能の一つです。正しく活用すると不正なデータが登録される前段階で検知し、データクリーンアップの手間を削減し、発見困難な静的な不具合を事前に防止します。

本ガイドで紹介した6種類の制約はそれぞれ固有の役割を持ち、NOT NULLによる必須項目の定義からFOREIGN KEYによるテーブル間関連の維持まで対応します。守るべき基本的な習慣は単純です。制約には必ず名前を付ける、稼働中テーブルにルールを追加する前に既存データを監査する、使用しているデータベース製品ごとのNULLやCHECK制約の挙動差異を把握することの3点です。

制約は単一インスタンス内のデータを保護します。複数システム・環境を管理するチームは、レプリケーションとバックアップ戦略と組み合わせることでエンドツーエンドのデータ保護を実現できます。Info2softはデータ保護、レプリケーション、マイグレーション向けのフルラインナップソリューションを提供し、データ整合性が妥協できない企業環境向けに設計されています。

概要は準備中です

関連記事

# 【3つの実用的な手法】SQL Serverにおけるデータベースダンプの実施方法
SQL Serverにおけるデータベースダンプは、バックアップ、環境移行、災害復旧に活用されます。本ガイドではダンプの定義と、複数の汎用手法によるSQL Serverデータベースの出力・復元手順を解説します。
記事を読む
SQL Serverデータベースが復元状態でスタックした場合の6つの効果的な解決策
SQLデータベースが復元モードのままになるトラブルが発生すると、データベースの復元作業が中断し、通常業務に影響を及ぼします。本記事では代表的な発生原因を解説し、当該問題を効率的に診断・解決する6つの実用的な手法を紹介します。
記事を読む
ブロックレベルバックアップ解説:概要、メリット、その他詳細
ブロックレベルバックアップはファイル全体ではなく変更されたデータブロックのみを保存することで、バックアップ速度とストレージ効率を向上させます。本ガイドではブロックレベルバックアップの仕組み、ファイルレベルバックアップとの比較、最新の企業向けバックアップ・災害復旧における役割について解説します。
記事を読む
増分永久バックアップ:完全技術ガイド
増分永久バックアップとは、1回の完全バックアップ実施後に継続的な増分バックアップを実行する最新のバックアップ方式です。本記事ではその動作モデル、主なメリット、課題、各種最新バックアップアーキテクチャとの比較を詳しく解説します。
記事を読む
目次:
最新情報を購読
最新のインサイト、ニュース、限定コンテンツをお届けします。いつでも配信解除が可能です。
購読する
ビジネスデータのセキュリティ強化を始めませんか?
60日間の無料トライアルまたはデモで、Info2softが企業データをどのように保護するかをご確認ください。
フォームにご記入の上、送信してください。担当者より追ってご連絡いたします。
このフォームを送信することにより、 プライバシー通知を読み、同意したことを確認します。
{{ isSubmitting ? '送信中...' : '送信する' }}