基礎から学ぶPython入門 90日コース | データベース・Web API - Day 61:SQL基礎

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

Day 61:SQL基礎 ― 「データをしまう箱」をちゃんと理解する

Day 61では、いよいよ データベースSQL の世界に足を踏み入れていきます。 ここまで Python でファイルに保存したり、CSVを書いたりしてきましたが、 「もっと整理された形でデータを管理したい」と感じている方も多いはずです。

今日はその願いを叶えてくれる存在―― データベース / テーブル / レコード / カラム を、 ひとつひとつ丁寧に、感覚でつかめるところまで解説していきます。

データベースとは ― 「たくさんの情報をしまう大きな本棚」

データベースのイメージを言葉でつかむ

まずは、難しい定義よりも「イメージ」からいきましょう。

  • データベース は、 たくさんの情報を整理してしまっておくための「大きな本棚」のようなものです。
  • その本棚の中には、 「顧客情報」「商品情報」「注文履歴」など、 いろいろな種類のデータが、きれいに並べられています。
  • そして、その本棚に対して「この条件に合うデータを出して」「新しいデータを追加して」と 指示を出すための言葉が SQL(エスキューエル) です。

少しだけ真面目に言うと、 データベース(DB) は「構造化されたデータを効率よく保存・検索・更新するためのシステム」です。 でも、今は「ちゃんと片付けられた情報の倉庫」くらいのイメージで十分です。

テーブルとは ― 「本棚の中の一冊のノート」

テーブル=同じ種類のデータを集めた「表」

データベースの中には、テーブル と呼ばれる単位があります。

  • テーブルは、 「同じ種類のデータ」を集めた 表(テーブル) です。
  • たとえば、ユーザー情報なら users テーブル、 商品情報なら products テーブル、といった具合です。
  • Excelのシートを思い浮かべてもらうと近いです。 行と列があって、そこにデータが並んでいますよね。 あれがまさに「テーブル」のイメージです。

テーブルの中身をざっくり図で見る

例えば、ユーザー情報を管理する users テーブルは、こんな感じの表だと思ってください。

idnameemailage
1Tarotaro@example.com25
2Hanakohanako@example.com30
3Kenken@example.com22

この「表」そのものが テーブル です。 そして、この中に出てくる が、次のキーワードにつながっていきます。

レコードとは ― 「表の中の1行ぶんの情報」

レコード=1人ぶん、1件ぶんのデータ

テーブルの中の 1行 を、データベースの世界では レコード と呼びます。

さきほどの users テーブルでいうと、

idnameemailage
1Tarotaro@example.com25

この1行が 1レコード です。

  • 「Taroさんというユーザーの情報」
  • 「id=1 のユーザーの情報」

といった「ひとつのまとまり」が、レコードです。

レコードの感覚をつかむ

レコードは、 「ひとり」「ひとつ」「ひとつの出来事」 を表す単位だと考えると分かりやすいです。

  • 顧客テーブルなら「ひとりの顧客」
  • 商品テーブルなら「ひとつの商品」
  • 注文テーブルなら「ひとつの注文」

それぞれが、1レコードとして保存されていきます。

カラムとは ― 「表の縦の項目、属性の名前」

カラム=「何の情報か」を表す列

テーブルの のことを、データベースでは カラム(列) と呼びます。

さきほどの users テーブルでいうと、

  • id
  • name
  • email
  • age

これらが カラム名 です。

カラムは、 「この列には何の情報が入っているか」 を表すラベルのようなものです。

カラムの役割をイメージする

カラムは、データを「意味のある形」にしてくれます。

  • name カラムがあるから、「これは名前だ」と分かる
  • email カラムがあるから、「これはメールアドレスだ」と分かる
  • age カラムがあるから、「これは年齢だ」と分かる

もしカラムがなかったら、 ただ数字や文字が並んでいるだけで、何が何だか分からなくなってしまいます。

Python+SQLiteで「テーブル・レコード・カラム」を体験してみる

言葉だけだと、どうしてもふわっとしてしまうので、 ここからは Pythonコードで実際にテーブルを作ってみる ところまでやってみましょう。

ここでは、軽量な組み込みデータベース SQLite を使います。 Pythonには標準で sqlite3 モジュールが入っているので、追加インストールなしで試せます。

1. データベースファイルに接続する

# day61_sql_basic.py
import sqlite3
from pathlib import Path


def get_connection(db_name: str = "day61_example.db") -> sqlite3.Connection:
    """
    SQLiteデータベースに接続するための関数です。
    指定したファイルがなければ、新しく作られます。
    """

    db_path = Path(db_name)
    print(f"データベースに接続します: {db_path}")

    # sqlite3.connect() でデータベースファイルに接続します。
    conn = sqlite3.connect(db_path)
    return conn
Python

ここで作られる day61_example.db が、 「データベースファイル」=本棚そのもの だと思ってください。

2. テーブルを作る(CREATE TABLE)

次に、このデータベースの中に users テーブルを作ります。

def create_users_table(conn: sqlite3.Connection) -> None:
    """
    users テーブルを作成する関数です。
    テーブルの「カラム構造」をここで定義します。
    """

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

    # SQL文を文字列として書きます。
    sql = """
    CREATE TABLE IF NOT EXISTS users (
        id   INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT NOT NULL,
        age  INTEGER
    );
    """

    # cursor を使って SQL を実行します。
    cur = conn.cursor()
    cur.execute(sql)
    conn.commit()
    print("users テーブルの作成が完了しました。")
Python

ここで出てきた SQL を、少し分解してみましょう。

  • CREATE TABLE IF NOT EXISTS users
    • users という名前のテーブルを作る
    • すでに存在していたら作らない(エラーを避けるための保険)
  • id INTEGER PRIMARY KEY AUTOINCREMENT
    • id カラムは整数型
    • 主キー(PRIMARY KEY)として、レコードを一意に識別する役割
    • AUTOINCREMENT で、1, 2, 3… と自動で番号が振られる
  • name TEXT NOT NULL
    • name カラムは文字列型
    • NOT NULL で「必ず値が入っていなければならない」と制約をつける
  • email TEXT NOT NULL
    • メールアドレス用の文字列カラム
  • age INTEGER
    • 年齢用の整数カラム(NULLも許可)

この一文で、 「テーブルのカラム構造」=どんな項目を持つ表か を定義しているわけです。

レコードを追加する ― INSERTで「1行ぶんの情報」を入れる

テーブルができたら、次は レコード(行)を追加する 番です。

3. INSERTでユーザーを登録する

def insert_user(conn: sqlite3.Connection, name: str, email: str, age: int | None = None) -> None:
    """
    users テーブルに新しいユーザーを追加する関数です。
    1回の呼び出しで、1レコード(1行)が追加されます。
    """

    print(f"ユーザーを追加します: name={name}, email={email}, age={age}")

    sql = """
    INSERT INTO users (name, email, age)
    VALUES (?, ?, ?);
    """

    cur = conn.cursor()
    # ? プレースホルダに、Python側の値を渡します。
    cur.execute(sql, (name, email, age))
    conn.commit()
    print("ユーザーの追加が完了しました。")
Python

ここでのポイントは、

  • INSERT INTO users (name, email, age)
    • users テーブルの name, email, age カラムに値を入れる、という宣言
  • VALUES (?, ?, ?)
    • ? は「あとで値を差し込む場所」を表すプレースホルダ
  • cur.execute(sql, (name, email, age))
    • Python側の変数を、SQLの ? に安全に埋め込む

この1回の insert_user() 呼び出しが、 「1レコードを追加する」=表に1行増える という動きになります。

レコードを読み出す ― SELECTで「表から探してくる」

追加したレコードは、もちろん 読み出せる 必要があります。

4. SELECTで全ユーザーを取得する

def fetch_all_users(conn: sqlite3.Connection) -> list[tuple]:
    """
    users テーブルから、すべてのユーザーを取得する関数です。
    戻り値は、レコードごとのタプルのリストになります。
    """

    print("users テーブルから全ユーザーを取得します。")

    sql = "SELECT id, name, email, age FROM users;"

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

    rows = cur.fetchall()  # すべての行を取得します。
    print(f"{len(rows)} 件のユーザーを取得しました。")

    for row in rows:
        # row は (id, name, email, age) のタプルです。
        print(f"id={row[0]}, name={row[1]}, email={row[2]}, age={row[3]}")

    return rows
Python

ここでの SQL はとてもシンプルです。

  • SELECT id, name, email, age FROM users;
    • users テーブルから、指定したカラムを全部取り出す
    • 結果は「レコードの集合」として返ってくる

このとき、 1レコード=1行ぶんのタプル として扱われます。

Day 61ミニテンプレート:SQL基礎をひとまとめにしたサンプル

最後に、Day 61の内容をコンパクトにまとめた 「SQL基礎ミニプロジェクト」 を載せておきます。

# day61_sql_mini_project.py
import sqlite3
from pathlib import Path


def get_connection(db_name: str = "day61_example.db") -> sqlite3.Connection:
    db_path = Path(db_name)
    conn = sqlite3.connect(db_path)
    return conn


def create_users_table(conn: sqlite3.Connection) -> None:
    sql = """
    CREATE TABLE IF NOT EXISTS users (
        id   INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT NOT NULL,
        age  INTEGER
    );
    """
    cur = conn.cursor()
    cur.execute(sql)
    conn.commit()


def insert_user(conn: sqlite3.Connection, name: str, email: str, age: int | None = None) -> None:
    sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?);"
    cur = conn.cursor()
    cur.execute(sql, (name, email, age))
    conn.commit()


def fetch_all_users(conn: sqlite3.Connection) -> list[tuple]:
    sql = "SELECT id, name, email, age FROM users;"
    cur = conn.cursor()
    cur.execute(sql)
    rows = cur.fetchall()
    return rows


def main():
    conn = get_connection()
    create_users_table(conn)

    # サンプルユーザーを追加します。
    insert_user(conn, "Taro", "taro@example.com", 25)
    insert_user(conn, "Hanako", "hanako@example.com", 30)
    insert_user(conn, "Ken", "ken@example.com", 22)

    # 追加したユーザーを取得して表示します。
    users = fetch_all_users(conn)
    for u in users:
        print(f"id={u[0]}, name={u[1]}, email={u[2]}, age={u[3]}")

    conn.close()


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

Day 61のまとめ ― 「表の世界」が見えてくると、データがぐっと扱いやすくなる

今日のキーワードは、

  • データベース:たくさんの情報をしまう「本棚」
  • テーブル:同じ種類のデータを集めた「表」
  • レコード:表の中の「1行ぶんの情報」
  • カラム:表の縦の項目、「何の情報か」を表すラベル

そして、Python+SQLiteを使って、

  • テーブルを作る(CREATE TABLE
  • レコードを追加する(INSERT
  • レコードを読み出す(SELECT

という、SQLのいちばん基本的な流れを体験しました。

ここまで来ると、 「データをちゃんと整理してしまっておく」という感覚が、 だいぶ自分の中に根を下ろしてきているはずです。

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