データベース1問1答

データベースの分野に関する基礎的な問題を1問1答形式で書いていくので、自分の力試しなどに利用して下さい。（もし間違っている知識などがあれば**優しく**教えて下さい！！）
言い切りの形だったり、です、ます調になっていたりと殴り書きの文章なのでご承知ください、、、
それでは30問始めます！

# 問題 (折りたたみを開いたら回答があります)
<details><summary>1データベースの基本的な役割とは何でしょうか？
</summary>

- 大量のデータを効率的に保存すること。テーブル、行、列、など構造化された形式で保存される。
- 追加、更新、削除などの操作を効率的に行うために利用される

</details>

<details><summary>2.データベース管理システム（DBMS）にはどのような種類があるでしょうか？
</summary>

- リレーショナルデータベース管理システム（RDBMS）:
  - データをテーブル形式で管理し、SQLを使用して操作する
  - 例: MySQL, PostgreSQL, Oracle Database, Microsoft SQL Server

- NoSQLデータベース:
  - リレーショナルモデル以外のデータモデルを使用し、柔軟なスキーマ（データベースの構造）を持つデータベース
  - 例: MongoDB, Cassandra, Redis

- オブジェクト指向データベース管理システム（OODBMS）:
  - オブジェクト指向プログラミングの概念を取り入れたデータベース
  - 例: db4o, ObjectDB
</details>

<details><summary>3.データベースの主な構成要素にはどのようなものがありますか？
</summary>

RDBMS: 
- テーブル：
  - データを行（カラム）と列（レコード）の形式で格納する基本的な単位
- 行(Row)/レコード(Record)：
  - テーブル内の一つのエントリーされたデータを表す
- 列(Column)/フィールド(Field)
  - テーブル内のデータ属性を表す。各列はそれぞれ特定の属性を持ち、テーブル内の全ての行に対して同じ属性を持つ
- 主キー
  - テーブル内の各行を一意に識別するための列または列の組み合わせ。主キーは一意であり、NULLなどは許されない
- 外部キー
  - 他のテーブルの主キーを参照するための列。外部キーにより、色々なテーブル間でのリレーションシップを定義し、データの整合性を保つ
など

NoSQL
- キー・バリュー型
- ドキュメント型
- カラムファミリー型
- グラフ型

OODBMS
- オブジェクト
- クラス
- 継承

</details>

<details><summary>4.RDBMSとNoSQLデータベースはどのような違いがありますか？
</summary>

RDBMS
ACID特性(atomicity consistency isolation durability)し、固定スキーマ（事前にデータの形式が決められている）を持ち、テーブルに対してSQL(Structured Query Language)を用いてアクセスする。
- メリット：ACID特性により、データの整合性や一貫性が保証される。SQLを理解することで、MySQLやPostgreSQLなどの異なるRDBMSでも比較的容易に操作することができる
- デメリット：水平スケーリング（データベースを複数のサーバーに分散すること）などが難しい場合がある。固定スキーマのため、データモデルの変更が難しいことがある。それにより、パフォーマンスが下がったり、使用しないカラムが存在したりしてしまう

NoSQL (Not Only SQL)
リレーショナルモデル以外のデータモデルを使用するデータベース。主な種類にはキー・バリュー型、ドキュメント型、カラムファミリー型、グラフ型がある。スキーマレス、または柔軟なスキーマをもち、データ構造を動的に変更可能。
- メリット：水平スケーリングが容易で、大規模なデータセットや高トラフィックのアプリケーションに適している。特定のユースケースに適しており、高速なデータアクセスが可能
- デメリット：ACID特性を完全にサポートしない場合があり、データの整合性が保証されないことがある。SQLのような標準化されたクエリ言語が存在せず、データベースごとに異なるクエリ言語やAPIを使用する必要がある
</details>

<details><summary>5.主キーとは何でしょうか？また、主キーの役割は何ですか？
</summary>

主キーとは、データベーステーブル内の各行（レコード）を一意に識別するための列（または列の組み合わせ）。主キーはテーブル内で一意であり、NULL値を持つことはできない。

役割
- 主キーはテーブル内の各レコードを一意に識別するため、同じ値を持つレコードないことを保証する。これにより、データの重複を防ぐ
- 主キーは他のテーブルとのリレーションシップを確立するために使用される。外部キーというもので、他のテーブルの主キーを参照してテーブル間での関係性を定義する


</details>

<details><summary>6.外部キーとは何ですか？その用途について説明してください。
</summary>

外部キーとは、あるテーブルの列（または列の組み合わせ）が、別のテーブルの主キー（または一意キー）を参照するために使用されるキー。外部キーは、テーブル間のリレーションシップを確立し、データの整合性を保つために使用される。

用途
- 外部キーは、2つのテーブル間の関係を定義する。例えば、`orders`テーブルの`customer_id`列が`customers`テーブルの`customer_id`列を参照することで、各注文がどの顧客に関連しているかを示す。
- 外部キー制約により、参照されるデータが存在しない場合などにデータの挿入や更新を防ぎ、整合性を担保する
- 外部キー制約により、親テーブルのデータが削除された時に、子テーブルのデータを自動的に削除または更新するので、整合性が保たれる

</details>

<details><summary>7.リレーショナルデータベースで「正規化」とは何を指すでしょうか？
</summary>

正規化とは、データベースの設計の際にデータの冗長性を減らし、データの整合性を保つためにデータを構造化するプロセスである。

正規化の目的
- 重複するデータなどを削除し、冗長性をなくすことで、ストレージを効率的に使用できるようにする
- データの一貫性を保ち、整合性を確保する
- データの追加や更新、削除などのプロセスを高速に行えるようにする
</details>

<details><summary>8.第1正規形、第2正規形、第3正規形の違いを説明してください。
</summary>

第一正規系（1NF: First Normal Form)
- 各セルが単一の値を持つ
- 各列が同じデータ型を持つ
- 各行が一意である

```txt
注文ID | 顧客名 | 商品名 | 商品価格
-----------------------------------
1     | 田中    | ペン   | 100
1     | 田中    | ノート | 200
2     | 鈴木    | ペン   | 100
```
この例では、各セルに単一の値が含まれており、1NFを満たしている

第二正規系（2NF: Second Normal Form)
- 第一正規系を満たしている
- 主キーの一部に依存している部分的な依存関係がないこと。つまり、主キーの一部だけに依存する列が存在しないこと（部分関数従属の削除）

```txt
注文ID | 顧客名
----------------
1     | 田中
2     | 鈴木

注文ID | 商品名 | 商品価格
-------------------------
1     | ペン   | 100
1     | ノート | 200
2     | ペン   | 100
```
この例では、もともと`注文ID`に対して`顧客名`が依存していたので、それを別テーブルに分割することで、部分的な依存関係を断ち、データの整合性を保つ

第三正規系（3NF: Third Normal Form)
- 第二正規系を満たしていること
- 主キー以外の列に依存する推移的な依存関係がないこと。つまり、主キー以外の列が他の非キー列に依存しないこと（推移的関数従属の削除）

```txt
注文ID | 顧客ID
----------------
1     | 1
2     | 2

顧客ID | 顧客名
--------------
1     | 田中
2     | 鈴木

注文ID | 商品ID
----------------
1     | 1
1     | 2
2     | 1

商品ID | 商品名 | 商品価格
-------------------------
1     | ペン   | 100
2     | ノート | 200
```
この例では、 `顧客名`が`顧客ID`に依存しているため、別のテーブルに分割されている。また、`商品価格`が`商品名`に依存しているため、別のテーブルに分割されている。
</details>

<details><summary>9.「JOIN」句にはどのような種類がありますか？それぞれの用途について説明してください。</summary>

以下のテーブルを結合することを考える

```txt
user_id | name             |       user_id | product       
--------|---------         |     ----------|------------
   1    | Alice            |          1    |   Laptop
   2    | Bob              |          2    | SmartPhone
   3    | Charlie          |          1    |   Tablet
                           |          4    |   Monitor   
```

INNER JOIN (内部結合)
- 2つのテーブル間でデータが一致する行のみを結合する。結合条件に一致する行が両方のテーブルに存在する場合のみ結果に含まれる
```txt:INNER JOIN
name    | product
--------|---------
Alice   | Laptop
Alice   | Tablet
Bob     | Smartphone
```

LEFT OUTER JOIN (左外部結合)
- LEFT JOINは、左側のテーブルの全ての行と、結合条件に一致する右側のテーブルの行を結合する。右側のテーブルに一致する行がない場合、NULLが返される
```txt:LEFT OUTER JOIN
name    | product
--------|---------
Alice   | Laptop
Alice   | Tablet
Bob     | Smartphone
Charlie | NULL
```

RIGHT OUTER JOIN (右外部結合)
- RIGHT JOINは、右側のテーブルの全ての行と、結合条件に一致する左側のテーブルの行を結合する。左側のテーブルに一致する行がない場合、NULLが返される
```txt:RIGHT OUTER JOIN
name    | product
--------|---------
Alice   | Laptop
Alice   | Tablet
Bob     | Smartphone
NULL    | Monitor
```

FULL OUTER JOIN (完全外部結合)
- FULL JOINは、両方のテーブルの全ての行を結合し、結合条件に一致する行を結合する。一致しない行については、NULLが返される
```txt: FULL JOIN
name    | product
--------|---------
Alice   | Laptop
Alice   | Tablet
Bob     | Smartphone
Charlie | NULL
NULL    | Monitor
```

CROSS JOIN (交差結合)
- 全ての組み合わせを生成する場合に使用する。特定の条件に基づく結合ではなく、全ての行の組み合わせが必要な場合に使用する
```txt: CROSS JOIN
name    | product
--------|---------
Alice   | Laptop
Alice   | Smartphone
Alice   | Tablet
Alice   | Monitor
Bob     | Laptop
Bob     | Smartphone
Bob     | Tablet
Bob     | Monitor
Charlie | Laptop
Charlie | Smartphone
Charlie | Tablet
Charlie | Monitor
```

</details>

<details><summary>10.テーブル結合を行う際に気をつけるべきポイントは何でしょうか？
</summary>

- 結合条件の適切な設定
- 結合種類の選択
- パフォーマンスの考慮
  - 結合に使用する列に対してインデックスを設定することでパフォーマンス向上を目指す
  - 大規模なテーブル同士の結合はパフォーマンスの低下につながるので、必要に応じてデータをフィルタリングしてから結合する
- 外部キー制約を使用して、参照整合性を保つことでデータの一貫性を確保する
- NULL値が結果に入ることがあるのでそれらを考慮する
など
</details>

<details><summary>11.インデックスとは何でしょうか？また、その利点と欠点について説明してください。
</summary>

インデックスとは、DB内のテーブルに対して作られるデータ構造で、データの検索や取得を高速化するために使用される。インデックスは特定の列や列の組み合わせなどに基づいて作成され、データの物理的な順序とは独立して管理される

利点
- 特定の条件に一致するデータを迅速に取得することができる。例えば、`Alice`, `Bob`, `Charlie`などの人のデータが入っているものに対して、インデックスなしでCharlieを探す時は一つずつ順に探して一致するかを確認しなければならないが、インデックスをつけておくと、 `Charlie = 3 `とすぐにわかり、二分探索などやハッシュ検索などで高速に検索することができる
- 名前や歳などにインデックスをつけておくと、データのソートが効率的に行われる

欠点
- インデックスを作成すると、追加のディスクスペースが必要になる。特に大規模なテーブルに対して複数のインデックスを作成すると、ディスクスペースの消費が増加してしまう
- インデックスが存在するテーブルに対してデータの挿入、更新、削除操作を行うと、インデックスの更新が必要になるので、一部操作のパフォーマンスが下がることがある

</details>

<details><summary>12.SQLにおける「GROUP BY」句と「HAVING」句の使い方はどのようなものでしょうか？
</summary>

 `GROUP BY`句は指定した列の値に基づいてデータをグループ化し、集計関数(`COUNT`,`SUM`...)を使用して、グループごとの集計結果を取得するために使用される。

 `HAVING`句は`GROUP BY`句でグループ化されたデータに対して条件を指定するために使用される。`WHERE`句がグループ化される前のデータに対して条件を指定するのに対し、`HAVING`句はグループ化されたデータに対して集計関数を適用するために使用される。
 
</details>

<details><summary>13.トランザクションとは何ですか？また、その重要性について説明してください。
</summary>

データベースにおける一連の動作（INSERT, DELETE, UPDATE...)を一つの単位として扱う概念。トランザクションは、すべての操作が成功するか、またはすべての操作が失敗して元の状態に戻るかのいずれかを保証する。

これは、データベースにおいて整合性や一貫性を保つために重要であり、ACID特性を持つ。

トランザクションの基本動作
- BEGIN TRANSACTION
  - トランザクションの開始を宣言
- COMMIT
  - トランザクション内の全ての変更を確定し、データベースに反映する
  - つまり、コミットされるまではそれぞれの変更はデータベースには反映されていない
- ROOLBACK
  - トランザクション内の全ての変更を取り消し、データベースをトランザクション前の状態に戻す

```sql:COMMIT
-- トランザクションの開始
BEGIN TRANSACTION;

-- アカウント1から100を引く
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

-- アカウント2に100を加える
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

-- トランザクションの確定
COMMIT;
```

```sql:ROLLBACK
-- トランザクションの開始
BEGIN TRANSACTION;

-- アカウント1から100を引く
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;

-- アカウント2に100を加える（エラーが発生する場合）
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

-- エラーが発生した場合、トランザクションをロールバック
ROLLBACK;
```
</details>

<details><summary>14.トランザクションの4つの特性（ACID特性）について説明してください。
</summary>

ACID特性とはデータベーストランザクションの信頼性を保証するための重要な特性である。

- Atomicity (原始性)
  - トランザクション内の全ての操作が完全に行われるか、全く実行されないかのどちらかであることを保証する。部分的な実行は許されない、という特性
- Consistency (一貫性)
  - トランザクションの開始前と終了後で、データベースが一貫した状態であることを保証する。トランザクションが成功した場合は、データベースの整合性制約が満たされた状態である、ということを保証する特性
- Isolation (独立性)
  - 複数のトランザクションが同時に実行される場合でも、各トランザクションが他のトランザクションから独立して実行されることを保証します。これにより、トランザクション間の干渉が防止されることを保証するという特性
- Durability (永続性)
  - トランザクションが成功すると、その結果が永続的に保存されることを保証します。システム障害が発生しても、トランザクションの結果は失われないことを保証するという特性
</details>

<details><summary>15.ETLについて説明して下さい。
</summary>

ETL(Extract, Transform, Load)はデータソースからデータを抽出し、変換して目的の形式に整え、データウェアハウスやデータマートにロードするプロセスのこと。
- Extract: データソースからデータを抽出するプロセス。データソースには、データベースだけでなく、ファイルやAPIなども含まれる
- Transform: 抽出したデータを目的の形式に変換するプロセス。例えば。複数の異なるデータベースから顧客情報を抽出した場合などは、フォーマット形式が異なるので、それを統一したり、データのクリーニングを行ったりする
- Load: 変換したデータをデータウェアハウスやデータマートにロードするプロセス。ロードは一括で行われる場合もあれば、それぞれロードされる場合もある
</details>

<details><summary>16.デッドロックとは何ですか？また、デッドロックを避けるための方法はありますか？</summary>

デッドロックとは
複数のトランザクションがお互いにリソースを待ち続けている状態のこと。この状態になると、トランザクションは永遠に完了せず、システムが停止してしまう

e.g)
1.トランザクションAがリソース1をロックし、リソース2を待っている
2.トランザクションBがリソース2をロックし、リソース1を待っている
この場合、トランザクションAとBがお互いにリソースを待ち続けるため、どちらの操作も完了することができない

解決策
- リソースの順位付け
  - 全てのトランザクションに対してリソースを取得する順序を統一させることで、デッドロックを防ぐ
- タイムアウト
  - トランザクションが一定時間リソースを待ち続けるとタイムアウトしてロールバックするように設定する
- デッドロック検出
  - デッドロックを検出するアルゴリズムを利用して、デッドロックが発生した場合にはトランザクションをロールバックするというもの。多くのDBMSではデッドロック検出機能を提供しているので、それらを利用する
- プリエンプティブロック
  - トランザクションがリソースを取得する前に、他のトランザクションがそのリソースを保持している場合、リソースを強制的に解放させる方法。これにより、強制的にデッドロックを回避する

</details>

<details><summary>17.データの冗長性を減らし整合性を保つための設計方法にはどのようなものがありますか？</summary>

- 正規化
  - データベース設計においてデータの冗長性を減らし、データの整合性を保つためのプロセス
>第一正規系：各列が単一の値を持ち、重複する列がないこと
>第二正規系：第一正規系を満たしていること。主キーの一部に依存する部分的な依存関係がないこと（部分的依存の排除）
>第三正規系：第二正規系を満たしていること。主キー以外の列に依存する推移的な依存関係がないこと（推移的依存の排除）
>ボイス・コッド正規系：第三正規系を満たしていること。任意の非キー属性が候補キーに完全に依存していること

- 制約の使用
  - データベース制約を使用する。例えば、主キー制約（テーブル内の各行を一意に識別するための列を定義する）や外部キー制約（他のテーブルの主キーを参照する列を定義し、テーブル間でのリレーションシップを確立する）などを利用して安全なデータのみを扱うようにして整合性を保てる。他にもチェック制約や非NULL制約など色々ある
- トリガーの使用
  - トリガーは特定のイベント（INSERT, DELETE等)が発生した時に自動的に実行されるストアドプロシージャである
>ストアドプロシージャとは？
>戻り値のある関数はファンクション(function)と呼ばれ、戻り値のない関数はプロシージャ(procedure)と呼ばれる。
>そのうち、SQLで書かれたものをストアド〜(stored hoge)と呼ぶ。
>よって今回でいうストアドプロシージャ(stored procedure)とは戻り値のない関数をトリガーとして設定するということである

</details>

<details><summary>18.ビュー（仮想テーブル）とは何でしょうか？そのメリットは何ですか？
</summary>

ビュー (view、仮想テーブル)とは、データベース内の一つ以上のテーブルから作成される仮想のテーブル。ビューは実際のデータを保持せず、元になるテーブルのデータに対するクエリの結果を表す。ビューはSELECT文を使用して定義され、仮想的なテーブルとしてあつかわれる
簡単に言うとSELECT文に対するあだ名のようなもの
```sql:view
CREATE VIEW active_users AS
SELECT id, name, email
FROM users
WHERE status = 'active';
```

このようにすると、`active`なstatusを保持する`user`の`id`や`name`などが`active_users`というテーブルとして定義される。これらを再度利用して、
```sql:viewの再利用
SELECT name
FROM active_users
WHERE id <= 100;
```
このようにすることで
```sql
SELECT name
FROM {
    CREATE VIEW active_users AS
    SELECT id, name, email
    FROM users
    WHERE status = 'active';
    }
WHERE id <= 100;
```
と同義になる

メリット
-  データの抽象化：ビューを使用することで、複雑なクエリを簡略化し、データの抽象化を提供し簡単に再現できるようになる
-  セキュリティの向上：ビューを使用することで、ユーザーがアクセスできるデータを制限することができる。特定の行や列のみを含むビューを作成し、ユーザーにアクセス権を与えることで、機密データのアクセスを制御できる
-  データの一貫性の維持：ビューにより、複数のアプリケーションやユーザーが同じデータビューを共有できるため、データの一貫性が保たれる
-  パフォーマンスの向上：マテリアライズドビュー（実際のデータを保持するビュー）を使用することで、頻繁に実行されるクエリの結果をキャッシュし、パフォーマンスを向上させることができる

</details>

<details><summary>19.SQLインジェクションとは何ですか？また、対策方法について説明してください。
</summary>

SQLインジェクションとは、攻撃者が悪意のあるSQLコードを入力フィールドやURLパラメータに挿入し、データベースに対して不正な操作を行う攻撃手法
```sql:SQLインジェクション例
SELECT * FROM users WHERE username = 'admin' AND password = 'password';
```
このような入力を考える。ここでの`admin`と`password`は私たちが入力したものが反映される。

このようなものに対して
```sql:攻撃者
username: admin' --
password: anything
```
としたとする。
すると、
```sql:入力
SELECT * FROM users WHERE username = 'admin' --' AND password = 'anything';
```
このように反映される。
ここで問題なのが、``--`はSQLにおいてコメントアウト記号であり、後続の部分が無視される。
結果としてクエリは以下のように読み込まれる
```
SELECT * FROM users WHERE username = 'admin';
```
これにより、攻撃者はパスワードを知らなくても`admin`ユーザーとしてログインできてしまう。

対策
- プレースホルダ（Placeholder）
  - プレースホルダはSQLクエリ内で動的に値を挿入するための位置を示す記号
  ```sql:プレースホルダ
  SELECT * FROM users WHERE username = ? AND password = ?
  ```
  - これにより、`?`がプレースホルダとして使用され、あとで実際の値がバインドされる。これ単体というよりも、後のプリペアードステートメントなどと共に使用される
- エスケープ処理（Escaping）
  - エスケープ処理は、ユーザー入力を安全な形式に変換することで、SQLインジェクションを防ぐ方法。特定の文字（シングルクウォート、ダブルクウォート）をエスケープすることで、SQLクエリの構文を壊さないようにする 
- プリペアードステートメントとパラメータ化クエリ（Prepared Statements and Parameterized Queries）
  - プリペアードステートメントとは、SQLクエリと事前にコンパイルしておくという方法である。その際に、実際の値は事前コンパイル時には受け取っていないので、プレースホルダーで位置のみをコンパイルする。プレースホルダを用いてコンパイルをして、そこに実際の値を安全にバインドする方法をパラメータ化クエリという。
    ```go:Goでの例
    // プリペアードステートメントの作成（プレースホルダを用いて事前コンパイル）
    stmt, err := db.Prepare("SELECT * FROM users WHERE username = ? AND password = ?")
    if err != nil {
        log.Fatal(err)  
    }
    defer stmt.Close()

    // パラメータのバインドとクエリの実行（パラメータ化クエリ）
    rows, err := stmt.Query(username, password)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()
    ```
  - これにより、SQLコードとデータが分離され、ユーザー入力はデータとして扱われ、SQLクエリの構文として解釈されなくなる。また、データベースエンジンはプレースホルダにバインドされた値を自動的にエスケープするので、ユーザー入力がSQLクエリの構文を壊すことを防ぐことができる
- ウェブアプリケーションファイアウォール（WAF）の使用
  - WAFはwebアプリケーションへの攻撃を検出し、防御するためのシステム
  - WAFの機能
    - 攻撃パターンの検出
    - リアルタイムの防御
    - 攻撃の思考をログに記録し、管理者にアラートを送信する

</details>

<details><summary>20.データベースのバックアップ方法にはどのようなものがありますか？
</summary>

Full Backup
- データベース全体の完全なコピーを作成する。すべてのデータ、テーブル、インデックス、トリガー、ストアドプロシージャなどが含まれる
- 利点：データベースが完全に復元できるため、最も信頼性が高い
- 欠点：バックアップファイルのサイズが大きくなり、バックアップと復元に時間がかかることがある
Incremental Backup
- 前回のバックアップ以降に変更されたデータのみをバックアップする。フルバックアップと合わせて使用される
- 利点：バックアップファイルのサイズが小さく、バックアップ時間が短縮される
- 欠点：復元にはフルバックアップとすべての増分バックアップが必要。復元プロセスが複雑になることがある
Diffrential Backup
- 最後のフルバックアップ以降に変更されたデータのみをバックアップする。フルバックアップと組み合わせて使用される
- 増分バックアップよりも復元が簡単で、フルバックアップと最新の差分バックアップだけで復元できる
- 増分バックアップよりもバックアップファイルのサイズが大きくなることがある
> [図でわかりやすく](https://www.activeimage-re.com/column_b/backup-column23.html)

Transaction Log Backup
- トランザクションログをバックアップし、データベースの変更履歴を保存する。フルバックアップと組み合わせて使用される
- データベースのポイントインタイムリカバリが可能。特定の時点にデータベースを復元できる
- トランザクションログの管理が必要。ログが大きくなると、バックアップと復元に時間がかかることがある
Snapshot Backup
- ストレージレベルでデータベースのスナップショットを作成する。ストレージシステムの機能を使用して、データベースの状態を瞬時にキャプチャして、保存する。なので、ディスクの故障などで元データが壊れた場合などは元の状態に戻れなくなる
- 利点：状態を保存するだけなのでバックアップが非常に高速で、データベースのパフォーマンスに影響を与えない
- 欠点：ストレージシステムの機能に依存し、スナップショットができない場合などもある。あくまでも、ある時点のイメージが同様のストレージ内に保存されているだけなので、ディスクが故障した場合などにデータを復元できない。（バックアップなどは別のストレージ（クラウドやNAS(Network Attached Storage)などに保存されるため、一つのディスクが壊れても復元可能だが、スナップショットの場合は復元不可）
Cloud Backup
- データベースのバックアップをクラウドストレージに保存する。クラウドプロバイダのバックアップサービスを使用する
- データの安全性が向上し、災害復旧が容易。クラウドストレージのスケーラビリティを活用できる
- クラウドストレージのコストが発生する。データ転送速度が遅い場合がある

</details>

<details><summary>21.データベースのレプリケーション方法として実現可能なものをあげて下さい。
</summary>

- マスタースレーブレプリケーション(Master-Slave Replication)
- マルチマスターレプリケーション(Multi-Master Replication)
- リングレプリケーション(Ring Replication)
- ハブアンドスポークレプリケーション(Hub and Spoke Replication)
- ピアツーピアレプリケーション(Peer-to-Peer Replication)
- ストリーミングレプリケーション(Streaming Replication)
- データベースシャーディング(Database Sharding)
[記事書きました](https://qiita.com/Yutosaki/items/1f9fe3e1efca5324c848)
</details>

<details><summary>22.ストアドプロシージャとは何ですか？また、その利点は何ですか？
</summary>

ストアドプロシージャとは、データベース内にあらかじめ保存された一連のSQL文やロジックをまとめたプログラムのこと。クライアントからの要求に応じてサーバー側で実行される

> SQLで書かれたプログラムをストアド(Stored)という
> 戻り値を持たないか、複数の値をOUTパラメータで返却する関数をプロシージャ(Procedure)、戻り値のある関数をファンクション(Function)という
> ストアドファンクションは単一の戻り値を返すので、SELECT文の中で使用することができる

利点：
- 一度コンパイル・最適化されてデータベース内に保存されるため、実行時のオーバーヘッドが減少する
> オーバーヘッドとは
> システムやプログラムが本来の目的を達成するために必要な追加の計算資源や時間のことを指す。具体的には、以下のようなものが含まれる
> 計算オーバーヘッド: プログラムの実行に必要な追加の計算処理。
> メモリオーバーヘッド: プログラムの実行に必要な追加のメモリ使用量。
> 通信オーバーヘッド: ネットワーク通信に伴う追加の遅延やデータ転送量。
>ネットワークオーバーヘッドの削減: クライアントとサーバー間の通信回数が減少するため、ネットワークの遅延が減少する
>計算オーバーヘッドの削減: 一度コンパイルされたストアドプロシージャは、再利用時に再コンパイルが不要なため、実行時のオーバーヘッドが減少する
>メモリオーバーヘッドの削減: ストアドプロシージャはデータベースサーバー上で実行されるため、クライアント側のメモリ使用量が減少する

- 権限管理をストアドプロシージャに設定することで、直接テーブルにアクセスさせずに操作を制限できる
- 共通の処理をストアドプロシージャとして定義し、複数のアプリケーションやクライアントから呼び出すことができる

</details>

<details><summary>23.RDBMSにおいてトリガーとはどのような役割を持つでしょうか？
</summary>

トリガー(Trigger)は特定のイベントが発生したときに自動的に実行される一連のSQLステートメント。トリガーは、データベースの整合性を保ち、特定のビジネスロジックをデータベースレベルで実行するために使用される

役割
- トリガーは、データの挿入、更新、削除時に自動的に実行されるため、データの整合性を保つためのルールを強制することができる。例えば、関連するテーブル間でデータの一貫性を保つためなどに使用される
- トリガーによって、ある特定の変更などをログなどに保存することができる

トリガーの種類
- BEFORE トリガー
- AGTER トリガー
- INSTEAD OF トリガー

```sql:BEFOREトリガー
CREATE TRIGGER before_user_insert
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
    SET NEW.username = UPPER(NEW.username);
END;
```
このようにすることで、データを挿入前に大文字に直したり、などができる

</details>

<details><summary>24.データベース設計におけるER図の役割と作成方法について説明してください。
</summary>

ER図(エンティティ・リレーションシップ図)はデータベース設計の初期段階で使用される視覚的なツールで、データベースの構造を表現する

役割
- データベース内のエンティティ（テーブル）とそれらの間のリレーションシップ（関係）を視覚的に表現する。これにより、データベースの全体像を把握しやすくなる
- エンティティ間の関係や制約を明確にすることで、データの整合性を確保する。例えば、外部キー制約や一意性制約などを設計段階で考慮できる
- データベース設計の初期段階で、ビジネス要件やデータ要件を明確にするために使用される。関係者間で共通の理解を持つことができる

作成方法
- データベース内で管理する必要がある主要なオブジェクト（エンティティ）を特定する。エンティティは、データベース内のテーブルに対応する
  - 顧客、注文、商品、など
- 各エンティティに関する属性を特定する。属性は、エンティティの特性や情報を表す
  - 顧客エンティティの属性として、顧客ID、名前、メールアドレス、など
- 各エンティティに対して一意に識別するための主キー(Primary key)を設定する
  - 顧客エンティティの主キーとして顧客IDを設定
- エンティティ間の関係（リレーションシップ）を特定する。リレーションシップはエンティティ間の関連性を表す
  - 顧客と注文の間には、顧客は複数の注文を持つ、というリレーションシップがある
- リレーションシップの種類（1対1、1対多、多対多）を特定する。リレーションシップの種類に応じて、外部キーや中間テーブルを設計する
  - 顧客と注文のリレーションシップは1対多である。注文と商品のリレーションシップは多対多（注文は複数の商品を含み、商品は複数の注文に含まれる）など

</details>

<details><summary>25.データベースのパーティショニング（分割）とは何ですか？また、その利点は何ですか？
</summary>

DBのパーティショニング(Partitioning)とは、大規模なテーブルを複数の小さな部分(パーティション)に分割する技術。各パーティションは独立して管理され、クエリのパフォーマンス向上や管理の効率化を図るために使用される。
- レンジパーティショニング
  - 特定の範囲に基づいてデータを分割する。例えば、日付や、数値の範囲に基づいてパーティションを作成する
- ハッシュパーティショニング
  - ハッシュ関数を使用してデータを分割する。特定の列の値に基づいてハッシュ値を計算し、そのハッシュ値に基づいてパーティションを決定する
- リストパーティショニング
  - 特定のリストに基づいてデータを分割する。例えば、地域ごとにデータを分割したりなど

利点：
- パーティショニングにより、クエリが特定のパーティションに対してのみ実行されるため、検索範囲が狭まり、クエリのパフォーマンスが向上する
- 大規模なテーブルを複数のパーティションに分割することで、データの管理が容易になる
- パーティショニングにより、特定のパーティションに障害が発生しても、他のパーティションは影響を受けずに動作を続けることができる
</details>

<details><summary>26.分散データベースの利点と課題について説明してください。
</summary>

分散DBとは、データが複数の物理的な場所に分散して保存されるDBMSである。これにより、データの可用性、スケーラビリティ、パフォーマンスが向上するが課題もあるというもの

利点：
- データとトラフィックを複数のサーバーに分散させることができるので、システム全体のスケーラビリティが向上する
- データが複数の場所に分散されるため、一つのサーバーがダウンしても他のサーバーがデータを提供し続けることができる
  - 分散DBではデータの可用性を高めるため、それぞれのサーバーに対してさらにレプリケーションがあることが一般的である。なので、一つのサーバーが落ちても可用性が高く、データにアクセスすることができる
  - また、分散DBには自動的にフェイルオーバーをする（稼働中のサーバーに障害が生じたら、待機中のサーバーに切り替えること）機能を備えているので、サービスの中断を最小限に抑えることができる
- データとトラフィックが分散されるので、負荷が分散され、システム全体のパフォーマンスを最適化する

課題
- 複数のサーバー間でデータの同期を行う際にデータの整合性を保つための仕組みが必要（CAP定理（Consistency, Availability, Partition Tolerance）により、完全な一貫性と可用性を同時に達成することは難しいとされている）
- 分散データベースはネットワークに依存しているため、ネットワークの信頼性や遅延がシステム全体のパフォーマンスに影響を与えることがある。ネットワークの障害や遅延が発生すると、データの同期やクエリの応答時間が遅くなる可能性があるので注意が必要
- データをどのように分散（シャーディング）するかを設計することが難しい。適切なシャーディングキーを選択し、データの分散を最適化する必要がある
- 複数のサーバー間にデータが分散しているので、セキュリティとアクセス制御が複雑になる
</details>

<details><summary>27.NoSQLデータベースにはどのような種類がありますか？また、それぞれの特徴について説明してください。
</summary>

NoSQL(Not Only Structure Query Language)はリレーショナルデータベースとは異なるデータモデルと採用しており、特定のユースケースやスケーラビリティの要件に応じて設計されている。

- キー・バリュー型データベース(Key-Value Stores)
  - キー・バリュー型DBはキーとそれに対応するバリューのペアでデータを保存する。キーは一意であり、バリューは任意のデータ型を持つことができる
  - 特徴
    - キーとバリューのペアでデータを管理するため、非常にシンプルなデータモデルを持つ
    - データの分散とスケーリングが容易で、大規模なデータセットに対して高いパフォーマンスを発揮する
    - キーを使用してデータに直接アクセスするので、読み書きの操作が非常に高速
　　
- ドキュメント型データベース(Document Stores)
  - JOSNやXMLなどの形式でデータを保存する。各ドキュメントは自己完結型であり、複雑なデータ構造を持つことができる
  - 特徴
    - スキーマレス、または柔軟なスキーマを持つので、データモデルの変更が容易
    - ドキュメント内にネストされたデータ構造を持つことができるので、複雑なデータを効率的に管理できる
    - ドキュメントの内容に基づいて柔軟なクエリを実行できる
　　
- カラムファミリー型データベース(Column-Family Stores)
  - データを行と列の形式で保存するが、リレーショナルDBとは異なり、 各行には異なる列を持つことができる。データはカラムファミリーと呼ばれるグループに分けられる
  - 特徴
    - 大規模なデータセットに対して高いスケーラビリティ
    - 同じカラムファミリー内のデータは効率的に圧縮される
    - 各行が異なる列をもつことができ、スキーマの変更が容易

- グラフ型データベース(Graph Database)
  - ノード（エンティティ）とエッジ（関係）を使用してデータを表現する。ノードをエンティティを表、エッジはエンティティ間の関係を表す
  - 特徴
    - エンティティ間の複雑なリレーションシップを効率的に管理できる
    - グラフ操作（最短経路探索、隣接ノードの検索など）が高速に実行できる
    - データのリレーションシップを直感的に表現でき、特にソーシャルネットワークや推薦システムに適している
</details>

<details><summary>28.キャッシュとデータベースの違いは何ですか？また、キャッシュを使う利点は何ですか？
</summary>

データベース(Database)
- データの永続的な保存と管理を行うシステム。データベースはデータの整合性、一貫性、永続性を保証し、複雑なクエリやトランザクションをサポートする

キャッシュ(Cache)
- 頻繁にアクセスされるデータを一時的に保存し、高速なデータアクセスを提供するシステム。キャッシュはデータベースや他のデータソースからのデータメモリを保存し、アクセス速度を向上させる。キーバリュー型でデータを管理することが一般的で、高速なデータアクセスが可能

キャッシュを使う利点：
- キャッシュはメモリ内でデータを管理するため、DBに比べてアクセス速度が非常に高速。これにより、アプリケーションの応答時間が短縮される
- キャッシュを使用することで、頻繁にアクセスするデータがキャッシュから取得できるため、DBへのクエリ数が減少し、DBへの負荷が軽減される
- キャッシュは分散キャッシュシステムを使用して、スケールアウトすることができるので、大規模なトラフィックに対応できる
</details>

<details><summary>29.スケーリングの方法には垂直スケーリングと水平スケーリングがありますが、その違いは何でしょうか？
</summary>

垂直スケーリング(Vertical Scaling)
- 既存のサーバーのリソース（CPU, メモリ、ストレージ）を増強することで、システムのパフォーマンスを向上させる方法。単一のサーバーの性能を向上させることで、より多くのリクエストやデータを処理できるようにする
- 利点：
  - 既存のサーバーにリソースを追加するだけなので比較的簡単
  - アプリケーションの構造を変更する必要がないため、既存のアプリケーションのまま使用できる
- 欠点：
  - サーバーのハードウェアには物理的な限界があるため、リソースを無限に追加することはできない
  - 単一のサーバーに依存するため、単一障害点(SPOF)になりうる
  - 高性能なハードウェアは高価なので、コストが増加する

水平スケーリング (Horizontal Scaling)
- 複数のサーバーを追加してシステム全体のキャパシティを向上させる方法。新しいサーバーを追加することでリクエストやデータを分散して処理できるようにする
- 利点：
  - サーバーを追加することで、システムのキャパシティをほぼ無限に拡張できる
  - 複数のサーバーにリクエストを分散するため。一つのサーバーがダウンしてもシステム全体が影響を受けにくくなる
  - 比較的安価なサーバーを追加することで、コスト効率よくスケーリングできる
- 欠点：
  - 複数のサーバーを管理するため、システムの管理が複雑になる
  - アプリケーションが分散環境で動作するように設計する必要があ理、データの一貫性やセッションの管理などに対応する必要がある
</details>

<details><summary>30.データベースのパフォーマンスを最適化するための手法にはどのようなものがありますか？</summary>

- インデックスの使用
  - データベース内の特定の列に対して作成されるデータ構造で、データ検索や取得を高速化するために使用される
- クエリの最適化
  - 不要な列の選択や、複雑な結合を避け、シンプルなクエリを作成する
  - 結合条件にインデックスを使用し、結合順序を最適化する
- 正規化と非正規化のバランスを変える
  - データベースの正規化は、データの冗長性を減らし、データの整合性を保つために重要である。しかし、過度な正規化はクエリのパフォーマンスを低下させることがあり、適切なバランスを保つことが重要
  - パフォーマンス向上のために特定のケースで非正規化を行い、データの重複を許容する
- キャッシュの使用
  - 頻繁にアクセスされるデータをキャッシュに保存することで、データベースへのアクセス回数を減らし、パフォーマンスを向上させる
  - アプリケーションキャッシュ：アプリケーションレベルで使用し、データベースへのアクセスを減らす
  - データベースキャッシュ：データベース内でキャッシュを使用し、クエリの結果をキャッシュする
- パーティショニング
  - 大規模なテーブルを複数の小さなパーティションに分割することで、クエリのパフォーマンスを向上させる
- データベース設定の最適化
  - バッファサイズを調整して、キャッシュヒット率を向上させる
  - DB接続プールを設定し、接続のオーバーヘッドを減らす
  - クエリのキャッシュを有効にする
</details>

# 最後に
30問お疲れ様でした！どこかしらで聞いたことのある知識や名前から類推できるものもたくさん合ったと思います！色んな分野の1問1答を行っているので、よければ他の記事も見ていってください！
[インフラ編](https://qiita.com/Yutosaki/items/da6be5f84de7fe156b9e0)
[ネットワーク編](https://qiita.com/Yutosaki/items/956c0545a1fb506ab3880)