H2 Database（H2DB）におけるテーブル作成方法 詳細チュートリアル

# H2 Database（H2DB）におけるテーブル作成方法 詳細チュートリアル

このチュートリアルでは、**H2 Database（H2DB）**を使用してテーブルを作成する方法について、より詳細かつ具体的に解説します。基本的なテーブル作成から、データ型、制約、インデックスの設定など、実践的な内容をステップバイステップで学びましょう。

## 目次

1. [テーブル作成の基本構文](#テーブル作成の基本構文)
2. [データ型の選択](#データ型の選択)
3. [主キーの設定](#主キーの設定)
4. [外部キーの設定](#外部キーの設定)
5. [制約の追加](#制約の追加)
   - NOT NULL
   - UNIQUE
   - DEFAULT
   - CHECK
6. [インデックスの作成](#インデックスの作成)
7. [テーブル作成の実践例](#テーブル作成の実践例)
8. [テーブルの変更と削除](#テーブルの変更と削除)
9. [まとめ](#まとめ)

---

## テーブル作成の基本構文

SQLでテーブルを作成する際の基本的な構文は以下の通りです。

```sql
CREATE TABLE テーブル名 (
    カラム名1 データ型 制約,
    カラム名2 データ型 制約,
    ...
);
```

**例：**

```sql
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100)
);
```

この例では、`employees`というテーブルを作成し、`id`, `name`, `email`の3つのカラムを定義しています。`id`カラムには主キー制約が設定されています。

---

## データ型の選択

H2DBでは、多くのデータ型がサポートされています。主なデータ型を以下に示します。

### 数値型

- `INT`：整数型。範囲は -2,147,483,648 から 2,147,483,647。
- `BIGINT`：大きな整数型。
- `DECIMAL(p, s)`：固定小数点数。`p`は精度（総桁数）、`s`は小数点以下の桁数。
- `DOUBLE`：倍精度浮動小数点数。

### 文字列型

- `VARCHAR(n)`：可変長文字列。`n`は最大文字数。
- `CHAR(n)`：固定長文字列。
- `TEXT`：長いテキストデータ。

### 日付・時刻型

- `DATE`：日付。
- `TIME`：時刻。
- `TIMESTAMP`：日時。

### ブール型

- `BOOLEAN`：真偽値。

### バイナリ型

- `BINARY`、`VARBINARY`：バイナリデータ。

**注意点：**

- データ型はデータの性質に合わせて適切に選択しましょう。例えば、メールアドレスには`VARCHAR(100)`、価格には`DECIMAL(10,2)`など。
- H2DBは多くのSQL標準データ型に対応していますが、特定のデータ型については[公式ドキュメント](https://www.h2database.com/html/datatypes.html)を参照してください。

---

## 主キーの設定

**主キー（Primary Key）**は、テーブル内の各レコードを一意に識別するためのカラムです。主キーは一つ以上のカラムで構成されます。

### 単一カラムの主キー

```sql
CREATE TABLE users (
    user_id INT PRIMARY KEY,
    username VARCHAR(50),
    email VARCHAR(100)
);
```

### 複数カラムの主キー（複合主キー）

```sql
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);
```

**ポイント：**

- 主キーには`PRIMARY KEY`制約を使用します。
- 主キーは一意性と非NULLを自動的に保証します。

---

## 外部キーの設定

**外部キー（Foreign Key）**は、他のテーブルの主キーを参照するカラムです。テーブル間のリレーションシップを構築するために使用します。

**例：**

```sql
CREATE TABLE departments (
    dept_id INT PRIMARY KEY,
    dept_name VARCHAR(100) NOT NULL
);

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    dept_id INT,
    FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);
```

**ポイント：**

- 外部キー制約を設定することで、参照整合性を保つことができます。
- 外部キーは、参照先のテーブルとカラムが存在している必要があります。

---

## 制約の追加

テーブル作成時に様々な**制約（Constraints）**を追加することで、データの整合性や品質を保つことができます。主な制約について詳しく見ていきましょう。

### NOT NULL

**NOT NULL**制約は、カラムにNULL値が入るのを禁止します。

**例：**

```sql
CREATE TABLE products (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100) NOT NULL,
    price DECIMAL(10, 2) NOT NULL
);
```

### UNIQUE

**UNIQUE**制約は、カラムの値が全て一意であることを保証します。

**例：**

```sql
CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE,
    phone VARCHAR(15)
);
```

### DEFAULT

**DEFAULT**制約は、カラムに値が指定されなかった場合に自動的に設定されるデフォルト値を指定します。

**例：**

```sql
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    order_date DATE DEFAULT CURRENT_DATE,
    status VARCHAR(20) DEFAULT 'pending'
);
```

### CHECK

**CHECK**制約は、カラムに格納される値に対する条件を指定します。

**例：**

```sql
CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INT,
    CHECK (age >= 18)
);
```

**注意点：**

- 複数の制約を組み合わせて使用することができます。
- 制約名を指定することで、後から制約を変更・削除しやすくなります。

**例： 制約名付きのチェック制約**

```sql
CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INT,
    CONSTRAINT chk_age CHECK (age >= 18)
);
```

---

## インデックスの作成

**インデックス（Index）**は、検索速度を向上させるために使用されます。頻繁に検索やJOINに使用されるカラムに対してインデックスを作成することが推奨されます。

### 単一カラムのインデックス

```sql
CREATE INDEX idx_username ON users(username);
```

### 複数カラムのインデックス（複合インデックス）

```sql
CREATE INDEX idx_order_product ON order_items(order_id, product_id);
```

**ポイント：**

- インデックスは検索速度を向上させますが、データの挿入や更新時にオーバーヘッドが発生します。
- 必要なカラムにのみインデックスを作成するようにしましょう。

---

## テーブル作成の実践例

ここでは、具体的なテーブル作成の例を通じて、上記の知識を実践的に適用してみましょう。

### 例1：ユーザーテーブルの作成

```sql
CREATE TABLE users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

**解説：**

- `user_id`は自動インクリメントの主キー。
- `username`と`email`は一意であり、NULL不可。
- `password`はハッシュ化されたパスワードを格納。
- `created_at`はレコード作成時のタイムスタンプを自動設定。

### 例2：ブログ投稿テーブルの作成

```sql
CREATE TABLE posts (
    post_id INT AUTO_INCREMENT PRIMARY KEY,
    author_id INT,
    title VARCHAR(200) NOT NULL,
    content TEXT NOT NULL,
    published_at TIMESTAMP,
    FOREIGN KEY (author_id) REFERENCES users(user_id)
);
```

**解説：**

- `post_id`は自動インクリメントの主キー。
- `author_id`は`users`テーブルの`user_id`を参照する外部キー。
- `title`と`content`はNULL不可。
- `published_at`は公開日時を記録。

### 例3：注文テーブルと注文詳細テーブルの作成

```sql
CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    customer_id INT,
    order_date DATE DEFAULT CURRENT_DATE,
    status VARCHAR(20) DEFAULT 'pending',
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT CHECK (quantity > 0),
    price DECIMAL(10, 2),
    PRIMARY KEY (order_id, product_id),
    FOREIGN KEY (order_id) REFERENCES orders(order_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id)
);
```

**解説：**

- `orders`テーブルは各注文の基本情報を保持。
- `order_items`テーブルは各注文の詳細（商品ごとの数量と価格）を保持。
- 複合主キーとして`order_id`と`product_id`を設定。
- `quantity`にはチェック制約で1以上を保証。
- 外部キーで`orders`および`products`テーブルと関連付け。

---

## テーブルの変更と削除

既存のテーブルに対して変更を加えたり、不要になったテーブルを削除したりする方法についても理解しておきましょう。

### テーブルの変更

#### カラムの追加

```sql
ALTER TABLE users ADD COLUMN phone VARCHAR(15);
```

#### カラムの削除

```sql
ALTER TABLE users DROP COLUMN phone;
```

#### カラムのデータ型変更

```sql
ALTER TABLE users ALTER COLUMN username VARCHAR(100);
```

#### 制約の追加

```sql
ALTER TABLE users ADD CONSTRAINT chk_username_length CHECK (LENGTH(username) >= 3);
```

#### 制約の削除

```sql
ALTER TABLE users DROP CONSTRAINT chk_username_length;
```

### テーブルの削除

```sql
DROP TABLE IF EXISTS users;
```

**注意点：**

- テーブルを削除すると、そのテーブルに含まれる全てのデータも失われます。実行前に必ずバックアップを取るようにしましょう。
- 外部キー制約が存在する場合、関連するテーブルから先に削除する必要があります。

---

## まとめ

このチュートリアルでは、**H2 Database（H2DB）**を使用したテーブル作成方法について、以下のポイントを詳しく解説しました：

1. **基本構文の理解**：`CREATE TABLE`文の基本的な構造と使用方法。
2. **データ型の選択**：適切なデータ型を選ぶことで、データの整合性と効率性を確保。
3. **主キーと外部キーの設定**：テーブル間のリレーションシップを構築し、データの一意性と参照整合性を保つ。
4. **制約の追加**：`NOT NULL`、`UNIQUE`、`DEFAULT`、`CHECK`などの制約を用いてデータ品質を保証。
5. **インデックスの作成**：検索性能を向上させるためのインデックス設定。
6. **実践的なテーブル作成例**：具体的なシナリオに基づいたテーブル設計の例。
7. **テーブルの変更と削除**：既存のテーブルに対する変更方法と削除手順。

これらの知識を活用して、H2DBで効率的かつ効果的なデータベース設計を行いましょう。さらに深い理解を得るために、[H2 Database 公式ドキュメント](https://www.h2database.com/html/documentation.html)も参照してください。

---

**参考リンク**

- [H2 Database 公式サイト](https://www.h2database.com/)
- [H2 Database データ型一覧](https://www.h2database.com/html/datatypes.html)
- [H2 Database SQL コマンド](https://www.h2database.com/html/commands.html)