導入
データベースを設計する際に、特定の列に入力できるデータに制限を設けたい場合があります。例えば、高層ビルに関する情報を格納するテーブルを作成する場合、各ビルの高さを格納する列に負の値を入力できないようにしたい場合があります。.
リレーショナルデータベース管理システム(RDBMS)では、制約を使用してテーブルに追加されるデータを制御できます。制約とは、1つまたは複数の列(またはテーブル全体)に適用される特別なルールであり、ステートメントを介してテーブルのデータに加えられる変更を制限します。 入れる、 アップデート、 または 消去 制限があります。.
この記事では、制約とは何か、そしてRDBMSでどのように使用されるかを詳細に解説します。また、SQL標準で定義されている5つの制約をそれぞれ取り上げ、対応する機能についても説明します。.
制限事項は何ですか?
SQLにおいて、制約とは、列またはテーブルに挿入できるデータを制限するルールを指します。テーブルに格納されているデータを変更する操作(INSERT、UPDATE、DELETE文など)を実行しようとすると、RDBMSはデータが既存の制約に違反していないかどうかをテストし、違反している場合はエラーを返します。.
データベース管理者は、データベースが定義済みのビジネスルールセットに準拠していることを保証するために、制約を利用することがよくあります。データベースの文脈において、ビジネスルールとは、企業やその他の組織が従うべきポリシーまたは手順であり、そのデータが遵守する必要があります。例えば、顧客の店舗の在庫をカタログ化するデータベースを構築しているとします。顧客が各製品レコードに一意の識別番号を付与することを指定している場合、UNIQUE制約を持つ列を作成し、その列に同じエントリが2つ存在しないようにすることができます。.
制約はデータの整合性を維持するのにも役立ちます。データ整合性とは、データベースに保存されているデータの全体的な正確性、一貫性、合理性を、特定のユースケースに基づいて説明するためによく使われる広義の用語です。データベース内のテーブルは互いに関連していることが多く、あるテーブルの列は別のテーブルの値に依存しています。データ入力は人為的なミスが発生しやすいため、制約はこのような場合に有用です。制約によって、誤って入力されたデータがそのような関係性に影響を与え、データベースデータの整合性を損なうことがないようにすることができます。.
2つのテーブルを持つデータベースを設計しているとします。1つは学校の在校生をリストするテーブル、もう1つはその学校のバスケットボールチームのメンバーをリストするテーブルです。バスケットボールチームテーブルの列に、学校テーブルの列を参照する外部キー制約を適用できます。これにより、チームテーブルの各エントリが生徒テーブルのエントリを参照するように要求することで、2つのテーブル間のリレーションシップが確立されます。.
ユーザーはテーブルを最初に作成するときに制約を定義します。また、テーブル内の既存のデータと競合しない限り、ALTER TABLE 文を使用して後から制約を追加することもできます。制約を作成すると、データベースシステムによって自動的に名前が作成されますが、ほとんどのSQL実装では、各制約にカスタム名を追加できます。これらの名前は、ALTER TABLE 文で制約が変更または削除されたときに、その制約を参照するために使用されます。.
SQL 標準では、正式には次の 5 つの制約のみが定義されています。
- 主キー
- 外部キー
- 個性的
- レビュー
- 空ではありません。
制約の使用方法について大まかに理解できたので、次にこれら 5 つの制約をそれぞれ詳しく見ていきましょう。.
主キー
PRIMARY KEY 制約では、特定の列の各エントリが一意であり、NULL ではないことが要求されるため、その列を使用してテーブル内の個々の行を識別できます。.
リレーショナルモデルにおいて、キーとはテーブル内の列または列セットのことであり、各値は一意であり、NULL値を含まないことが保証されています。主キーは特別なキーであり、その値はテーブル内の個々の行を識別するために使用されます。また、主キーを構成する列は、データベースの残りの部分でテーブルを識別するために使用できます。.
これはリレーショナルデータベースの重要な側面の一つです。主キーを使用すると、ユーザーはデータが物理的にマシンに保存されていることを意識する必要がなく、DBMSは各レコードを追跡し、アドホックに取得できます。つまり、レコードに論理的な順序は定義されておらず、ユーザーは任意の順序やフィルターを使用してデータを取得できます。.
SQLでは、PRIMARY KEY制約を使用して主キーを作成できます。これは基本的にUNIQUE制約とNOT NULL制約を組み合わせたものです。主キーが定義されると、DBMSはそれに関連付けられたインデックスを自動的に作成します。インデックスは、テーブルからデータをより速く取得するのに役立つデータベース構造です。教科書の索引のように、クエリはインデックスが付けられた列のエントリを調べるだけで関連する値を見つけられます。これにより、主キーはテーブル内の各行の識別子として機能します。.
テーブルには主キーを1つしか持てませんが、通常のキーと同様に、主キーは複数の列で構成できます。とはいえ、主キーの特徴は、テーブル内の各行を一意に識別するために必要な最小限の属性セットのみを使用することです。この概念を説明するために、次の3つの列を使用して学校の生徒に関する情報を格納するテーブルを想像してみてください。
学生ID: 各生徒の固有の識別番号を保存するために使用されますファーストネーム: 各生徒の名前を記入するために使用されます苗字: 各生徒の姓を記入するために使用されます
学校内の生徒の中には、同じ名前(ファーストネーム)を持つ生徒がいる可能性があります。その場合、firstName列を主キーとして使用するのは適切ではありません。lastName列についても同様です。firstName列とlastName列の両方を主キーとして使用することは可能ですが、それでも2人の生徒が同じ名前(ファーストネームとラストネーム)を持つ可能性があります。.
学生IDとfirstName列またはlastName列からなる主キーも有効ですが、各学生のID番号は既に一意であるため、各名前列を主キーに含めるのは冗長です。したがって、この場合、各行を識別できる最小限の属性セットは、学生ID列のみであり、これがテーブルの主キーとして適切です。.
キーが観測可能で使用可能なデータ(つまり、現実世界のエンティティ、イベント、またはプロパティを表すデータ)で構成されている場合、それは自然キーと呼ばれます。キーが内部的に生成され、データベース外部のものを何も表さない場合、それは代理キーまたは人工キーと呼ばれます。一部のデータベースシステムでは、一見固定されているように見えるデータポイントでさえ予測できない形で変化する可能性があるため、自然キーの使用を推奨していません。.
外部キー
FOREIGN KEY 制約では、特定の列の各エントリが別のテーブルの特定の列に既に存在している必要があります。.
2つのテーブルを相互に関連付けたい場合、FOREIGN KEY制約を使用して外部キーを定義する方法があります。外部キーとは、一方のテーブル(「子」テーブル)の列の値が、もう一方のテーブル(「親」テーブル)のキーから取得されることを意味します。これは、2つのテーブル間の関係を表す方法です。FOREIGN KEY制約では、適用対象の列の値が、参照先の列にも必ず存在することが条件となります。.
次の図は、2つのテーブル間の関係を示しています。1つは会社の従業員に関する情報を記録するテーブル、もう1つは会社の売上を追跡するテーブルです。この例では、EMPLOYEESテーブルの主キーがSALESテーブルの外部キーによって参照されています。
子テーブルにレコードを挿入しようとした際に、外部キー列に入力された値が親テーブルの主キーに存在しない場合、挿入ステートメントは無効になります。これにより、両方のテーブルの行は常に正しく関連付けられるため、リレーションシップレベルでの整合性が維持されます。.
多くの場合、テーブルの外部キーは親テーブルの主キーと同じですが、必ずしもそうとは限りません。ほとんどのRDBMSでは、親テーブルでUNIQUE制約またはPRIMARY KEY制約が設定されている列は、子テーブルの外部キーから参照できます。.
個性的
UNIQUE 制約は、指定された列に重複する値が追加されるのを防ぎます。.
名前が示すように、UNIQUE制約は、特定の列の各エントリが一意の値を持つことを要求します。列に既に存在する値を追加しようとすると、エラーが発生します。.
UNIQUE制約は、テーブル間の1対1の関係を確立するのに役立ちます。前述のように、外部キーを使用して2つのテーブル間の関係を確立できますが、テーブル間にはいくつかの種類の関係が存在します。
親テーブルの行が子テーブルの 1 つの行にのみ対応している場合、2 つのテーブルは 1 対 1 の関係にあると言われます。.یک به یک1対多: 多対任意のリレーションシップでは、親テーブルの行は子テーブルの複数の行に関連付けられますが、子テーブルの各行は親テーブルの 1 つの行にのみ関連付けられます。.幾つか?親テーブルの行が子テーブルの複数の行に関連付けることができ、その逆も成り立つ場合、2 つの間には多対多の関係があると言われます。.
FOREIGN KEY 制約が適用されている列に UNIQUE 制約を追加すると、親テーブルの各エントリが子テーブルに 1 回だけ表示されるようになり、2 つのテーブル間に 1 対 1 の関係が確立されます。.
UNIQUE制約は、列レベルだけでなくテーブルレベルでも定義できることに注意してください。テーブルレベルで定義した場合、UNIQUE制約は複数の列に適用できます。この場合、制約内の各列には重複した値を設定できますが、各行には制約対象列の値の組み合わせが一意である必要があります。.
レビュー
CHECK 制約は、列に入力される値が満たす必要がある条件 (述語と呼ばれる) を定義します。.
CHECK制約述語は、TRUE、FALSE、または潜在的に不明な値に評価される式として記述されます。CHECK制約に値を入力し、その値によって文がTRUEまたは不明な値(NULL値の場合に発生)に評価された場合、操作は成功します。ただし、式がFALSEに評価された場合は失敗します。.
CHECK述語は、多くの場合、数学的な比較演算子(<、>、<=、OR >=など)を使用して、特定の列で許容されるデータの範囲を制限します。例えば、CHECK制約の一般的な用途の一つは、以下の例のように、負の値が意味をなさない場合に、一部の列に負の値が保持されるのを防ぐことです。.
この CREATE TABLE 文は、各製品の名称、ID番号、価格の列を持つ productInfo というテーブルを作成します。製品の価格が負の値を持つことは意味をなさないため、この文は価格列に CHECK 制約を適用し、正の値のみを持つことを保証します。
CREATE TABLE productInfo (
productID int,
name varchar(30),
price decimal(4,2)
CHECK (price > 0)
);すべてのCHECK述語で数学的な比較演算子を使用することはできません。通常、CHECK述語では、LIKE、BETWEEN、IS NOT NULLなど、真、偽、または不明と評価できる任意のSQL演算子を使用できます。一部のSQL実装では、CHECK述語にサブクエリを含めることもできますが、すべてではありません。ただし、ほとんどの実装では、ステートメント内で別のテーブルを参照することはできません。.
空ではありません。
NOT NULL 制約は、指定された列に NULL 値が追加されないようにします。.
ほとんどのSQL実装では、データ行を挿入した際に特定の列に値を指定しなかった場合、データベースシステムはデフォルトでその欠損データをNULLとして扱います。SQLにおいて、NULLは未知の値、欠損値、または未指定値を表す特別なキーワードです。ただし、NULLは値そのものではなく、未知の値の状態を表します。.
この違いを説明するために、タレント事務所で顧客管理を行うテーブルを想像してみてください。このテーブルには、各顧客の姓と名を入力する列があります。顧客が「シェール」、「アッシャー」、「ビヨンセ」など、名前を1つだけ使用している場合、データベース管理者は「名」列に名前を1つしか入力しない可能性があります。その結果、DBMSは「姓」列にNULLを挿入します。データベースは、顧客の姓を文字通り「NULL」とは見なしません。これは、その行の姓列の値が不明であるか、そのフィールドがそのレコードに適用されないことを意味するだけです。.
名前が示すように、NOT NULL制約は、指定された列の値がNULLになることを禁止します。つまり、NOT NULL制約が設定された列には、新しい行を挿入する際に必ず値を指定する必要があります。そうしないと、INSERT操作は失敗します。.
結果
制約は、高いレベルのデータ整合性とセキュリティを備えたデータベースを設計しようとするすべての人にとって不可欠なツールです。列に入力されるデータを制限することで、テーブル間の関係が適切に維持され、データベースがその目的を定義するビジネスルールに準拠していることを保証できます。.










