リレーショナルデータベースシステムでは、データベースインデックス はデータ検索のための非常に強力なツールです。このガイドでは、一意のインデックス、主キー、および複合主キーについて学習します。
データベースインデックスとは何ですか?
データベースインデックス データベーステーブルに関連付けられたデータ構造オブジェクトです。これは、データベースクエリの速度を上げるために使用されます(SQL SELECT
を介して) 指図)。一般に、作成するインデックスのタイプを決定するための明確に定義された方法があります。これは主に、データベース内のテーブルが相互にどのように関連し、データがどのように取得されるかによって決まります。
インデックスを使用する理由
一般に、SQL SELECT
を介したテーブル内のクエリ(またはルックアップ) コマンドはシーケンシャルです。シーケンシャルルックアップでは、テーブルの先頭から開始し、目的のデータが取得されるまでデータのすべての行を読み取る必要があります。これは非常に非効率的であり、速度の点でコストのかかる操作になる可能性があります。
一方、インデックスは、ハッシュ関数を使用してインデックス値を計算します。インデックス内の影響を受ける行(キー)への直接アクセスを提供します。その行(キー)がインデックスに配置されると、インデックスレコードには、クエリで必要なテーブル行への直接のポインタが含まれます。これらのポインタは、インデックスの作成およびインデックスの保守中に確立されます。インデックスを使用する場合のデータ取得の速度は桁違いに向上します。
一意のデータベースインデックスの構造
データベーステーブルには、1つ以上のインデックスを関連付けることができます。インデックス自体は、テーブル内の1つ以上の列の行(キー)値を保持します。また、これらのキー値を含む実際のテーブル行を指すポインターもあります。インデックス内の特定のキーが指す行数は、そのインデックスが一意のインデックスであるかどうかによって異なります。 または一意でないインデックス 。
名前が示すように、一意のインデックスには、特定のテーブルの1つのデータ行のみを指すキーが含まれています。一意のインデックスにより、テーブルの各行に、定義されたインデックス付きテーブルの列に一意の値が含まれるようになります。事実上、2つの行がインデックス付きの列に同じ値を持つことはできません。さらに、主キーとして指定された列に一意のインデックスが作成されます テーブルのために。主キーは、データベーステーブルの行を一意に定義する1つ以上の列として定義されます。
以下の例は、SQLで主キーと一意のインデックスがどのように使用されるかを示しています。すべての例では、Student
という名前のテーブルを使用しています 、exampledb
という名前のサンプルデータベース 。サンプルデータを追加するには、次のコマンドを使用します。
INSERT INTO Student(SSNumber, LastName, FirstName)
VALUES
(111111111, Smith, John),
(222222222, Jones, Mary),
(333333333, Hansen, Robert);
Student
に保存されているデータを表示する テーブル:
SELECT * FROM Student;
次の出力が表示されます。
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 111111111 | Smith | John |
| 222222222 | Jones | Mary |
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
注 特に明記されていない限り、このガイドのすべてのコマンドは、両方の MySQLで適切に機能します。 およびPostgreSQL データベース。
単一列の主キーとインデックス
例として、学校がStudent
という名前のテーブルで生徒を追跡していると仮定します。 。このテーブルには、Student
という名前の列が関連付けられています 、SSNumber
、LastName
、およびFirstName
。これらの列から、Student
Student
のデータの各行を一意に識別するため、は主キー列です。 テーブル。一意のインデックスを作成します(SSIndex
)SSNumber
で 列、テーブルからのデータの迅速な取得を容易にします。このクエリを実行するには、次のSQLDDLコマンドを使用します。
CREATE TABLE Student(SSNumber CHAR(9)NOT NULL、LastName VARCHAR(30)NOT NULL、FirstName VARCHAR(20)NOT NULL、PRIMARY KEY(SSNumber));
CREATE UNIQUE INDEX SSIndex ON Student (SSNumber);
注 上記の両方のSQLコマンドは、ほとんどのリレーショナルデータベースシステムと互換性のあるセミコロン(;)で区切られています。 SSNumber
テーブルの主キーとして具体的に指定されています。
SSIndex
Student
の各行のデータを一意に識別する情報のみが含まれています テーブル。 SSIndex
の各行 Student
の対応する行へのポインタがあります テーブル。このSSIndex
インデックスを使用すると、テーブル内のデータの順次検索を回避でき、クエリに必要な時間を最小限に抑えてパフォーマンスを向上させることができます。
Robert Hansen
の関連情報を見つけるには SSNumber
経由 、以下に含まれるSQLコマンドを使用します。このコマンドは、Student
の順次検索を排除するだけではありません。 テーブルだけでなく、SSIndex
も使用します 必要なデータ行への直接アクセスを提供します。これは、ハッシュ関数と関連するインデックスポインタを使用しているためです。
SELECT * FROM Student WHERE SSNumber = 333333333;
返されるデータは次のとおりです。
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
複数列の複合主キーとインデックス
このセクションの例では、テニスリーグに関連するデータを格納する3つのテーブルを使用しています。 3つのテーブルの名前はPlayer
です。 、League
、およびMembership
。プレーヤーは複数のリーグでプレーでき、メンバーシップテーブルはその関連付けを提供します。 3つのテーブルには、次の列が関連付けられています。
Player
の列 表はPlayedID
とともに下に表示されます 主キーとして。
+----------+-----------+-----------+
| PlayedID | LastName | FirstName |
+----------+-----------+-----------+
League
の列 表はLeagueId
とともに下に表示されます 主キーとして。
+----------+------------+------------+
| LeagueId | LeagueName | SkillLevel |
+----------+------------+------------+
Membership
の列 表は下に表示されます
+----------+-----------+
| PlayedID | LeagueId |
+----------+-----------+
以下の手順は、Player
を作成する方法を示しています 、League
、およびMembership
テーブル。
-
Player
から テーブル、PlayedID
列は、データの各行を一意に識別します。Player
を作成します テーブルの後にPlayerId
の一意のインデックスが続きます 列。CREATE TABLE Player ( PlayedID INT NOT NULL, LastName VARCHAR(30) NOT NULL, FirstName VARCHAR(20) NOT NULL, PRIMARY KEY (PlayedID) ); CREATE UNIQUE INDEX PlayerIndex ON Player (PlayedID);
-
League
から テーブル、LeagueId
列は、データの各行を一意に識別します。League
を作成します テーブルの後にLeagueId
の一意のインデックスが続きます 桁。この操作を実行するためのSQLコマンドは次のとおりです。CREATE TABLE League ( LeagueId INT NOT NULL, LeagueName VARCHAR(50) NOT NULL, SkilLevel VARCHAR(20) NOT NULL, PRIMARY KEY (LeagueId) ); CREATE UNIQUE INDEX LeagueIndex ON League (LeagueId);
-
Membership
から テーブル、両方のPlayedID
およびLeagueId
列はデータの各行を一意に識別します。これは複合主キーです。Membership
を作成します テーブルの後にPlayedID
の一意の複合インデックスが続きます およびLeagueId
列。CREATE TABLE Membership ( PlayerId INT NOT NULL, LeagueId INT NOT NULL, PRIMARY KEY(PlayerId, LeagueId) ); CREATE UNIQUE INDEX MembershipIndex ON Membership (PlayerId, LeagueId);
MembershipIndex
複合キー(PlayedId
で構成されるハッシュ生成インデックスです およびLeagueId
)。それが表すデータ行へのポインタがあります。このようなインデックスを使用すると、線形シーケンシャルデータ検索とは対照的に、迅速な直接アクセスデータ検索が容易になります。たとえば、上記の各表のいくつかのレコードから「Men’s Doubles」に関連付けられているすべてのプレーヤーを特定するには、次のSQLコマンドを発行できます。
SELECT Player.LastName, Player.Firstname
FROM Player, Membership
WHERE Membership.LeagueId = 2
AND Membership.PlayerId = Player.PlayerId
次のデータが返されます:
+----------+-----------+
| LastName | FirstName |
+----------+-----------+
| Smith | John |
| Hansen | Robert |
+-----------+----------+
MembershipIndex
を使用しない場合 およびPlayerIndex
、上記のクエリの実行速度は大幅に低下します。
非一意のインデックス
非一意のインデックスには、特定のキー値の1つ以上の行を指す可能性のあるエントリが含まれています。たとえば、人の名前で検索するには、両方のFirstName
のテーブルに一意でない複合インデックスを作成する必要があります。 およびLastName
。 FirstName
の組み合わせ以降 およびLastName
一意であることを保証することはできません。これらの2つの列に作成された結果のインデックスは、非一意のインデックスを効果的に生成します。
インデックスを使用したデータベースパフォーマンスの低下の問題
インデックスはクエリの実行速度を向上させますが、インデックス付きの列が変更されたとき、またはテーブルの行がデータベースに追加またはデータベースから削除されたときに更新する必要があります。これは、データベースのパフォーマンスに悪影響を与える可能性があります。トランザクションデータベースの使用中にインデックスに必要な挿入、削除、および変更の量を覚えておくことが重要です。データベースアプリケーションで何が重要かを検討してください。クエリ実行の速度またはデータ操作の速度。その質問に対する答えは、データベースアプリケーションの使用方法、データベースの設計に影響を与える頻度、および作成されるインデックスの数にあります。
結論
データベースインデックスを作成して使用すると、迅速なクエリ取得応答が生成され、テーブルからの連続した行ルックアップが排除されます。ただし、データ操作によるインデックスの保守は、データベースのパフォーマンスに悪影響を与える可能性があります。データベース設計者は、データベースインデックスを使用する際のトレードオフを認識し、データベース全体のパフォーマンスの最適化に留意する必要があります。