なぜデータベース・オブジェクトの管理が重要なのか？

## はじめに
データベース・オブジェクトの管理は、データベースのパフォーマンス、整合性、セキュリティを維持するために重要です。表、索引、ビュー、トリガー、ストアドプロシージャなどのデータベース・オブジェクトを適切に管理することで、効率的で信頼性の高いデータベースシステムを構築することができます。定期的なメンテナンスと最適化を行い、データベースのパフォーマンスを最大限に引き出すことができます。

今回は、なぜデータベース・オブジェクトの管理が重要なのか？整理してみました。

### なぜデータベース・オブジェクトの管理が重要なのか？

**データの整合性** 
オブジェクトの構造やデータの整合性を保ち、データの信頼性を確保する必要があるから。
**パフォーマンス向上** 
適切な索引を作成することで、クエリの実行時間を大幅に改善できるから。
**データのセキュリティ** 
アクセス権限の設定や、不要なオブジェクトの削除により、データのセキュリティを確保する必要があるから。
**ストレージの効率化** 
不要なオブジェクトを削除したり、パーティショニングを適用することで、ストレージ容量を最適化する必要があるから。

### 各オブジェクトの管理

#### 1. 表（Tables）

**作成** データを格納するための基本的なオブジェクトです。
**変更** 列の追加・削除、データ型の変更、制約の追加など、表の構造を変更します。
**削除** 不要になった表を削除します。
**パーティショニング** 大規模な表を複数のパーティションに分割することで、クエリのパフォーマンスを向上させたり、管理を容易にします。

#### 2.索引（Indexes）

**作成** 特定の列に索引を作成することで、その列に対する検索を高速化します。
**変更** 索引の種類を変更したり、索引のキーを変更します。
**削除** 不要になった索引を削除します。
**最適化** 索引の利用状況を分析し、不要な索引を削除したり、新しい索引を作成することで、索引の性能を最適化します。

#### 3.ビュー（Views）

**作成** 基底となる表のデータを仮想的に表示するためのオブジェクトです。
**変更** ビューの定義を変更します。
**削除** 不要になったビューを削除します。

#### 4.トリガー

**トリガー** は、特定のイベント（INSERT、UPDATE、DELETEなど）が発生した際に、自動的に実行されるデータベースオブジェクトです。トリガーは、データの整合性維持、監査ログの作成、関連するテーブルの更新など、様々な用途に利用されます。

**データの整合性維持**
特定の列にNULL値が入らないようにする
主キーの重複を防ぐ
関連するテーブルのデータを連動して更新する
**監査ログの作成**
データの変更履歴を記録する
**ビジネスロジックの実装**
複雑なビジネスロジックをデータベース内に実装する

#### 5.ストアドプロシージャ

**ストアドプロシージャ** は、事前に定義された一連のSQL文をまとめたもので、名前をつけて保存しておくことができます。ストアドプロシージャは、複雑な処理をカプセル化し、再利用性を高めるために使用されます。

**複雑な処理の実装**
複数のテーブルを結合する
条件分岐やループ処理を行う
**トランザクション処理**
複数のSQL文を一つのトランザクションとして実行する
**データの集計**
大量のデータを効率的に集計する

### トリガーとストアドプロシージャの違い

| 特徴 | トリガー | ストアドプロシージャ |
|---|---|---|
| 呼び出し方 | イベント発生時自動実行 | アプリケーションから呼び出し |
| パラメータ | なし | あり |
| 結果セット | 返さない | 返す |
| 目的 | データの整合性維持、監査ログなど | 複雑な処理の実装、再利用性向上 |



#### 


### 1. 表（Tables）

#### 作成
表はデータを格納する基本的なデータベース・オブジェクトです。

```sql
CREATE TABLE employees (
    id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email VARCHAR(100) UNIQUE,
    hire_date DATE
);
```

#### 変更
既存の表に列を追加したり、列のデータ型を変更したりすることができます。

```sql
-- 列の追加
ALTER TABLE employees ADD COLUMN department_id INT;

-- 列のデータ型変更
ALTER TABLE employees MODIFY COLUMN email VARCHAR(150);
```

#### 削除
不要になった表を削除することができます。

```sql
DROP TABLE employees;
```

### 2. 索引（Indexes）

#### 作成
索引は、データベースの検索パフォーマンスを向上させるために使用されます。

```sql
CREATE INDEX idx_last_name ON employees (last_name);
```

#### 変更
索引の変更は直接行うことはできませんが、既存の索引を削除して新しい索引を作成することが一般的です。

```sql
-- 索引の削除
DROP INDEX idx_last_name ON employees;

-- 新しい索引の作成
CREATE INDEX idx_last_name_first_name ON employees (last_name, first_name);
```

#### 再構築
索引の断片化を防ぐために、定期的に索引を再構築することが推奨されます。

```sql
ALTER INDEX idx_last_name REBUILD;
```

#### 削除
不要になった索引を削除することができます。

```sql
DROP INDEX idx_last_name ON employees;
```

### 3. ビュー（Views）

#### 作成
ビューは、複雑なクエリを簡略化し、データの抽象化を提供する仮想テーブルです。

```sql
CREATE VIEW employee_details AS
SELECT id, first_name, last_name, email
FROM employees
WHERE hire_date > '2020-01-01';
```

#### 変更
既存のビューを変更するには、ビューを再作成する必要があります。

```sql
-- 既存のビューを削除
DROP VIEW employee_details;

-- 新しいビューを作成
CREATE VIEW employee_details AS
SELECT id, first_name, last_name, email, department_id
FROM employees
WHERE hire_date > '2020-01-01';
```

#### 削除
不要になったビューを削除することができます。

```sql
DROP VIEW employee_details;
```

### 4. トリガー（Triggers）

#### 作成
トリガーは、特定のイベント（INSERT、UPDATE、DELETE）が発生したときに自動的に実行されるストアドプロシージャです。

```sql
CREATE TRIGGER before_employee_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
    SET NEW.hire_date = IFNULL(NEW.hire_date, CURDATE());
END;
```

#### 変更
既存のトリガーを変更するには、トリガーを再作成する必要があります。

```sql
-- 既存のトリガーを削除
DROP TRIGGER before_employee_insert;

-- 新しいトリガーを作成
CREATE TRIGGER before_employee_insert
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
    SET NEW.hire_date = IFNULL(NEW.hire_date, CURDATE());
    SET NEW.email = LOWER(NEW.email);
END;
```

#### 削除
不要になったトリガーを削除することができます。

```sql
DROP TRIGGER before_employee_insert;
```

### 5. ストアドプロシージャ（Stored Procedures）

#### 作成
ストアドプロシージャは、複数のSQLステートメントをまとめて実行するためのプログラムです。

```sql
CREATE PROCEDURE add_employee (
    IN p_first_name VARCHAR(50),
    IN p_last_name VARCHAR(50),
    IN p_email VARCHAR(100),
    IN p_hire_date DATE
)
BEGIN
    INSERT INTO employees (first_name, last_name, email, hire_date)
    VALUES (p_first_name, p_last_name, p_email, p_hire_date);
END;
```

#### 変更
既存のストアドプロシージャを変更するには、プロシージャを再作成する必要があります。

```sql
-- 既存のプロシージャを削除
DROP PROCEDURE add_employee;

-- 新しいプロシージャを作成
CREATE PROCEDURE add_employee (
    IN p_first_name VARCHAR(50),
    IN p_last_name VARCHAR(50),
    IN p_email VARCHAR(100),
    IN p_hire_date DATE,
    IN p_department_id INT
)
BEGIN
    INSERT INTO employees (first_name, last_name, email, hire_date, department_id)
    VALUES (p_first_name, p_last_name, p_email, p_hire_date, p_department_id);
END;
```

#### 削除
不要になったストアドプロシージャを削除することができます。

```sql
DROP PROCEDURE add_employee;
```

参考文献
オラクルマスター教科書 Silver DBA Oracle Database Administration I
第21章　ビュー
https://www.shoeisha.co.jp/book/detail/9784798172033