Newer
Older
hello-programmer-world / src / pages / sql / 010-foundation.mdx
@h.sakamoto h.sakamoto on 10 Feb 6 KB sql
---
layout: "@/layouts/MarkdownLayout.astro"
---

export const title = "SQLの基本";

# {title}

## TOC

## 考え方

データベースとは、データいくつかのデータを1つのまとまり(テーブル)として保存し、そのテーブルに対して様々な操作を行う仕組みです。

例えば個人情報を扱う場合、実際に登場する情報には以下のようなものが考えられます。

- 氏名
- 性別
- 住所
- 電話番号
- 誕生日

etc...

様々なものがありますが、これらのうち必要なものを選び、1つのまとまり(テーブル)として保存します。  
以下の例では、氏名と住所を1つのまとまりとして保存するテーブルです。

同時に、管理番号として`ID`を付与しています。

**例**: `users`テーブル

テーブル構造

| 列名 | 型 |
| :----- | :-- |
| `id` | INT |
| name | VARCHAR(100) |
| address | VARCHAR(255) |

データ例

| id | name | address |
| --: | :---- | :------ |
| 1 | 山田太郎 | 東京都千代田区 |
| 2 | 佐藤花子 | 東京都新宿区 |
| 3 | 鈴木一郎 | 愛知県名古屋市 |

## 型

代表的な型を紹介します。

| 型名 | 説明 | データ例 |
| :----- | :-- | :------ |
| `INT` | 整数 | 1, 100, -50 |
| `BIGINT` | 21億より大きい数に対応した整数 | 10000000000 |
| `VARCHAR(n)` | 文字列(最大n文字まで) | '山田太郎', 'Hello' |
| `TEXT` | 文字列(長文向け) | 'これは長い文章です。' |
| `DATETIME` | 日付と時間 | '2024-01-01 12:00:00' |

## なぜIDが必要なの?

普段の生活では、例えば誰かを判断する場合に名前で判断することが多いです。  
しかしプログラムの世界では、これを避けて敢えて`ID`を割り振っています。

ところで、2000人の人を1か所に集めると、そのなかに同姓同名のペアが1つ以上存在する確率は約86%だそうです。  
[引用 - 同姓同名のペアができる確率をExcelで計算したら予想よりも高かった件。](https://note.com/yudo_tanaka/n/ndddef4b15d95)

これが多いか少ないかはさておき、名前で人を特定することが難しい場合があることがわかります。  
複数の箇所で名前が登録されているとき、それが同一人物なのか別人なのかを判断することができません。

これを回避して確実に1人を特定するために、`ID`を割り当てているのです。

なお、SQLの世界では、`ID`は主に **主キー (Primary Key)** として使われます。  
また、複数のキーを組み合わせて一意に特定する **複合キー (Composite Key)** にすることもあります。

IDには、以下のようなものが使われることが多いです。

**連番 (1, 2, 3, ...)**

自動で連番を振る仕組みがデータベースに備わっていることが多く、重複しないことが直感的にわかりやすい

**UUID (例: `550e8400-e29b-41d4-a716-446655440000`)**

時刻や、操作しているコンピュータの情報などを元に生成されるIDで、重複する可能性が天文学的に低い

**ハッシュ値 (例: `5d41402abc4b2a76b9719d911017c592`)**

例えばメールアドレスなど、元のデータから一意に生成される値をIDとして使う場合に使われることがある。  
同じメールアドレスからは同じハッシュ値が生成されるため、重複を避けられる。

## テーブルそのものを操作する

### テーブルを作成 (CREATE TABLE)

```sql
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    address VARCHAR(255)
);
```

### テーブルを削除 (DROP TABLE)

```sql
DROP TABLE users;
```

## テーブルからデータを操作する

### データを追加 (INSERT)

どんな操作をするにしても、まずはデータが必要です。  
データを追加するテーブルの構造に合わせて、`INSERT`文を使ってデータを追加します。

```sql
-- 1件のデータを追加する場合
INSERT INTO users (id, name, address) VALUES (1, '山田太郎', '東京都千代田区');

-- 複数件のデータを追加する場合
INSERT INTO users (id, name, address)
VALUES
(2, '佐藤花子', '東京都新宿区'),
(3, '鈴木一郎', '愛知県名古屋市');
```

### データを取得 (SELECT)

#### 登場したすべてのテーブルから、すべての列を取得する場合

```sql
SELECT * FROM users;
```

#### 登場した特定のテーブルから、すべての列を取得する場合

```sql
SELECT users.* FROM users;
```

#### 特定の列だけを取得する場合

```sql
SELECT users.id, users.name FROM users;
```

### 条件を指定する (WHERE)

`SELECT`でデータを全件取得したとしても、実際にはそこから何かを探すことが多いです。  
この、テーブルから特定の条件に合うデータだけを取得したい場合、`WHERE`句を使います。

後述する`UPDATE`や`DELETE`でも、同様に使うことができます。

#### 完全に一致するものを取得する場合

```sql
-- IDが1のユーザーを取得する
SELECT * FROM users WHERE id = 1;

-- 名前が「山田太郎」のユーザーを取得する
SELECT * FROM users WHERE name = '山田太郎';
```

#### 部分的に一致するものを取得する場合

```sql
-- 名前のどこかに「花」を含むユーザーを取得する
SELECT * FROM users WHERE name LIKE '%花%';

-- 住所が「東京都」で始まるユーザーを取得する
SELECT * FROM users WHERE address LIKE '東京都%';

-- 名前が「太郎」で終わるユーザーを取得する
SELECT * FROM users WHERE name LIKE '%太郎';
```

#### 範囲を指定する場合

```sql
-- IDが2以上のユーザーを取得する
SELECT * FROM users WHERE id >= 2;
```

### データを更新 (UPDATE)

データを更新するには、`UPDATE`文を使います。  
バックアップなどを取らずに更新をする場合、元に戻せないことがあるため、注意が必要です。

あらかじめ、`SELECT`文で更新対象のデータを確認してから実行すると良いでしょう。

```sql
-- IDが1のユーザーの住所を更新する
UPDATE users SET address = '東京都港区' WHERE id = 1;
```

### データを削除 (DELETE)

`UPDATE`と同様に、`DELETE`文もバックアップなどを取らずに実行すると元に戻せないことがあるため、注意が必要です。  
あらかじめ、`SELECT`文で削除対象のデータを確認してから実行すると良いでしょう。

```sql
-- IDが3のユーザーを削除する
DELETE FROM users WHERE id = 3;
```