データベーススペシャリスト試験勉強用。
DBとは
Database(データベース)とは、データの集合のことを指す。
「データ」とは特定の形式にフォーマットされた事実のことを指し、「情報」とはデータを特定の文脈や観点に従って集約または加工、抽出されたものを指す。
DBMSとは
DBMS(Database Managemant System)はデータベースを実装したソフトウェアを指す。
混同しやすいのは、DB自体は単体では使うものではなく、DBMSを介して利用するということ。会話の中では「DBMS」を指して「DB」と言ったりするため、厳密には違うということを理解しておきたい。
DBのモデル
DBの代表的なモデルはリレーショナルDBだが、リレーショナルDBはいくつかの種類のうちの一つにすぎない。
-
RDB
- Relational Database
- リレーショナルデータベース
- 表形式(テーブル)データを管理する
- SQL(Structured Query Language)を用いてデータを操作する
- Oracle Database、SQL Server、PostgreSQL、MySQL
- NoSQL
- Not Only SQL
- スキーマが存在せず、RDBよりも柔軟性が高い
- MongoDB、Redis、Apache Cassandra、Neo4j
- キーバリュー型ストア
- KVS、Key - Value Store
- Key と Value による単純構造
- 高速
- XMLDB
- XML Database
- XML形式の階層構造でデータを扱う
- 列指向データベース
- 行指向データベース(RDB)と対比される文脈で使用される分類
- Apache Cassandra、HBase
- オブジェクト指向データベース
- OODB、Object Oriented Database
- データと操作をオブジェクトにまとめて管理する
- Java、C++などの言語が採用している
- グラフデータベース
- データをノードとエッジのネットワーク関係で保存、管理する
- Neo4j、ArangoDB
- メモリデータベース
- メインメモリ(主記憶装置。物理的にはRAM)上にデータを保持する
- 一時的なデータやキャッシュに利用される
- Redis、Memcached
- 時系列データベース
- センサーデータやログデータなどを保存、分析するために特化したもの
- InfluxDB、TimescaleDB
RBDの製品
- Oracle Database
- Oracle社製
- Windows OS、Linuxのマルチプラットフォーム対応
- 有料(商用利用時)
- SQL Server
- Microsoft社製
- Windows OSでのみ使用可能
- 有料(商用利用時)
- DB2
- IBM社製
- Windows OS、UNIX系OSのマルチプラットフォーム対応
- PostgreSQL
- 米バークレイ大学製
- 無料(OSS)
- MySQL
- サン・マイクロシステムズ → Oracle社製
- 無料(OSS)
3層スキーマ
構造を論理的に分類するためのモデル。
- 外部スキーマ
- 概念スキーマ
- 内部スキーマ
昔は概念スキーマが存在せず外部スキーマと内部スキーマのみであったが、両者の依存性が高いために、アプリケーションの仕様変更やデータの物理的な格納方法変更が広範囲に影響を与えた。
そこで両者の依存を弱めることを目的として概念スキーマが登場した。
概念スキーマによって外部スキーマはデータベースの内部構造を意識する必要がなくなる(その逆も然り)。
概念スキーマは内部スキーマを仲介することで両者の依存を弱め、変更に対する柔軟性を提供する。
設計
設計にはそれぞれ概念設計、論理設計、物理設計と呼ばれる工程がある。これらの分類は正確に3層スキーマと対応するものではないが、概ね以下のような位置付けとなっている、
外部スキーマ ↔ 概念設計
概念スキーマ ↔ 概念設計、論理設計
内部スキーマ ↔ 物理設計
概念設計と論理設計は厳密に区別できない場合がある。概念設計は「データの意味とその関係を理解し、視覚化することによって要件を正確に捉えること」に焦点を当てて行うのに対して、論理設計では、「概念設計で作成したデータモデルを具体的かつ効率的なデータベース構造に変換すること」に焦点を当てて行う。
概念設計 ▶️ データの意味とその関係を理解し、視覚化することによって要件を正確に捉えること
論理設計 ▶️ 概念設計で作成したデータモデルを具体的かつ効率的なデータベース構造に変換すること
また、概念設計の成果物は主にER図なのに対して、論理設計の成果物は正規化されたテーブル定義やデータモデルとなる。ただし、論理設計ではER図のブラッシュアップが行われることもあり、両者を明確に区別できない場合がある、
論理設計では原則、特定のDBMS(内部スキーマ)に依存しない形でデータ構造を定義する。
一般的には以下の順に行われる。
要件分析
システムが必要としているデータの種類、データ同士の関係、制約、必要な操作を分析し、「何を」「どのようなフォーマットで」保存するかを決定する。
データフローを理解することも必要とされる。
初めてシステム化されるなどの場合、データがデータベース向けに整理されていない事があり、データクレンジングと呼ばれるデータフォーマットが必要になることもある。
概念設計
ER図やUML(Unified Modeling Language)を使用して現実の世界をモデル化する設計工程。概念設計により作成されるデータモデルを 概念モデル と言う。
概念モデルとは、エンティティやエンティティ同士の関係、属性、制約などの定義を指す。
またこの段階で作成するER図はまだ正規化を行なっておらず、おおまかなエンティティとその関係性だけを表現したものになる。
トップダウンアプローチ
システム全体の概念を最初に定義し、それを段階的に詳細化していく手法。大きな枠組みから出発し、徐々に具体的な部分に焦点を当てていく。
要件分析
⬇️
ER図作成
⬇️
属性の洗い出し。キー、制約の設定
⬇️
正規化
システム全体を俯瞰できると言う利点があり、大規模システムに向いている。また本来どうあるべきかと言う視点で進められるため、理想的なデータモデルを構築することができる。
一方で、設計の初期段階で要件定義をする必要があるためエンティティに過不足が発生しやすく設計の難易度が高い。そのため、高いスキルが求められ、設計の変更が発生しやすいことなどがある。
ボトムアップアプローチ
既存のデータや小さなデータ単位から出発し、それらを組み合わせて全体のシステムを構築する手法。具体的なデータやプロセスからスタートして、徐々に大きな構造を作り上げていく。
属性の洗い出し。キー、制約の設定
⬇️
正規化
⬇️
ER図作成
具体的なデータに基づいた設計を行うため、現実に即した設計ができ、小規模なシステムに向いている。一方で、全体の構造が最後まで見えないため、全体の一貫性を保ちづらい、細部がうまく噛み合わず設計が非効率になりやすいと言う欠点がある。
論理設計
Logical Design
概念モデルをもとにしてテーブルの構造、カラムやキーなどの制約条件の定義を行い 論理データモデル を作成する。
物理設計
Physical Design
論理設計で作成されたテーブル定義書を基に、データベースのパフォーマンスや効率を考慮して、実際のDBMS上にデータベースを構築する。インデックスの作成やストレージの最適化などを行う。
物理設計で作成されるデータモデルを 物理データモデル と言う。
インデックス設計
⬇️
物理的なストレージの選定
⬇️
ストレージの冗長構成の決定
⬇️
ファイルの物理配置
⬇️
パフォーマンスチューニング
ER図
Entity-Relationship Diagram
実体関連図。
その名の通り、エンティティとリレーション(関係)を可視化した図のこと、
ER図を作成する際に注目すべきポイントは主キー。主キーを中心に見ていくことで1対1、1対多、多対多などのテーブル同士の関係性に気が付きやすくなる。
1対1、1対多、多対多などのテーブル同士の関係性をカーディナリティと言う。
エンティティ
日本語で「実体」。
物理的に存在する「顧客」「商品」「人物」を指すこともあれば、物理的実体を伴わない「注文履歴」「注文」などを指すこともある。
エンティティはテーブルにおいて属性(列)という形で管理される。
エンティティは長方形で表現する。
エンティティには複数の属性が含まれることがある。なお、属性はER図において省略される場合がある。
主キー属性は上に記載し、非キー属性は下に記載する。
概念データモデルと関係スキーマは対で作成される。
強エンティティ / 弱エンティティ
単独で存在できるエンティティを強エンティティと言い、強エンティティが存在して初めて存在することができるエンティティを弱エンティティと言う。
「注文」は単独で存在することができるため強エンティティに分類されるが、「注文明細」は「注文」の存在があって初めて存在することができるエンティティであるため、弱エンティティに分類される。
カーディナリティ
Cardinality = 濃度
様々な文脈で使用される用語。
エンティティ間にリレーションが存在する時、一方のエンティティに対応するもう一方のエンティティのレコード数をカーディナリティと言う。
以下の4つがある。
カーディナリティ | |
---|---|
1対1 | 例:社員とパスポート 1人の社員に対してパスポートは複数存在しない 反対に、1つのパスポートに対して複数の社員は存在しない |
1対多 | 例:親と子 1人の親は複数の子を持つことができる 反対に、それぞれの子は1人の親としか関連しない |
多対1 | 例:兄弟姉妹と親 複数の子が1人の親に関連する 反対に、1人の親は複数の子(兄弟姉妹)に関連する |
多対多 | 学生と受講コース 各学生は複数のコースを受講できる(1人の学生に着目すると、その学生は複数の受講コースを持ち、同じような学生が複数存在する) 各コースは複数の学生から受講される(1つのコースに着目すると、そのコースは複数の学生から受講されていて、同じようなコースが複数ある) |
1対1
1対多
エンティティが常に1以上存在する(⚫︎)とき、次のように表現する。
一方のエンティティが存在しない(◯)場合があるときは、次のように表現する。
多対多
多対多の関係は、一方を特定するためのキーを持たないため、好ましくないとされる。多対多の関係を解消するには、2つのテーブルの間に連関エンティティと呼ばれるエンティティを作成する方法がある。
連関エンティティ
associateive entity
多対多の関係はデータモデルとしての表現はできるが、実装することができない。「多対多」の関係を2つの「1対多」の関係に分解して、連関エンティティに双方のエンティティ間の関係情報を管理させる。
連関エンティティは連結エンティティ、関連エンティティと呼ばれることがある。
連関エンティティは、「多対多」の関係に介入することで「多対多」の関係を「1対多」の関係に分解する
スーパータイプ / サブタイプ
複数の子エンティティが共通の親エンティティを持つとき、親エンティティをスーパータイプ、子エンティティをサブタイプと表現する。
オブジェクト指向プログラミングと同じで、親から子への方向を特化、子から親への方向を汎化と言う。
サブタイプには排他的サブタイプと共存的サブタイプがある。
排他的サブタイプ
Mutually Exclusive Subtypes
スーパータイプが、一つのサブタイプにしか属さない。
具体例として、スーパータイプ「従業員」に対するサブタイプ「正社員」「パートタイプ社員」などがある。
共存的サブタイプ
Overlapping Subtypes
スーパータイプが、複数のサブタイプに同時に属することができる。
具体例としてスーパータイプ「アプリケーション」に対する「ゲームアプリ」「教育アプリ」などがある。
制約
検査制約
CHECK
属性の取りうる値の範囲を制限する(特定の範囲内の値しか登録できない)ための制約。
CHECK (condition)
condition
の例としては範囲を制限するものがある。
CHECK (column_name > 0)
CHECK (column_name IN (0, 1, 2, 3))
一意性制約
UNIQUE
(主キー以外の)特定の属性(列)において他のレコードとの重複を許容しないための制約。候補キーに対して使用される。
NOT NULL 制約
NOT NULL
属性値にNULLを許容しないための制約。可能な限り設定した方が良い。
主キー制約
PRIMARY KEY
テーブル内で値が一意であることを保証するための制約。一意性制約とNOT NULL 制約を組み合わせたもの。
参照整合性制約
REFERENCES
子テーブルの外部キーが別の親テーブルの主キーまたは一意のキーを参照することを保証するための制約。外部キー制約とも呼ばれる。
親のテーブルの主キー、一意のキーに存在しない値を子のテーブルの外部キーに許可しないようする事ができる。
例えば「部署」、「社員」というテーブルがあった時に、部署テーブルの主キーに存在しない部署IDを、社員テーブルの所属部署IDとして格納することはできない。
カスケード
CASCADE
参照整合性制約が存在するテーブルにおいて、親テーブルでの変更や削除が子テーブルにも影響を与えること。
親テーブルの変更や削除が起きた場合、整合性を保つためには更新された親テーブルのデータを参照する子テーブルのレコードに対して、何らかのアクション(カスケード操作)が必要となる。
例えば、親テーブルで主キーの属性値が1つ削除された場合に、もし子テーブルでその属性値を参照していたら、存在しないデータを参照していることになってしまうため削除しなければならない。
もしこのようなカスケード操作が必要になってしまったら、データ削除は親からではなく子から削除するようにして、カスケード操作自体がなるべく発生しないようにした方が良い。
カスケード操作は、なるべく必要にならない方が良い
ページ
データをディスクに格納するための最小単位を ページ と言う。データベースは大量のデータを扱うため、ディスクに保存する際はこのページ単位でデータを扱う。
データベース製品の使用によって異なるものの、一般的にページは2000バイト(2KB)、4000バイト(4KB)、8000バイト(8KB)、16000バイト(16KB)などの固定サイズになっている。
ページは、データベースエンジンがデータを読み書きする際の基本単位になるため、例えデータの更新が1レコードの1カラムに関わるほんのわずかなものであったとしても、更新するレコードを含むページがディスクからは読み込まれる。
ページにはいくつかの種類がある。
データページ
テーブルのレコードが格納されるページ。
インデックスページ
インデックス情報が格納されるページ。
LOBページ
テキストやバイナリデータなどの Large Object を格納するためのページ。
テキスト型の LOB は CLOB (Charactor LOB)、バイナリ型の LOB は BLOB (Binary LOB) と呼ばれる。
トランザクションログページ
トランザクションログが格納されるページ。障害時のリカバリに利用される。
インデックス
データベースにおいて検索速度を向上させるために使用されるデータ構造をインデックスという。
インデックスは、テーブルの特定の列(または列の組み合わせ)に対して作成され、クエリの実行速度を大幅に改善させる。
ソート操作にも有効で、特定の列にインデックスがある場合、その列に基づくソートが高速に行うことができる。
インデックスは、テーブルの特定の列(または列の組み合わせ)に対して作成され、クエリの実行速度を大幅に改善させる
ただしデータベースにとってインデックスの設定は必須のものではなく、あくまでもパフォーマンス向上のためのものである。
またインデックスの実体は、特定の列の値(キー)と、その値が格納されているレコード(実データ)へのポインタ(参照)がプログラミング言語のMapのような形で保持されたもの。Bツリーインデックスやハッシュインデックスなどの形で実装される。
インデックスの実体は、
key:列
value:レコードへのポインタ
の key-value マップ
実装方式には様々あるものの、実際には他のデータ構造と比べて多くの側面で平均点以上の性能を持つオールラウンド型であるBツリーインデックスが選択されることがほとんど。
クラスタリングインデックス
key-value形式で保存される複数のデータを、記憶装置の同じ場所に物理的に固めて格納することをクラスタリングという。クラスタリングされていないインデックスはすべて、非クラスタリングインデックスになる。
まとめて格納されることで、BETWEEN
や比較演算子によって範囲を指定した検索時に、検索対象データが物理的にまとまった位置から取得することができる。
クラスタリングインデックスは1つのテーブルに対して、1つしか設定できないため、主キーに対して設定することが最も効果的とされる。
クラスタリングインデックスは、1つのテーブルに1つしか設定できないため、主キーに設定することが効果的
Bツリーインデックス
最も一般的なインデックス。(Bツリーの「B」には特に意味がない)
Bツリーインデックスは、ツリー構造によってデータを管理し、そのうちリーフ(末尾のノード)だけが実データへのポインタを保持している。
平衡木(Balanced Tree)と呼ばれる構造になっていて、ルートからリーフまでの深さが全方向で等しいため、キーの値に関わらず常に同じ計算量でルートからリーフまでたどり着く事ができるとされる。平衡木はバランス木とも呼ばれる。
平衡木はすべてのリーフの深さが均一なツリー構造
ただし、テーブルの更新を繰り返すことによって平衡木構造が少しづつ崩れていくため、探索コストは徐々に均等でなくなっていく。そのため、インデックスを作成した属性(列)自体の値が更新されるような場合、定期的にインデックスを作成し直すメンテナンスを行う必要がある。
Bツリーにおける検索の計算量は、ツリーの深さ(の最大値)に依存し、データ数には単純比例しない。そのため通常、レコード数が1万を超えるような大規模なテーブルに対して使用する事が効果的。小規模なレコード数の場合、インデックスを作成しない方が、よりパフォーマンスの良いことがある。
設計におけるインデックス
インデックスはデータ検索時のパフォーマンスを大幅に改善させ得るものである一方で、設定することでかえってパフォーマンスが悪くなる場合もあるため、その点を考慮した設計が必要になる。
具体的にはインデックスの設定はSELECT
文に対してはパフォーマンス向上の要因となるが、INSERT
、UPDATE
、DELETE
文に対しては実行の度にインデックスの再構築が必要になるため、パフォーマンス低下の要因になる。
そのため、データの更新頻度がインデックス設定の可否を決める上で重要となる。また、検索時にあまり利用されない列に対してインデックスを設定することは避けるようにする。
インデックスはデータの更新頻度を加味して設計する
データの量がそれほど多くない場合、インデックスを使用した検索よりも、単純な検索の方が高速な場合もある。
その他、以下の点に留意する。
- 不等号(
<
、>
、<=
、>=
)、BETWEEN
に対してもインデックスは有効だが、否定条件(<>
、!=
)に対しては効果がない - カーディナリティ(属性が取りうる値のバリエーション)が高い属性に対して使用することによって、データ全体に対して検索対象を大幅に絞り込むことができる。ただしこの場合、データの分布が特定の属性値に偏っているデータに対しては効果が薄い
- SQL文の
WHERE
句、結合条件に指定される属性に対して使用する - SQL文の中でインデックスを作成した属性を演算して利用してしまうと効果がなくなる
-
IS NULL
を使用しても効果がなくなる -
OR
を使用しても効果がなくなる - 暗黙の型変換が行われている場合も効果がなくなる
- 主キー、一意制約を設定した属性に対しては内部で自動的にインデックスが作成されるため、改めて作成する必要はない
インデックスは、不等号(<
、>
、<=
、>=
)、BETWEEN
に対して有効
否定条件(<>
、!=
)に対しては効果がない
トランザクション
トランザクションが満たすべきとされる特性はACID特性と呼ばれる。
ACID特性
原始性 / Automicity
トランザクション内の操作は、「成功する(コミット)」か、または「失敗する(ロールバック)」かのいずれかにしかならないことが保証された状態。部分的に操作が成功することがない。
一貫性 / Consistency
トランザクションの開始前と後でデータの一貫性が失われないことが保証された状態。
異なる2つのトランザクションが存在するとき、どのような順番で実行しても最終的なデータの状態が同じになることを指し、直列化可能性、直列可能性とも言う。
独立性 / Isolation
複数のトランザクションを同時に実行しても、互いに干渉しないことが保証された状態。独立性のレベルには以下の4つの段階(分離レベル)がある。
これらの分離レベルは一般的に、程度が上がるにつれてデータの整合性が高まるが、処理負荷が増すためパフォーマンスは低下する。
分離レベルを上げるほどデータの整合性は増すが、パフォーマンスは低下する
READ UNCOMMITED
- 最も程度が低い分離レベル
- 他のトランザクションがコミットしていない変更も読み取ることができる(ダーティリードが発生する)
READ COMMITED
- 他のトランザクションがコミットした変更のみを読み取ることができる(ダーティリードが発生しない)
- 読み取ったデータが、他のトランザクション開始時点のデータであることが保証されていないため、実行元トランザクション内で同じクエリを複数回実行した際に、異なる実行結果になる可能性がある(アンリピータブルリードが発生する)
REPEATABLE READ
- トランザクションが開始された時点のデータを読み取ることができる(ダーティリードが発生しない)
- 読み取ったデータが他のトランザクション開始時点のデータであることが保証されているため、実行元トランザクション内で同じクエリを何度実行しても常に同じ結果が得られる(アンリピータブルリードが発生しない)
- トランザクションが完了するまでの間の他のトランザクションによる行の挿入、削除がブロックされない(ファントムリードが発生する)
SERIALIZABLE
- 最も程度が高い分離レベル
- 他のトランザクションがコミットした変更のみを読み取ることができる(ダーティリードが発生しない)
- 読み取ったデータがトランザクション開始時点のデータであることが保証されているため、トランザクション内で同じクエリを何度実行しても常に同じ結果が得られる(アンリピータブルリードが発生しない)
- トランザクションが完了するまで、他のトランザクションによる行の挿入、削除をブロックする(ファントムリードが発生しない)
ダーティリード
Dirty = 汚れた、不正な
他のトランザクションが処理途中(コミット前)の不正確なデータが読み取られること。
アンリピータブルリード
Unrepeatable = 繰り返せない、再現できない
同じデータを読みとった際に、異なる結果が返されること。
トランザクション中に複数の読み取り処理が存在する場合に、他のトランザクションによる「コミット前」と「コミット後」のデータを1つのトランザクション内で読み取った場合に発生する。
ファントムリード
Phantom = 幻、幽霊
あるトランザクションが特定の範囲のデータを取得して複数回処理を実行しようとするとき、途中で別のトランザクションによってその範囲内に新たなデータが追加されたり既存のデータが削除されたりすることで、同じクエリを実行しているのに、途中で出現または消失する「幻のような」データによって取得結果が影響を受けること。
トランザクションが並行して実行される際に発生する。
耐久性 / Durability
トランザクション完了(コミット)後は、データが永続的に保存されることが保証された状態。仮に障害が発生したとしても、データを復旧させることができる。
物理的なストレージの選定
データベースの予想されるサイズ(容量)、成長率(どのようにデータが増加していくか)を見積もり、ディスクの種類(SSD、HDDなど)、RAIDの構成、ストレージキャッシュの設定などを行う。
基本的にはHDDを使用する。
キャパシティ(容量)のサイジングとパフォーマンスのサイジングという2つの観点から行う。
データの整合性とパフォーマンスにはトレードオフの関係が存在するため、「こちらを立てればあちらが立たず」の状況の中で、最適なものを選定するのは非常に難易度が高いとされる。
性能を考慮する上でTPS(Transaction Per Second)が指標として用いられる。
データ所要量の見積もり
データをディスクに格納する際に必要となる容量は、以下の順に計算を行う。
総行数 ▶️ ページサイズ ▶️ 1行あたりのサイズ ▶️ 1ページあたりの平均行数 ▶️ 必要ページ数 ▶️ データ所要量
総行数
見込まれるデータの総行数。
ページサイズ
データを格納するのに最適なページサイズ。
1行あたりのデータ容量
テーブルのレコード1行分のデータ容量。
1ページあたりの平均行数
ページには、実際には容量100%分のデータが格納されることはなく実際には何も格納されていないデータの空き領域が存在する。ページ対する空き領域の割合を空き領域率と言う。
空き領域率が低い場合、データの更新時にページが足りなくなることで、1つのデータを複数のページに分割して保存する「ページ分割」が発生し、パフォーマンスが低下する。
反対に空き領域率が高い場合、必要以上のページサイズが与えられていることになるため、ディスク容量の無駄遣いにつながる。
1ページあたりの平均行数 を求めるには、まず1ページに対して実際どのくらいのデータが格納されているかを知る必要がある。これは
ページサイズ ❎ (1 - 空き領域率)
で求めることができる。
これを1行あたりのデータ容量で除して 1ページあたりの平均行数 を求める。
ページサイズ ❎ (1 - 空き領域率) / 1行あたりのデータ容量
必要ページ数
で求めることができる。
データ所要量
で求めることができる。
ストレージの冗長構成の決定
データベースに保存されるデータは、基本的に消失が許されない。
ここではRAID(Redundant Array of Independent Disk)という技術を使用し、データを冗長化させたり、パフォーマンスを高める。
選定としては可能な限りRAID10が望ましい。コストが問題になるようであればRAID5も選択肢となる。
RAID0
ストライピング。stripe=縞
データを複数のHDDに分散して保管する。
Input / Output にかかるスループット時間が分散されるため、処理時間が短縮されるが冗長性は向上しない。
RAID1
ミラーリング。
2つのHDDに全く同じデータを重複した状態で保管する。
Input / Output にかかるスループット時間は短縮されないが、データの冗長性が増す。
RAID5
パリティ分散。
最低3つの以上のHDDによって構成され、データ以外にパリティと呼ばれる符号訂正符号を分散して保存する。
パリティはデータが壊れた際に使用される。データが失われた場合でも、パリティによってデータを復元することができる。
RAID10
RAID1+10とも呼ばれる。
RAID1 と RAID0 を組み合わせたもの。最低4つ以上のHDDが必要で、コストが高い。
ファイルの物理配置
- データファイル
- インデックスファイル
- データファイルとは別に保存される
- システムファイル
- 一時ファイル
- ログファイル
パフォーマンスチューニング
データベースのパフォーマンスを向上させるためのチューニングを行います。クエリの最適化、インデックスの調整、キャッシュ設定、クラスタリングなどが含まれます。
正規化
normalization=正規化
normal form(NF)=正規形
データの冗長性を除去することにより、更新時異状を防ぐことを目的として行う。更新時異状は、「異常」ではなく「本来の姿とは声となった状態になる」ことを指す。正規化は、設計において最重要とされる工程になる。
正規化は通常、第3までで十分とされ、それ以上の正規化は特定の状況下でのみ必要となる。第4次以上の正規化は高次正規化と呼ばれる。
正規化は機械的に行えば良いものではなく、要件によっては戸籍のように最新情報だけではなく情報の履歴を残す必要があるものがあり、その場合、あえて正規化を行わないという選択も必要になる。
また正規化による分解をすることによって、結合処理が必要になりパフォーマンスの低下を招くこともある。
正規化は機械的に行うのではなく、時には「しない」という選択も必要
第 1 正規形
意味を持つ最小単位のデータをスカラ値と言い、一つのセルに一つのスカラ値を格納する原則をスカラ値の原則と言う(scalar=単一の)。
ただし、実際にはスカラ値の原則に従っていないデータの方が稀で、違和感を覚える人が多いはず。
分割されたデータは結合することができるため、意味が破壊されない限り、データはなるべく分解したほうが良いとされる。
第 2 正規形
一つのテーブル内の部分関係従属性を排除して、完全関係従属のみにすること。
主キーが複数の属性の組み合わせ(𝐴,𝐵)である場合に、特定の属性(𝐶)が主キーのうちの一つの属性(例えば𝐴)にのみ依存している場合、部分関係従属性が存在する。
この時、テーブルを分解して完全関係従属性のみにする(𝐴 を主キーとするテーブルと 𝐵 を主キーとするテーブルにする)ことで、複数の属性を含む主キーが単独の属性になる。これにより複数のエンティティをまとめて管理する必要が無くなり、構造がよりシンプルになる。
特に複数の重複したレコードの更新処理が1レコードだけで済む。
第二正規形によるテーブルの分解は可逆的な分解であるため結合によって元に戻す事ができる。また分解によってデータが失われないため無損失分解と呼ばれる。
結合は INNER JOIN
または OUTER JOIN
などのSQL文によって行う。コストがかかる処理であるため、正規化とコストはトレードオフの関係にある。
正規化は検索(のための結合)処理のコストとトレードオフの関係にある
正規化を行わないという選択肢もあり、この辺りは人によって考えがまちまちらしい。参考書に載っていた「『非正規化』は最後の手段と考える」というのがわかりやすかった。
関係従属
属性 𝑋 が属性 𝑌 を関数的に決定する、すなわち、𝑋 の値が同じであれば 𝑌 の値も必ず同じになる関係性。
𝑋 → 𝑌
で表現する。 𝑋 を決定項、 𝑌 を従属項(もしくは被決定項)と言う。
完全関係従属性
𝑋 → 𝑌
が完全関係従属性である場合、𝑌 が 𝑋 の部分集合に依存しない関係性を指す。
例えば (𝐴, 𝐵) → 𝐶
が完全関係従属性である場合、𝐶 は (𝐴, 𝐵) の組み合わせに依存しているため、 𝐴 または 𝐵 のどちらか片方だけには依存しない。
部分関係従属性
𝑋 → 𝑌
が部分関係従属性である場合、𝑌 が 𝑋 の部分集合に依存している状態の関係性を指す。
例えば (𝐴, 𝐵) → 𝐶
が部分関係従属性である場合、𝐶 は 𝐴 または 𝐵 のどちらか片方に依存していて、決定項が (𝐴, 𝐵) である必要がない。
自明な関係従属性
当たり前に(常に)存在する関係従属性。
𝐵 が 𝐴 の部分集合であるとき、𝐴 → 𝐵
が常に成立すること。
部分集合 𝐵 が既に 𝐴 に含まれているため、𝐴 が定まれば 𝐵 の値も自動的に定まる、という意味で自明。
第 3 正規形
一つのテーブル内の推移的関係従属性を排除すること。
第3正規形による分解後の元のテーブルには外部キーが残る。
第3正規形も第2正規形と同様に無損失分解であり、結合操作によって元の形に戻す事ができる。
推移的関係従属性
𝑋 → 𝑌
かつ 𝑌 → 𝑍
の場合に、 𝑋 → 𝑍
が成り立つ関係従属性のこと。ただしこの時、𝑌 → 𝑋
は成り立たないことが前提。
第 3.5 正規形
ボイス・コッド正規形(Boyce-Codd Normal Form)とも呼ばれる。
高次正規形の一つであり、第 3 正規形を強化したものという位置付け。
高次正規形に分類される正規形は必ずしも必要とはされないが、複雑な要件が存在する場合には意識するべきとされる。
主キー以外の属性が他の候補キーに従属している状態を排除する。
これは𝑋 → 𝑌
という関係性があるときに、𝑋 が主キーではない状態を排除することを指す。
つまり、ボイスーコッド正規形においては𝑋 → 𝑌
という関係従属があるときは𝑋
が主キーでなければならない。
主キーになりうる属性が主キー以外の列に存在している状態とも表現できる。
ボイスーコッド正規形でない場合、主キーとして扱われていない 𝑋 に対して変更や削除があった際に、複数のレコードに存在しているかもしれない全ての 𝑋 に対しての更新が必要になる(処理負担が増える)。
ただし、 𝑋 が複合キーのうちの一つである場合、不可逆的な分解になってしまうため注意が必要。
ボイス・コッド正規系は不可逆分解になることがある
第 4 正規形
多値従属性を排除すること。
第 4 正規形は可逆的なので、結合によって元の状態に戻す事ができる。
多値従属性
属性 𝑋 に対して、属性 𝑌 と属性 𝑍 がそれぞれ独立して決まる関係性。属性 𝑌 と属性 𝑍 の間には関係性が存在しない。
𝑋 →→ 𝑌 | 𝑍
第 5 正規形
結合従属性を排除すること。
多対多の関係が頻繁に発生する場合に有用。
SQL
Structured Query Language = 構造化問合せ言語
SQLには一部のベンダで独自の文法が用意されている。これと対比させて、標準規格に準拠したものを標準SQLと言う。
DDL
Data Definition Language
データベースを定義するためのSQL。
テーブル、ビュー、インデックス作成に利用される。
CREATE DATABASE
データベースを作成する。
CREATE DATABASE database_name;
DROP
データベースを削除する。
DROP DATABASE database_name;
CREATE TABLE
テーブルを作成する。
CREATE TABLE table_name (
column_1 data_type [constraint],
column_2 data_type [constraint],
column_3 data_type [constraint],
....
);
constraint
(制約)にはPRIMARY KEY
、NOT NULL
などが指定できる。
ALTER
テーブルに変更を加える。
カラムを追加する場合は ADD
と合わせて使用する。
ALTER TABLE table_name
ADD column_name datatype;
カラムを削除する場合は、DROP
を合わせて使用する。
ALTER TABLE table_name
DROP COLUMN column_name;
カラム名を変更する場合
ALTER TABLE table_name
RENAME COLUMN old_name to new_name;
CREATE VIEW
ビューを作成する。
CREATE VIEW view_name (column_1, column_2, ...) AS
SELECT column_1, column_2, ...
FROM table_name
WHERE condition;
作成したビューは仮想テーブルであるため、次のようにして参照することができる。
SELECT * FROM view_name;
CREATE TABLE
では AS SELECT
を使用する
CREATE INDEX
インデックスを作成する。
CREATE INDEX index_name
ON table_name (column_1, column_2, ...);
CREATE ROLE
ロールを作成する。
CREATE ROLE role_name;
CREATE TRRIGER
トリガーを作成する。
CREATE TRIGGER trigger_name
AFTER target_operation
ON table_name
FOR EACH ROW
BEGIN
action
END;
AFTER
ではなく BEFORE
も使用可。
target_operation
(トリガーの対象とする操作)にはINSERT
、UPDATE
、DELETE
などが指定できる。
FOR EACH ROW
は全ての行に対して処理が実行されるようにするためのもの。
DELARE CURSOR
カーソルを宣言する。
データベースやテーブルとは異なり、カーソルは永続的なものではないため、CREATE
ではなく DECLARE
を使用する。
DECLARE cursor_name FOR
SELECT column_1, column_2, ...
FROM table_name;
DELARE CURSOR
では FOR SELECT
を使用する
DCL
Data Control Language
データベースのデータに対するアクセス制御を行うためのSQL。
他にもトランザクションの開始、終了、アクセス権の制御などを行うために利用される。
GRANT
GRANT privilege
ON table_name
TO user_name;
privilege
(権限)には、ALL PRIVILEGES
、SELECT
、INSERT
、DELETE
などが指定できる。
user_name
には、ユーザ名の他にロールも指定できる。
START TRANSACTION
トランザクションの開始を示す構文。
START TRANSACTION;
トランザクションの設定において、他のトランザクションとどのように隔離されるかの定義を分離レベルと言う。
START TRANSACTION isolation_level;
isonlation_level
(分離レベル)には以下の4つのいずれかを指定することができる。
READ UNCOMMITED
READ COMMITED
REPEATABLE READ
SERIALIZABLE
COMMIT
トランザクション内のすべての操作が成功した場合、データベースへの変更内容を確定させるための構文。
COMMIT;
ROLLBACK
トランザクション内でエラーが発生した場合、トランザクション内で行なった変更内容をキャンセルするための構文。
ROLLBACK;
DML
Data Manipulation Language
Manipulation = 操作
データベースのデータを操作するためのSQL。レコードの追加、更新、削除を行うために利用される。
SELECT
SELECT column_1, column_2, ...
FROM table_name;
DUSTINCT
を使用することで重複を排除することができる。
SELECT DINSTINCT column_1, column_2, ...
FROM table_name;
また、column_1
の部分には集約関数も使用できる。
INSERT
INSERT INTO table_name (column_1, column_2, column_3, ...)
VALUES (value_1, value_2, value_3, ...);
UPDATE
UPDATE table_name
SET column_1 = value_1, column_2 = value_2, ...
WHERE condition;
DELETE
DELETE FROM table_name
WHERE condition;
関係演算
Relational Algebra
algebra=代数
関係(リレーション、テーブル)に対しする操作やクエリのこと。関係演算を使用することで、リレーションから必要な情報だけを抽出したり、組み合わせて新たな関係を導くことができる。
和 / UNION
Union
2つのリレーションの全ての行を結合する操作。OR演算とも呼ばれる。
𝑅 ∪ 𝑆
で表現され、リレーション 𝑅 と 𝑆 の全ての行を結合することを意味する。
SELECT column_name FROM table_1
UNION [ALL]
SELECT column_name FROM table_2;
ALL
をつけることで重複した行も複数抽出される。
結合と似ているが、結合ではカラムが増えるのに対して、UNION
は和演算なので table_2
のレコード分が table_1
の下に追加される。
差 / EXCEPT
Difference
リレーションから別のリレーションとの共通行を除外する操作。
R − S
で表現される。
SELECT column_name FROM table_1
EXCEPT [ALL]
SELECT column_name FROM table_2;
table_1
に存在するが、table_2
には存在しない行を返す。
ALL
をつけることで重複した行もそのまま複数抽出される。(Oracle DB では EXCEPT
の代わりに MINUS
を使用する。)
table_1
と table_2
の順番を変えると結果が変わることに注意。
差は「順番」によって結果が変わる
積 / INTERSECT
Intersection
2つのリレーションの共通する行を抽出する操作。交差、AND
演算とも言う。
R ∩ S
で表現する。
SELECT column_name FROM table_1
INTERSECT [ALL]
SELECT column_name FROM table_2;
ALL
をつけることで重複した行もそのまま複数抽出される。
直積 / CROSS JOIN
Direct Product、Cartesian Product
2つのリレーションの全ての行を掛け合わせる操作。
𝑅 × 𝑆
で表現する。
SELECT *
FROM table_1
CROSS JOIN table_2;
射影
Projection
リレーションから特定の列(属性)を抽出する操作。
選択
Selection
リレーションから特定の行(タプル)を抽出する操作。
商
Division
特定の属性の値の組み合わせが全て揃っている行を抽出する操作。R ÷ S
で表現する。S を全て含む R の列を抽出する。
結合 / JOIN
Join
2つのリレーションを結合し、新しいリレーションを生成する操作。
ON
と合わせて利用する。結合を行う双方のカラム名が同じ場合、USING
で使うことでテーブル名を省略できる。
FROM A JOIN B USING common_column
外部結合でないもの(JOIN
)は、内部結合 INNER JOIN
(デフォルト)になる。
JOIN
は INNER JOIN
のこと
θ結合
θ(シータ)
2つのリレーション間を任意の条件(θ)に基づいて結合する操作。
比較演算子(θ) | |
---|---|
= |
等しい |
<> |
等しくない |
< |
小なり |
> |
大なり |
<= |
以下 |
>= |
以上 |
SELECT column_name
FROM table_1
JOIN table_2 ON table_1.column_name > table_2.column_name;
等結合
θが =
であるθ結合を特に等結合と言う。
SELECT column_name
FROM table_1
JOIN table_2 ON table_1.column_name = table_2.column_name;
自然結合 / NATURAL JOIN
SELECT column_name
FROM table_1
JOIN table_2 ON table_1.column_name = table_2.column_name;
と言う等結合を実行した時に、重複して表示されるカラム table_1.column_name
と table_2.column_name
の一方を排除したもの。
SELECT column_name
FROM table_1
NATURAL JOIN table_2;
USING
を使った場合と同じ結果を得ることができる。
外部結合 / OUTER JOIN
2つのリレーション間に、一致するものがない場合でも抽出操作を行う結合のこと。
左外部結合 / LEFT OUTER JOIN
リレーション R と S のうち、左側の R の行は全て抽出する結合操作。R に対応する S の行がない場合、NULL
が挿入される。
SELECT column_name
FROM table_left
LEFT OUTER JOIN table_right
ON table_left.column_name = table_right.column_name;
右外部結合 / RIGHT OUTER JOIN
リレーション R と S のうち、右側の S の行は全て抽出する結合操作。S に対応する R の行がない場合、NULL
が挿入される。
SELECT column_name
FROM table_left
RIGHT OUTER JOIN table_right
ON table_left.column_name = table_right.column_name;
外部完全結合 / FULL OUTER JOIN
リレーション R と S のうち、どちらかに存在する行は全て抽出する操作。対応する列が存在しない場合、NULL
が挿入される。
SELECT column_name
FROM table_left
FULL OUTER JOIN table_right
ON table_left.column_name = table_right.column_name;
内部結合 / INNER JOIN
2つのリレーション間で、一致するもののみを抽出する操作のこと。
SELECT column_name
FROM table_1
INNER JOIN table_2
ON table_1.column_name = table_2.column_name;
その他のSQL
集約関数
集計関数とも呼ばれる。
集約関数 | 説明 |
---|---|
SUM() |
合計 |
MAX() |
最大値 |
MIN() |
最小値 |
AVG |
平均値 |
COUNT() |
レコード数 |
COUNT(*) |
全レコード数 |
GROUP BY
特定の列に基づいてグループ化を行うための構文。
SELECT column_name, 集約関数
FROM table_name
WHERE condition
GROUP BY column_name;
複数のカラムの組み合わせをグループ化のキーとすることもできる。
GROUP BY column_name_1, column_name_2, column_name_3
とすると、(column_namne_1, column_namne_2, column_namne_3)
の組み合わせによる単位で一致するレコードがグループ化される。
グループ化を行なった場合、「グループ化を行なったカラム」もしくは「集約関数」しか表示させることはできない。
例えば、以下は表示できる。
SELECT 商品番号, SUM(売上額)
FROM 売上
GROUP BY 商品番号;
一方で商品番号でグループ化した時、同じ商品番号の売上額は複数存在することもあり、その場合どの値を表示すべきかがわからないため、以下はエラーが発生する。
SELECT 商品番号, 売上額
FROM 売上
GROUP BY 商品番号;
エラーを発生させないためには、グループ化の条件を以下のようにする必要がある(この例では、商品番号と売上額をグループ化して表示する目的は特に考えないこととする)。
SELECT 商品番号, 売上額
FROM 売上
GROUP BY 商品番号, 売上額;
GROUP BY
でグループ化を行なった場合、「グループ化を行なったカラム」もしくは「集約関数」しか表示させることはできない
HAVING
GROUP BY
の結果に検索条件をつける。
SELECT column_name
FROM table_name
GROUP BY column_name
HAVING condition;
CASE
SQLで条件分岐を行うための構文。
特定の条件に応じて異なる値を返したり、処理を分岐させることができる。
シンプルな構文と、高度な構文の2種類がある。
CASE column_1
WHEN value_1 THEN result_1
WHEN value_2 THEN result_2
WHEN value_N THEN result_N
ELSE result
END;
CASE
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
WHEN condition_N THEN result_N
ELSE result
END;
COALESCE
coalesce = 合体する、融合する
欠損値をデフォルト値に置き換えるための構文。データ分析を行う際に、 NULL
なら 0
として扱いたい場合などに利用する。
COALESCE(expression, default_value)
例えば、電話番号がNULL
の時にメールアドレスを返すようにする。
SELECT column_1,
COALESCE(phone, mail_address) AS contact
FROM table_1;
CONCAT
文字列を連結するための構文。
CONCAT(column_1, column_2)
ウィンドウ関数
SQLでデータの集計や分析を、より柔軟に行うために利用される高度な関数。
複雑な処理を行いたい場合に利用することで、副問合せを複数組み合わせるなどの複雑な記述不要になる。
OVER
句が使用される。
ウィンドウ関数 | 説明 |
---|---|
ROW_NUMBER() |
各行に対して、一意の行番号を付与する |
RANK() |
並べ替え順序に基づくランクを付与する |
DENSE_RANK() |
同順位がある場合、ランクを飛ばさずに連続して付与する |
LAG(column_name, n) |
n行だけ前にある行の値を参照 |
LEAD(column_name, n) |
n行だけ後ろにある行の値を参照 |
SUM() |
合計 |
AVG() |
平均 |
MAX() |
最大値 |
MIN() |
最小値 |
COUNT() |
行数 |
SUM()
、AVG()
、MAX()
、MIN()
、COUNT()
は、集約関数がウィンドウ関数として発展したもの。
ウィンドウ関数() OVER (
[PARTITION BY grouping_column]
[ORDER BY ordering_column]
[frame_range]
)
PARTITION BY
では、データをグループに分割するための列を指定する(GROUP BY
と同様)。
ORDER BY
では、並べ替えを行う列を指定する。
frame_range
には、 ROWS
または RANGE
を使ってウィンドウ関数が計算を行う範囲を指定する。
frame_range |
説明 |
---|---|
CURRENT ROW |
現在の行 |
n PRECEDING |
ROW : 現在行からn 行前RANGE : n 値前 |
n FOLLOWING |
ROW : 現在行からn 行後RANGE : n 値後 |
UNBOUNDED PRECEDING |
ウインドウの先頭行 |
UNBOUNDED FOLLOWING |
ウィンドウの末尾行 |
以下は「2行前から現在の行まで」を表す。
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
副問合せ
SELECT
文の中で、入れ子にしたSELECT
文。
外側のSELECT
文の方を主問合せという。
相関副問合せ
副問合せには主問合せと相関するものと相関しないものがあり、相関するものを特に相関副問合せという。
相関しない副問合せは「副問合せ▶️主問合せ」の順に単純に実行されるのに対して、相関副問合せは「主問合せから1行づつ値をもらいながら副問合せが複数回繰り返されながら実行」というように実行の形態が大きく異なる。そのため相関副問合わせは、相関しない副問合せと比べて実行負荷が非常に高い。
「相関副問合せ」は「副問合せ」の一つだが、実行形態が大きく異なる
EXISTS
相関副問い合わせとして利用される代表的なSQL文に EXISTS
がある。
SELECT column_name
FROM table_name_1
WHERE EXISTS
(SELECT column_name FROM table_name_2 WHERE condition);
副問合せ中の condition
に tabe_name_1
のカラムを使用した場合、主問合せと副問合せが相関することになる。
WITH
副問合せにおいて、一時的な仮想テーブルを作成することで複雑なクエリを読みやすくするための構文。
WITH virtual_table_name (column_name)
AS (
SELECT column_name
FROM real_table_name
WHERE condition;
);
SQLが実行される仕組み
Parser
文法チェックが実行される。
Optimizer
SQLのアクセスパスが決定される。最適化。
Catalog Manager
統計情報の照会を受け付ける。データへのアクセスプランを決定して回答する。
障害管理
リストアとリカバリ
バックアップしておいたファイルをDBに戻す作業をリストアと呼び、バックアップ実施後に作成されたトランザクションログを適用してバックアップ時から障害発生時までの状態に戻す作業をリカバリと呼ぶ。
バックアップ
フルバックアップ
- 全てのデータを対象とするため、バックアップを取得するための時間(バックアップウィンドウ)が長い
- データの整合性を保ちながらバックアップを取得するには、バックアップ中はサービスを停止させる必要がある
- バックアップデータのサイズが膨大
差分バックアップ
- フルバックアップと組み合わせて使用
- フルバックアップを定期的に行い、次回のフルバックアップまでは差分バックアップを取得する
- 実際にはDBへの操作を記録したログをバックアップする(復元時には過去の操作をもう一度行えば良い)
- バックアップデータ量が少なくて済む
増分バックアップ
- 差分バックアップをさらに効率的にしたもの
- 差分バックアップはフルバックアップとの差分を対象としているのに対して、増分バックアップは前回の差分バックアップとの差分を対象とするため、さらに少ないデータ量で済む
- 効率的な保存方法なのに対して、復元作業が複雑化するというデメリットがある
フォールトトレラント
Fault = 問題、誤り、障害
Tolerant = 受け入れる、耐える、我慢する
障害が起こっても機能維持する能力を持たせる設計手法。部分的に障害が発生してもシステム全体としては停止することなく稼働し続ける。
冗長化、バックアップなどにより実現される。
フォールトアボイダンス
Fault = 問題、誤り、障害
Avoidance = 避ける、回避する
障害が発生する可能性を可能な限り取り除くことで、障害自体が発生しないようにする設計手法。
障害を予防するためのメンテナンスや設計の最適化により実現する。
フェールセーフ
Fail = 失敗する、故障する
Safe = 安全
障害が発生しても、危機的状況には陥らず、安全な状態を維持するように設計すること。障害が新たな問題を発生させないようにする。
電源が切れたら自動的にシャットダウンする、障害児は赤信号を点灯させる、など。
フェールソフト
Fail = 失敗する、故障する
Soft = 軽度の、柔らかな、穏やかな
フォールトトレラントと似ているが、部分的な障害が発生した場合に、システム全体としては稼働停止せず、部分的な機能の稼働だけは維持し続けるようにする設計手法。
フールプルーフ
Fool = おろなもの、間違いを犯しやすい人
Proof = 耐える、防ぐ
ユーザが意図的ではなくても、誤った操作をした際に障害を発生させない、もしくは誤操作自体を行わせないようにする設計手法。
フォールトマスキング
Fault = 問題、誤り、障害
Masking = 隠す、覆い隠す
システム内部で障害を検出した際に、ユーザや他のシステムからは見えなくする、外部に影響を与えないようにする設計手法。
システムの冗長化によって実現する。例えば、計算機能を3つのコンポーネントに行わせ、1つが誤った結果を出してもその他の2つのコンポーネントによってシステム全体としては正しい結果が出る、など。
用語
テーブル
テーブルとはある共通点を持つレコードの集合であるため、必ず複数名詞で表現することができる(Items、Ordersなど)。
複数名詞で表現できないテーブルは、どこかに間違えが潜んでいる可能性が高いと考えた方が良い。
ビュー
テーブルのデータを表示する仮想的なテーブルをビューと言う。
ビューは実際のデータを持たず、元となるテーブルからデータを取得して表示したものを指す。基のテーブルを基底テーブルと言う。
基底テーブルのようにデータは保持せず、参照のたびにクエリを実行して常に動的にデータを取得する。そのため、ビューでは常に最新のデータが取得できる。
他にも、ユーザに対して複雑なクエリやテーブルの構造を隠蔽するためにも利用される。基底テーブルは、あくまでもユーザに対して隠蔽されるのであり、エンジニアは基底テーブルの存在を無視することはできない。多段的なビューがある場合などは、段の数だけ内部でSELECT
文が階層的に実行されていて、濫用するとパフォーマンスに悪影響を及ぼす。
また、基底テーブルに公開したくないカラムが含まれる場合、そのカラムを除いたビューを用意して、ビューのみを公開するなどと言う利用方法もある。
カーソル
クエリの結果として返される複数の行を一行ずつ処理するための仕組み。
特にプログラムやスクリプト内で複数行のデータを逐次処理する際に使用される。
基本的には以下の流れで操作を行う。
順番 | コマンド | 説明 |
---|---|---|
1 | DECLARE |
宣言 SQL文で取得するデータを指定してカーソルを宣言 DECLARE cursor_name CURAOR FOR SELECT...
|
2 | OPEN |
オープン カーソルを開いて、SQLクエリを実行 OPEN cursor_name
|
3 | FETCH INTO |
フェッチ カーソルから一行ずつデータを取得 取得したデータは変数( @variable_name )に格納されるFETCH cursor_name INTO : @variable_name
|
4 | CLOSE |
クローズ 処理が終わったら、カーソルを閉じてリソースを解放br> CLOSE cursor_name
|
ロール
ユーザーやグループに特定の権限やアクセス許可を付与するための概念をロールと言う。
ロールを使用することにより、個々のユーザに対して直接権限を設定するのではなく、権限の設定を行なったロールを各ユーザに割り当てることが可能になる。
トリガー
特定のデータベース操作(INSERT
、UPDATE
、DELETE
など)をきっかけにして、自動的に発生させるアクションや処理をトリガーと言う。
キー
関係においてレコード(行)を一意に識別するための属性、もしくは属性の集合をキーという。
キーを文字列型にする際の注意点
キーとなる属性を文字列型にする場合、可変長文字列にしてしまうと、同じ属性値を指して入力された値がひらがな・カタカナ・漢字表記の違いやスペースの有り無しによって微妙に変わってしまい、異なるキーとして登録されるという事態が発生する。
そのためキーに文字列型を使用する場合は、何らかのコードやIDなどの固定長文字列を使用するようにする。
また、基本的にキーは不変の値(コード)が望ましい。
変更の可能性がある情報をキーとして使用しない。
スーパーキー
レコード(行)を一意に識別する事ができる属性(列)や属性の集合。
レコードを一意に識別さえできれば良いため、識別するために不要な属性を含んでも良い。
候補キー
- レコード(行)を一意に識別する事ができる属性や属性の集合
- 1のうち、極小のもの
上記2つの条件を満たす属性(列)や属性の集合のこと。
条件を満たしていれば、レコードごとに異なる候補キーであっても良い。
主キーの候補となるキーのこと。
主キー
プライマリキー、ユニークキー(製品によって呼び名が微妙に違う)。
一意性制約とNOT NULL 制約を併せ持つ(主キー制約)。
レコードを識別するために余計な属性は含まないが、だからと言って一つの属性である必要はない(複数の属性の組み合わせが主キーであることもある。この場合、複合キーと呼ぶ)
複合キー
代理キー
候補キーのうち、主キーに選ばれなかった属性。
外部キー
他のテーブルの主キーを参照するために使用される属性あるいは属性の集合。
サロゲートキー
代理キー(surrogate=代理、身代わり)。
通し番号のような、人工的に作られた情報をキーにしたもの。
要件上、自然キーが存在せずやむを得ず使用される。
自然キー
ナチュラルキー。
人工的に作られたサロゲートキーに対して、自然に存在する情報をキーにしたもの。
シーケンスオブジェクト
単にシーケンスやシーケンスジェネレータとも呼ばれる。
一意な連続した数値を生成するためのオブジェクトで、多くのDB製品でCREATE SEQUENCE
などのSQLによって作成される。
初期値、増分(ステップ)、最大値、最小値、サイクル(再利用)などを設定してカスタマイズする事ができる。
また、テーブルとは独立して存在しているため、複数のテーブル間で共有する事ができる。
似たものに、オートナンバリング機能がある。
ただし、オートナンバリング機能は、
SQL Server : IDENTITY
型
PostgreSQL : SERIAL
型
MySQL : AUTO_INCREMENT
型
というようにDB製品間で互換性がないため、シーケンスオブジェクトの方が柔軟性がある。
CRUD分析
システムがどのようにデータを操作するかを整理し、設計の品質を高めるための手法。
-
Create : 作成 :
INSERT
-
Read : 参照 :
SELECT
-
Update : 更新 :
UPDATE
-
Delete : 削除 :
DELETE
機能 A | 機能 B | 機能 C | |
---|---|---|---|
テーブル A | RU | R | |
テーブル B | CRU | ||
テーブル C | C | C | CRD |
システムが機能ごとに各テーブルに対してどのような操作を行うかが明確になり、データ操作のパターンが整理されることで、設計の一貫性を保つことができる。
例えば、「作成」されていないデータを「参照」「更新」「削除」しようとしていないかをチェックしたり、また特定のテーブルに対する処置の偏り(アクセス数)がないかを把握することができる。
デシジョンテーブル
Decision Table
決定表
特に複雑なビジネスルールや条件付きのロジックを整理するためのツール。複数の「条件」とそれに対応する「アクション」を表形式でまとめることで、条件に基づいた決定が理解しやすくなる。
- 条件
- 「Y」(Yes)、「N」(No)等で表現される
- 処理
- 「X」(処理が必要)、「-」(処理が不要)等で表現される
区分 A | 1 | 1 | 2 | 2 |
---|---|---|---|---|
区分 B | 1 | 2 | 1 | 2 |
テーブル A | X | - | - | - |
テーブル B | - | - | - | X |