基礎から学ぶPython入門 90日コース | データベース・Web API - Day 64:テーブル設計

Python 90日で身につけるPython
スポンサーリンク
スポンサーリンク

Day 64:テーブル設計 ― 「データの家」をどう建てるかを学ぶ

Day 64では、データベースの中でも特に“設計”に関わる大切な概念を扱います。

  • 主キー(PRIMARY KEY)
  • 外部キー(FOREIGN KEY)
  • NOT NULL
  • UNIQUE
  • データ型(INTEGER / TEXT / REAL / …)

昨日までの「SELECT・INSERT・UPDATE・DELETE」は、 すでに出来上がったテーブルを“使う”操作でした。

今日はその一歩手前、 「そもそもテーブルをどう設計するか」 という、データベースの根っこに触れていきます。

テーブル設計は、家づくりに似ています。 柱をどこに置くか、どんな素材を使うか、どんな間取りにするか。 その設計がしっかりしているほど、後から使いやすく、壊れにくいデータベースになります。

データベース設計の世界へ ― 「テーブルはただの表じゃない」

テーブルは“構造”そのもの

テーブルはただの表ではありません。 そこには「どんなデータを入れていいか」「どんなルールで管理するか」が詰まっています。

たとえば、次のような users テーブルを考えてみましょう。

idnameemailage

この表を作るときに、 「id は必ず一意であるべきだよね」 「email は重複しちゃダメだよね」 「name は空っぽじゃ困るよね」 といったルールを決めていくのが テーブル設計 です。

主キー(PRIMARY KEY) ― 「このレコードは誰なのか」を示す絶対的な番号

主キーは“レコードの身分証明書”

主キーとは、 テーブルの中でレコードを一意に識別するためのカラム のことです。

  • 重複してはいけない
  • NULL(空)であってはいけない
  • テーブルの中で唯一の存在である

つまり、主キーは「この行は誰なのか」を示す絶対的な番号です。

SQLiteでの主キー定義

id INTEGER PRIMARY KEY AUTOINCREMENT

Python+SQLiteで書くとこうなります。

# day64_table_design.py
import sqlite3
from pathlib import Path


def create_users_table(conn: sqlite3.Connection) -> None:
    """
    users テーブルを作成する関数です。
    主キーや制約を含めたテーブル設計の例です。
    """

    print("users テーブルを作成します。")

    sql = """
    CREATE TABLE IF NOT EXISTS users (
        id     INTEGER PRIMARY KEY AUTOINCREMENT,
        name   TEXT NOT NULL,
        email  TEXT NOT NULL UNIQUE,
        age    INTEGER
    );
    """

    cur = conn.cursor()
    cur.execute(sql)
    conn.commit()

    print("users テーブルの作成が完了しました。")
Python

ここで id が主キーです。

  • PRIMARY KEY → 主キー
  • AUTOINCREMENT → 自動で 1, 2, 3… と番号が振られる

主キーは、ほとんどのテーブルに必ず存在します。 データベースの世界では「主キーがないテーブルは危険」と言われるほど重要です。

外部キー(FOREIGN KEY) ― 「別のテーブルとつながるための橋」

外部キーは“テーブル同士をつなぐ橋”

外部キーとは、

別のテーブルの主キーを参照するカラム

のことです。

たとえば、次のような関係を考えてみます。

  • users(ユーザー)
  • orders(注文)

注文は「誰がしたか」を必ず持っていますよね。 その「誰か」を示すのが外部キーです。

外部キーの例

user_id INTEGER,
FOREIGN KEY (user_id) REFERENCES users(id)

Python+SQLiteで書くとこうなります。

def create_orders_table(conn: sqlite3.Connection) -> None:
    """
    orders テーブルを作成する関数です。
    user_id が users.id を参照する外部キーになっています。
    """

    print("orders テーブルを作成します。")

    sql = """
    CREATE TABLE IF NOT EXISTS orders (
        id        INTEGER PRIMARY KEY AUTOINCREMENT,
        user_id   INTEGER NOT NULL,
        product   TEXT NOT NULL,
        price     REAL NOT NULL,
        FOREIGN KEY (user_id) REFERENCES users(id)
    );
    """

    cur = conn.cursor()
    cur.execute(sql)
    conn.commit()

    print("orders テーブルの作成が完了しました。")
Python

外部キーがあると何が嬉しいのか?

  • 「存在しないユーザーの注文」を防げる
  • データの整合性が保たれる
  • テーブル同士の関係が明確になる

外部キーは、データベースの“つながり”を作る大切な仕組みです。

NOT NULL ― 「絶対に空っぽでは困る項目」

NOT NULLは“必須項目”

NOT NULL は、

このカラムは必ず値が入っていなければならない

という制約です。

例:

name TEXT NOT NULL

これは「名前が空っぽのユーザーは登録できない」という意味です。

NOT NULLがあると安心できる理由

  • データの欠損を防げる
  • 必須項目が明確になる
  • 後から「この項目が空で困る」という事故が減る

NOT NULLは、テーブル設計の中でも特に重要な制約です。

UNIQUE ― 「重複してはいけない項目」

UNIQUEは“重複禁止”

UNIQUE は、

このカラムの値は重複してはいけない

という制約です。

例:

email TEXT NOT NULL UNIQUE

これは「同じメールアドレスのユーザーを複数登録してはいけない」という意味です。

UNIQUEが役立つ場面

  • メールアドレス
  • ユーザー名
  • 商品コード
  • 社員番号

「この値は世界にひとつだけ」という項目に使います。

データ型 ― 「どんな種類の値を入れるか」

SQLiteでよく使うデータ型は次の通りです。

データ型説明
INTEGER整数(年齢、IDなど)
REAL小数(価格、スコアなど)
TEXT文字列(名前、メールなど)
BLOBバイナリデータ(画像など)

データ型を正しく選ぶと何が嬉しい?

  • データの意味が明確になる
  • 不正な値が入りにくくなる
  • 検索や集計が高速になる

データ型は「そのカラムが何者なのか」を決める大切な要素です。

テーブル設計の総まとめ ― users+orders の例

最後に、今日の内容を全部盛り込んだ テーブル設計テンプレート を紹介します。

# day64_table_design_template.py
import sqlite3
from pathlib import Path


def create_tables(conn: sqlite3.Connection) -> None:
    """
    users と orders の2つのテーブルを作成するテンプレートです。
    主キー・外部キー・NOT NULL・UNIQUE・データ型をすべて含んでいます。
    """

    sql_users = """
    CREATE TABLE IF NOT EXISTS users (
        id     INTEGER PRIMARY KEY AUTOINCREMENT,
        name   TEXT NOT NULL,
        email  TEXT NOT NULL UNIQUE,
        age    INTEGER
    );
    """

    sql_orders = """
    CREATE TABLE IF NOT EXISTS orders (
        id        INTEGER PRIMARY KEY AUTOINCREMENT,
        user_id   INTEGER NOT NULL,
        product   TEXT NOT NULL,
        price     REAL NOT NULL,
        FOREIGN KEY (user_id) REFERENCES users(id)
    );
    """

    cur = conn.cursor()
    cur.execute(sql_users)
    cur.execute(sql_orders)
    conn.commit()


def main():
    conn = sqlite3.connect(Path("day64_example.db"))
    create_tables(conn)
    conn.close()


if __name__ == "__main__":
    main()
Python

Day 64のまとめ ― テーブル設計は“データの未来”を守る技術

今日扱ったキーワードは、

  • 主キー(PRIMARY KEY):レコードの身分証明書
  • 外部キー(FOREIGN KEY):テーブル同士をつなぐ橋
  • NOT NULL:必須項目
  • UNIQUE:重複禁止
  • データ型:そのカラムが何者なのかを決める

でした。

テーブル設計は、 「今のデータをどう扱うか」ではなく、 「未来のデータがどうあるべきか」 を考える作業です。

しっかり設計されたテーブルは、 後から使う人を助け、 データの整合性を守り、 システム全体を安定させてくれます。

タイトルとURLをコピーしました