データ管理の進化
# 1. プレーンテキストファイル
保存場所やフォーマットに統一性なし
例: user.txt、データ形式: "名前|パスワード"
→ アプリ間での互換性がなく非効率
# 2. 標準化されたディレクトリ構造
ファイル名と保存場所を統一
→ 検索は容易になったが、データ互換性の問題は未解決
# 3. データベースシステム
保存場所とデータ形式を厳密に定義
→ 現在主流。アプリ間互換性と整合性を確保
データ保存の変遷
# 1. 単体保存(オフライン)
各端末に独立して保存 → 共有不可
# 2. サーバー集中型(オンライン)
中央サーバーで一元管理 → ネットワーク必須
※ 安全性向上のため、クラスタ構成でリスク分散
データベースの本質
# C/Sアーキテクチャのソフトウェア
誰でも開発可能だが、既存製品が多数存在
狭義:データ処理エンジン(コアプログラム)
広義:そのエンジンを操作するGUIツール群
※ 学習対象は主に「広義」のツール操作
主要データベース分類
■ RDBMS(関係型)
- MySQL: 無料・オープンソース・普及率No.1
- Oracle: 高セキュリティ・有料
- PostgreSQL: 拡張性に優れる
- MariaDB: MySQLの代替候補
- SQLite: 軽量・Django標準搭載
■ NoSQL(非関係型)
- Redis: 高速キャッシュ・多様なデータ構造
- MongoDB: ドキュメント指向・ビッグデータ向け
- Memcached: Redisにほぼ置き換え済み
▼ 核心差異
RDBMS: 固定スキーマ+テーブル関連
NoSQL: スキーマフリー+キー/バリュー形式
▼ 学習戦略
各カテゴリ代表1つ習得 → 他は応用で習得可能
SQL vs NoSQL
共通目的: データの保存と取得
RDBMS → SQL言語で操作
NoSQL → 各製品固有のクエリ言語で操作
MySQL環境構築
■ 主要バージョン
5.6: 安定版(現行最多)
5.7: 移行期バージョン
8.x: 最新版(機能拡張)
※ バージョン間でSQL文法はほぼ互換
■ インストール手順(Windows)
1. 公式サイトからZIPパッケージダウンロード
2. binフォルダをPATHに追加
3. 管理者権限CMDで mysqld 起動
4. 別CMDで mysql -u root 接続
■ 重要ファイル
bin/ : サーバ(mysqld)とクライアント(mysql)
data/: データ保存領域
my.ini: 設定ファイル(文字コード等)
システムサービス化
# 自動起動設定
mysqld --install # サービス登録
net start mysql # 手動起動
net stop mysql # 停止
mysqld --remove # サービス削除
# サービス確認
services.msc → MySQLサービスを検索
パスワード管理
# 初期設定(rootユーザー)
mysqladmin -u root password '新パスワード'
# 変更方法
SET PASSWORD = PASSWORD('新パスワード');
# 忘れた場合の対処
1. mysqld --skip-grant-tables で起動
2. mysql -u root で接続
3. UPDATE mysql.user SET authentication_string=PASSWORD('新パス') WHERE User='root';
4. FLUSH PRIVILEGES; で権限再読み込み
5. 正常モードで再起動
基本概念
データベース → フォルダ
テーブル → ファイル
レコード → ファイル内の1行
基本SQL文
-- セミコロンで終了必須 --
SHOW DATABASES; -- 全DB表示
USE db_name; -- DB切り替え
SHOW TABLES; -- 現在DBの全テーブル
SELECT * FROM table_name; -- 全データ取得
SELECT * FROM table_name\G; -- 縦表示(大量データ時)
データベース操作
CREATE DATABASE db_name; -- 作成
SHOW CREATE DATABASE db_name; -- 詳細表示
ALTER DATABASE db_name CHARACTER SET utf8; -- 文字コード変更
DROP DATABASE db_name; -- 削除
SELECT DATABASE(); -- 現在DB確認
テーブル操作
-- DB内でのみ実行可能 --
CREATE TABLE t1(id INT, name VARCHAR(50)); -- 作成
SHOW CREATE TABLE t1; -- 構造確認
DESC t1; -- 簡易構造表示
ALTER TABLE t1 RENAME t2; -- 名前変更
ALTER TABLE t1 MODIFY id BIGINT; -- 型変更
DROP TABLE t1; -- 削除
レコード操作
INSERT INTO t1 VALUES (1,'A'),(2,'B'); -- 複数挿入
DELETE FROM t1 WHERE id=1; -- 条件削除
UPDATE t1 SET name='X' WHERE id=1; -- 更新
SELECT * FROM t1 WHERE name LIKE '%A%';-- 検索
文字コード設定
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
ストレージエンジン
SHOW ENGINES; -- 利用可能なエンジン表示
■ 主要エンジン
InnoDB: トランザクション対応(MySQL 5.5+デフォルト)
MyISAM: 高速だがトランザクション非対応
MEMORY: メモリ上に保存(高速だが揮発性)
BLACKHOLE: 書き込み即消失(テスト用)
■ テーブル作成時の指定
CREATE TABLE t1(id INT) ENGINE=InnoDB;
データ型
-- 数値型 --
TINYINT, SMALLINT, INT, BIGINT
UNSIGNED修飾子で符号なし化
-- 浮動小数点 --
FLOAT, DOUBLE, DECIMAL
精度: DECIMAL > DOUBLE > FLOAT
-- 文字列 --
CHAR(10): 固定長(空白埋め)
VARCHAR(10): 可変長(実サイズ保存)
-- 日付型 --
DATE, TIME, DATETIME, TIMESTAMP, YEAR
-- 特殊型 --
ENUM('A','B'): 単一選択
SET('X','Y'): 複数選択可能
制約条件
NOT NULL: NULL禁止
DEFAULT '値': デフォルト値設定
UNIQUE: 重複禁止
PRIMARY KEY: 主キー(NOT NULL + UNIQUE)
AUTO_INCREMENT: 自動採番(主キーと併用)
例:
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL DEFAULT '匿名',
email VARCHAR(100) UNIQUE
);
外部キー制約
-- 表間関係の確立 --
CREATE TABLE departments(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
);
CREATE TABLE employees(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
dept_id INT,
FOREIGN KEY (dept_id) REFERENCES departments(id)
ON UPDATE CASCADE
ON DELETE CASCADE
);
■ 関係タイプ
1対多: 外部キーを「多」側に配置
多対多: 中間テーブルを作成
1対1: 外部キーをどちらかに配置+UNIQUE制約
高度なクエリ
-- 条件検索 --
WHERE age BETWEEN 20 AND 30
WHERE salary IN (5000, 8000, 10000)
WHERE name LIKE '%山%' -- 部分一致
-- 集計関数 --
SELECT dept, AVG(salary) FROM employees GROUP BY dept;
SELECT MAX(salary), MIN(salary) FROM employees;
-- 並び替え --
ORDER BY salary DESC, age ASC
-- ページング --
LIMIT 10 OFFSET 20 -- 21件目から10件
-- 正規表現 --
WHERE name REGEXP '^[A-Z]'
Python連携
import pymysql
conn = pymysql.connect(
host='localhost',
port=3306,
user='root',
password='secret',
database='testdb',
charset='utf8mb4',
autocommit=True
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute("SELECT * FROM users WHERE id=%s", (user_id,))
result = cursor.fetchall()
SQLインジェクション対策
# 危険な例(直接結合)
sql = f"SELECT * FROM users WHERE name='{username}'"
# 安全な例(プレースホルダ使用)
sql = "SELECT * FROM users WHERE name=%s AND pwd=%s"
cursor.execute(sql, (username, password))
# 攻撃例: ' OR 1=1 --
# → プレースホルダ使用で無害化
トランザクション管理
START TRANSACTION;
UPDATE accounts SET balance=balance-100 WHERE id=1;
UPDATE accounts SET balance=balance+100 WHERE id=2;
COMMIT; -- 成功時
ROLLBACK; -- 失敗時
# ACID特性
Atomicity: 全て成功か全て失敗
Consistency: 整合性維持
Isolation: 並行処理時の干渉防止
Durability: コミット後は永続化