MySQL完全ガイド
MySQL完全ガイド
Section titled “MySQL完全ガイド”MySQLの実践的な使い方を、実務で使える実装例とベストプラクティスとともに詳しく解説します。
1. MySQLとは
Section titled “1. MySQLとは”MySQLの特徴
Section titled “MySQLの特徴”MySQLは、世界で最も広く使われているオープンソースのリレーショナルデータベース管理システム(RDBMS)です。
MySQLの特徴 ├─ オープンソース(無料) ├─ シンプルで使いやすい ├─ 高速なパフォーマンス ├─ 豊富なドキュメントとコミュニティ └─ 多くのホスティングサービスでサポートなぜMySQLを選ぶのか
Section titled “なぜMySQLを選ぶのか”MySQLを選ぶべき場合:
- シンプルなWebアプリケーション
- 高速な読み書きが必要
- 豊富なサポートが必要
- WordPress、DrupalなどのCMSを使用
MySQLを選ばないべき場合:
- 複雑なデータ型が必要(PostgreSQLの方が適している)
- 標準SQLへの準拠が重要(PostgreSQLの方が適している)
2. MySQLのインストールとセットアップ
Section titled “2. MySQLのインストールとセットアップ”macOSでのインストール
Section titled “macOSでのインストール”# Homebrewを使用brew install mysql
# サービスを開始brew services start mysql
# MySQLに接続mysql -u root -pLinuxでのインストール
Section titled “Linuxでのインストール”# Ubuntu/Debiansudo apt-get updatesudo apt-get install mysql-server
# サービスを開始sudo systemctl start mysqlsudo systemctl enable mysql
# セキュリティ設定sudo mysql_secure_installation
# MySQLに接続sudo mysql -u root -pWindowsでのインストール
Section titled “Windowsでのインストール”- MySQL公式サイトからインストーラーをダウンロード
- インストーラーを実行し、指示に従ってインストール
- MySQL Workbenchまたはコマンドプロンプトから接続
-- データベースの作成CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- ユーザーの作成CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword';
-- 権限の付与GRANT ALL PRIVILEGES ON myapp.* TO 'myuser'@'localhost';FLUSH PRIVILEGES;
-- データベースの選択USE myapp;3. ストレージエンジン
Section titled “3. ストレージエンジン”InnoDB(推奨)
Section titled “InnoDB(推奨)”-- InnoDBテーブルの作成CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB;
-- InnoDBの特徴-- - トランザクション対応-- - 外部キー制約対応-- - 行レベルロック-- - クラスタードインデックスMyISAM
Section titled “MyISAM”-- MyISAMテーブルの作成CREATE TABLE logs ( id INT AUTO_INCREMENT PRIMARY KEY, message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=MyISAM;
-- MyISAMの特徴-- - 高速な読み取り-- - フルテキストインデックス-- - テーブルレベルロック-- - トランザクション非対応ストレージエンジンの比較
Section titled “ストレージエンジンの比較”| 特徴 | InnoDB | MyISAM |
|---|---|---|
| トランザクション | 対応 | 非対応 |
| 外部キー | 対応 | 非対応 |
| ロック | 行レベル | テーブルレベル |
| クラッシュリカバリ | 対応 | 限定的 |
| フルテキストインデックス | 対応(MySQL 5.6以降) | 対応 |
| 使用例 | 一般的なアプリケーション | 読み取り専用、ログ |
4. インデックスの最適化
Section titled “4. インデックスの最適化”基本的なインデックス
Section titled “基本的なインデックス”-- 単一カラムインデックスCREATE INDEX idx_users_email ON users(email);
-- 複合インデックスCREATE INDEX idx_orders_user_date ON orders(user_id, order_date);
-- ユニークインデックスCREATE UNIQUE INDEX idx_users_email_unique ON users(email);
-- フルテキストインデックス(MyISAMまたはInnoDB)CREATE FULLTEXT INDEX idx_articles_content ON articles(content);インデックスの確認
Section titled “インデックスの確認”-- テーブルのインデックスを確認SHOW INDEX FROM users;
-- インデックスの使用状況を確認EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';
-- 使用されていないインデックスの確認SELECT TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX, COLUMN_NAMEFROM information_schema.STATISTICSWHERE TABLE_SCHEMA = 'myapp'AND INDEX_NAME != 'PRIMARY'AND CARDINALITY = 0;5. パーティショニング
Section titled “5. パーティショニング”範囲パーティショニング(Range Partitioning)
Section titled “範囲パーティショニング(Range Partitioning)”-- パーティショニングテーブルの作成CREATE TABLE orders ( id INT AUTO_INCREMENT, user_id INT NOT NULL, order_date DATE NOT NULL, amount DECIMAL(10, 2) NOT NULL, PRIMARY KEY (id, order_date)) PARTITION BY RANGE (YEAR(order_date)) ( PARTITION p2022 VALUES LESS THAN (2023), PARTITION p2023 VALUES LESS THAN (2024), PARTITION p2024 VALUES LESS THAN (2025), PARTITION p_future VALUES LESS THAN MAXVALUE);
-- パーティションの追加ALTER TABLE orders ADD PARTITION ( PARTITION p2025 VALUES LESS THAN (2026));
-- パーティションの削除ALTER TABLE orders DROP PARTITION p2022;ハッシュパーティショニング(Hash Partitioning)
Section titled “ハッシュパーティショニング(Hash Partitioning)”-- ハッシュパーティショニングテーブルの作成CREATE TABLE products ( id INT AUTO_INCREMENT, name VARCHAR(255) NOT NULL, category_id INT NOT NULL, price DECIMAL(10, 2) NOT NULL, PRIMARY KEY (id, category_id)) PARTITION BY HASH(category_id) PARTITIONS 4;リストパーティショニング(List Partitioning)
Section titled “リストパーティショニング(List Partitioning)”-- リストパーティショニングテーブルの作成CREATE TABLE users ( id INT AUTO_INCREMENT, name VARCHAR(255) NOT NULL, country VARCHAR(2) NOT NULL, email VARCHAR(255) NOT NULL, PRIMARY KEY (id, country)) PARTITION BY LIST (country) ( PARTITION p_jp VALUES IN ('JP'), PARTITION p_us VALUES IN ('US'), PARTITION p_uk VALUES IN ('UK'), PARTITION p_other VALUES IN (DEFAULT));6. レプリケーション
Section titled “6. レプリケーション”マスター・スレーブレプリケーション
Section titled “マスター・スレーブレプリケーション”-- マスターサーバーの設定(my.cnf)[mysqld]server-id = 1log-bin = mysql-binbinlog-format = ROW
-- レプリケーション用ユーザーの作成CREATE USER 'replicator'@'%' IDENTIFIED BY 'replicator_password';GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';FLUSH PRIVILEGES;
-- マスターの状態を確認SHOW MASTER STATUS;-- スレーブサーバーの設定(my.cnf)[mysqld]server-id = 2relay-log = mysql-relay-binread-only = 1
-- スレーブの設定CHANGE MASTER TO MASTER_HOST='master_host', MASTER_USER='replicator', MASTER_PASSWORD='replicator_password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154;
-- スレーブの開始START SLAVE;
-- スレーブの状態を確認SHOW SLAVE STATUS\Gマスター・マスターレプリケーション
Section titled “マスター・マスターレプリケーション”-- 両方のサーバーで設定[mysqld]server-id = 1 # サーバー1log-bin = mysql-binbinlog-format = ROWauto-increment-offset = 1auto-increment-increment = 2
[mysqld]server-id = 2 # サーバー2log-bin = mysql-binbinlog-format = ROWauto-increment-offset = 2auto-increment-increment = 27. パフォーマンス最適化
Section titled “7. パフォーマンス最適化”EXPLAINの使用
Section titled “EXPLAINの使用”-- クエリプランの確認EXPLAIN SELECT u.name, COUNT(o.id) AS order_countFROM users uLEFT JOIN orders o ON u.id = o.user_idWHERE u.created_at > '2024-01-01'GROUP BY u.id, u.nameORDER BY order_count DESCLIMIT 10;
-- EXPLAINの結果の見方-- type: ALL(全テーブルスキャン)は避ける-- key: 使用されているインデックス-- rows: スキャンされる行数クエリキャッシュ(MySQL 5.7以前)
Section titled “クエリキャッシュ(MySQL 5.7以前)”-- クエリキャッシュの設定(my.cnf)query_cache_type = 1query_cache_size = 64M
-- クエリキャッシュの確認SHOW VARIABLES LIKE 'query_cache%';注意: MySQL 8.0ではクエリキャッシュが削除されました。
-- 最大接続数の設定(my.cnf)max_connections = 200
-- 現在の接続数を確認SHOW STATUS LIKE 'Threads_connected';
-- 接続プールの使用を推奨(HikariCP、C3P0など)8. トランザクションとロック
Section titled “8. トランザクションとロック”トランザクションの分離レベル
Section titled “トランザクションの分離レベル”-- 分離レベルの設定SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 分離レベルの確認SELECT @@transaction_isolation;
-- トランザクションの開始START TRANSACTION;INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');COMMIT;ロックの種類
Section titled “ロックの種類”-- 行レベルロック(InnoDB)START TRANSACTION;SELECT * FROM users WHERE id = 1 FOR UPDATE;-- 他のトランザクションはこの行を更新できないUPDATE users SET name = 'New Name' WHERE id = 1;COMMIT;
-- 共有ロックSTART TRANSACTION;SELECT * FROM users WHERE id = 1 LOCK IN SHARE MODE;COMMIT;
-- テーブルロック(MyISAM)LOCK TABLES users READ;SELECT * FROM users;UNLOCK TABLES;9. バックアップとリストア
Section titled “9. バックアップとリストア”mysqldumpによるバックアップ
Section titled “mysqldumpによるバックアップ”# データベース全体のバックアップmysqldump -u root -p myapp > backup.sql
# 特定のテーブルのみのバックアップmysqldump -u root -p myapp users orders > tables.sql
# スキーマのみのバックアップmysqldump -u root -p --no-data myapp > schema.sql
# データのみのバックアップmysqldump -u root -p --no-create-info myapp > data.sql
# 圧縮してバックアップmysqldump -u root -p myapp | gzip > backup.sql.gzmysqlによるリストア
Section titled “mysqlによるリストア”# SQLファイルからのリストアmysql -u root -p myapp < backup.sql
# 圧縮ファイルからのリストアgunzip < backup.sql.gz | mysql -u root -p myappバイナリログによるポイントインタイムリカバリ
Section titled “バイナリログによるポイントインタイムリカバリ”-- バイナリログの有効化(my.cnf)[mysqld]log-bin = mysql-binbinlog-format = ROW
-- バイナリログの確認SHOW BINARY LOGS;
-- 特定の時点へのリカバリmysqlbinlog --start-datetime="2024-01-01 00:00:00" \ --stop-datetime="2024-01-02 00:00:00" \ mysql-bin.000001 | mysql -u root -p myapp10. セキュリティ
Section titled “10. セキュリティ”ユーザーと権限の管理
Section titled “ユーザーと権限の管理”-- ユーザーの作成CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'secure_password';
-- 権限の付与GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'app_user'@'localhost';FLUSH PRIVILEGES;
-- 権限の確認SHOW GRANTS FOR 'app_user'@'localhost';
-- 権限の取り消しREVOKE DELETE ON myapp.* FROM 'app_user'@'localhost';FLUSH PRIVILEGES;-- SSL接続の要求CREATE USER 'secure_user'@'%' IDENTIFIED BY 'password' REQUIRE SSL;
-- SSL証明書の確認SHOW STATUS LIKE 'Ssl%';11. 文字セットと照合順序
Section titled “11. 文字セットと照合順序”UTF8MB4の使用(推奨)
Section titled “UTF8MB4の使用(推奨)”-- データベースの文字セット設定CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- テーブルの文字セット設定CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci, email VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 接続時の文字セット設定SET NAMES utf8mb4;UTF8MB4 vs UTF8:
- UTF8: 最大3バイト、絵文字をサポートしない
- UTF8MB4: 最大4バイト、絵文字を完全サポート(推奨)
12. 実践的なベストプラクティス
Section titled “12. 実践的なベストプラクティス”-- テーブル名: 複数形、スネークケースCREATE TABLE user_profiles (...);
-- カラム名: スネークケースCREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
-- インデックス名: idx_テーブル名_カラム名CREATE INDEX idx_users_email ON users(email);マイグレーション管理
Section titled “マイグレーション管理”-- バージョン管理テーブルの作成CREATE TABLE schema_migrations ( version VARCHAR(255) PRIMARY KEY, applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP) ENGINE=InnoDB;
-- マイグレーションの適用START TRANSACTION;-- マイグレーションSQLINSERT INTO schema_migrations (version) VALUES ('001_create_users');COMMIT;-- スロークエリのログ設定(my.cnf)slow_query_log = 1slow_query_log_file = /var/log/mysql/slow.loglong_query_time = 1
-- 接続数の確認SHOW STATUS LIKE 'Threads_connected';
-- データベースサイズの確認SELECT table_schema AS 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'FROM information_schema.tablesWHERE table_schema = 'myapp'GROUP BY table_schema;
-- テーブルサイズの確認SELECT table_name AS 'Table', ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'FROM information_schema.tablesWHERE table_schema = 'myapp'ORDER BY (data_length + index_length) DESC;13. よくある問題と解決方法
Section titled “13. よくある問題と解決方法”問題1: 接続数が上限に達している
Section titled “問題1: 接続数が上限に達している”-- 接続数の確認SHOW STATUS LIKE 'Threads_connected';SHOW VARIABLES LIKE 'max_connections';
-- 接続プールの使用を推奨問題2: ディスク容量不足
Section titled “問題2: ディスク容量不足”-- データベースサイズの確認SELECT table_schema, ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'FROM information_schema.tablesGROUP BY table_schema;
-- 不要なデータの削除と最適化DELETE FROM old_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR);OPTIMIZE TABLE old_logs;問題3: クエリが遅い
Section titled “問題3: クエリが遅い”-- スロークエリの確認SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;
-- インデックスの確認SHOW INDEX FROM users;
-- クエリプランの確認EXPLAIN SELECT * FROM users WHERE email = 'user@example.com';問題4: デッドロック
Section titled “問題4: デッドロック”-- デッドロックの確認SHOW ENGINE INNODB STATUS;
-- デッドロックの回避-- - トランザクションを短くする-- - 同じ順序でロックを取得する-- - インデックスを適切に使用するMySQL完全ガイドのポイント:
- ストレージエンジン: InnoDB(推奨)とMyISAMの使い分け
- インデックス最適化: パフォーマンスの向上
- パーティショニング: 大規模データの効率的な管理
- レプリケーション: 高可用性の実現
- パフォーマンス最適化: EXPLAIN、クエリ最適化
- セキュリティ: ユーザー管理、SSL接続
- バックアップ: データ保護、ポイントインタイムリカバリ
- 文字セット: UTF8MB4の使用(推奨)
適切なMySQLの使用により、高速で信頼性の高いアプリケーションを構築できます。