💾 データベースとは?
📖 定義
データベース(Database, DB)は体系的に構造化されたデータの集合です。DBMS(Database Management System、データベース管理システム)は、データベースを作成、管理、アクセスするソフトウェアです。データベースはデータを効率的に保存・検索でき、複数のユーザーが同時に安全にアクセスできます。
🎯 比喩で理解する
図書館システム
データベースを図書館に例えると:
- データベース: 図書館全体
- テーブル: 各セクション(小説、科学、歴史など)
- 行(Row): 個別の本
- 列(Column): 本の属性(タイトル、著者、出版年など)
- 主キー(Primary Key): 図書固有番号
- DBMS: 司書と管理システム
図書館 (データベース)
├─ 小説セクション (テーブル)
│ ├─ 本1: ハリーポッター, J.K.ローリング, 1997
│ ├─ 本2: 指輪物語, トールキン, 1954
│ └─ 本3: 星の王子さま, サン=テグジュペリ, 1943
├─ 科学セクション (テーブル)
│ ├─ 本1: コスモス, カール・セーガン, 1980
│ └─ 本2: 利己的な遺伝子, リチャード・ドーキンス, 1976
└─ 貸出記録 (テーブル)
├─ 記録1: 会員123, ハリーポッター, 2024-01-15
└─ 記録2: 会員456, コスモス, 2024-01-20
⚙️ 動作原理
1. データベース構造
データベース (Database)
└─ テーブル (Table)
├─ 行 (Row/Record) - 個別データ項目
│ └─ 例: 一人のユーザー情報
└─ 列 (Column/Field) - データ属性
└─ 例: 名前、メール、年齢
2. リレーショナルデータベースの例
-- usersテーブル
users
┌────┬────────┬──────────────────┬─────┐
│ id │ name │ email │ age │
├────┼────────┼──────────────────┼─────┤
│ 1 │ 山田 │ yamada@mail.com │ 25 │
│ 2 │ 佐藤 │ sato@mail.com │ 30 │
│ 3 │ 鈴木 │ suzuki@mail.com │ 28 │
└────┴────────┴──────────────────┴─────┘
-- ordersテーブル
orders
┌────┬─────────┬─────────────┬───────┐
│ id │ user_id │ product │ price │
├────┼───────── ┼─────────────┼───────┤
│ 1 │ 1 │ ノートPC │ 1500 │
│ 2 │ 1 │ マウス │ 30 │
│ 3 │ 2 │ キーボード │ 80 │
└────┴─────────┴─────────────┴───────┘
↑
└─ 外部キー: usersテーブルのidを参照
3. CRUD操作
CRUDはデータベースの4つの基本操作です:
C - Create (作成): 新しいデータを追加
R - Read (読取): データを照会
U - Update (更新): 既存データを変更
D - Delete (削除): データを削除
💡 実例
SQLでCRUD操作
-- CREATE (作成): テーブル作成
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- CREATE (作成): データ追加
INSERT INTO users (name, email, age)
VALUES ('山田太郎', 'yamada@mail.com', 25);
INSERT INTO users (name, email, age)
VALUES
('佐藤花子', 'sato@mail.com', 30),
('鈴木一郎', 'suzuki@mail.com', 28);
-- READ (読取): 全ユーザー照会
SELECT * FROM users;
-- READ (読取): 条件付き照会
SELECT name, email FROM users
WHERE age >= 28;
-- READ (読取): ソートして照会
SELECT * FROM users
ORDER BY age DESC;
-- READ (読取): 検索
SELECT * FROM users
WHERE name LIKE '山田%';
-- UPDATE (更新): データ変更
UPDATE users
SET age = 26
WHERE name = '山田太郎';
-- UPDATE (更新): 複数フィールド修正
UPDATE users
SET email = 'new@mail.com', age = 31
WHERE id = 2;
-- DELETE (削除): データ削除
DELETE FROM users
WHERE id = 3;
-- DELETE (削除): 条件付き削除
DELETE FROM users
WHERE age < 20;
Node.jsでのデータベース使用
const mysql = require('mysql2/promise');
// データベース接続
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'myapp',
waitForConnections: true,
connectionLimit: 10
});
// CREATE - ユーザー追加
async function createUser(name, email, age) {
const [result] = await pool.execute(
'INSERT INTO users (name, email, age) VALUES (?, ?, ?)',
[name, email, age]
);
console.log('作成されたID:', result.insertId);
return result.insertId;
}
// READ - 全ユーザー取得
async function getAllUsers() {
const [rows] = await pool.execute('SELECT * FROM users');
return rows;
}
// READ - 特定ユーザー取得
async function getUserById(id) {
const [rows] = await pool.execute(
'SELECT * FROM users WHERE id = ?',
[id]
);
return rows[0];
}
// UPDATE - ユーザー情報更新
async function updateUser(id, name, email, age) {
const [result] = await pool.execute(
'UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?',
[name, email, age, id]
);
console.log('更新された行:', result.affectedRows);
return result.affectedRows;
}
// DELETE - ユーザー削除
async function deleteUser(id) {
const [result] = await pool.execute(
'DELETE FROM users WHERE id = ?',
[id]
);
console.log('削除された行:', result.affectedRows);
return result.affectedRows;
}
// 使用例
async function main() {
try {
// 作成
const userId = await createUser('山田太郎', 'yamada@mail.com', 25);
// 照会
const users = await getAllUsers();
console.log('全ユーザー:', users);
// 特定ユーザー照会
const user = await getUserById(userId);
console.log('特定ユーザー:', user);
// 更新
await updateUser(userId, '山田太郎', 'new@mail.com', 26);
// 削除
await deleteUser(userId);
} catch (error) {
console.error('エラー:', error);
}
}
main();
ORM使用 (Sequelize)
const { Sequelize, DataTypes } = require('sequelize');
// データベース接続
const sequelize = new Sequelize('myapp', 'root', 'password', {
host: 'localhost',
dialect: 'mysql'
});
// モデル定義 (テーブル構造)
const User = sequelize.define('User', {
name: {
type: DataTypes.STRING(50),
allowNull: false
},
email: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true
},
age: {
type: DataTypes.INTEGER
}
});
// CRUD操作 (SQLなしでJavaScriptのみ!)
async function ormExample() {
// CREATE - 作成
const user = await User.create({
name: '山田太郎',
email: 'yamada@mail.com',
age: 25
});
console.log('作成:', user.toJSON());
// READ - 照会
const allUsers = await User.findAll();
console.log('全ユーザー:', allUsers);
// READ - 条件照会
const youngUsers = await User.findAll({
where: { age: { [Sequelize.Op.gte]: 20 } },
order: [['age', 'DESC']]
});
// READ - 1つ照会
const oneUser = await User.findOne({
where: { email: 'yamada@mail.com' }
});
// UPDATE - 更新
await User.update(
{ age: 26 },
{ where: { name: '山田太郎' } }
);
// DELETE - 削除
await User.destroy({
where: { id: 1 }
});
}
リレーション設定 (JOIN)
// ユーザーと注文のリレーション設定
const User = sequelize.define('User', {
name: DataTypes.STRING,
email: DataTypes.STRING
});
const Order = sequelize.define('Order', {
product: DataTypes.STRING,
price: DataTypes.DECIMAL(10, 2)
});
// リレーション定義: 1人のユーザーは複数の注文が可能
User.hasMany(Order);
Order.belongsTo(User);
// JOINクエリ
async function getUserWithOrders(userId) {
const userWithOrders = await User.findOne({
where: { id: userId },
include: Order // JOIN
});
console.log(userWithOrders.toJSON());
// {
// id: 1,
// name: '山田太郎',
// email: 'yamada@mail.com',
// Orders: [
// { product: 'ノートPC', price: 1500 },
// { product: 'マウス', price: 30 }
// ]
// }
}
🤔 よくある質問
Q1. データベースを使う理由は?
A: ファイルシステムより多くの利点があります:
❌ ファイルシステム (例: users.txt)
├─ データの重複可能
├─ 同時アクセス問題
├─ バックアップ/復旧困難
├─ セキュリティ脆弱
└─ 検索遅い
✅ データベース
├─ データ整合性保証
├─ 同時実行制御 (複数ユーザー)
├─ バックアップ/復旧自動化
├─ アクセス権限管理
├─ 高速検索 (インデックス)
└─ トランザクションサポート
Q2. どのデータベースを選ぶべき?
A: プロジェクト要件によって異なります:
// リレーショナルデータベース (SQL)
MySQL / PostgreSQL / SQLite
├─ 長所: 正確なデータ構造、トランザクション
├─ 短所: 柔軟性低い、拡張性制限
└─ 適合: 金融、電子商取引、ユーザー管理
// 非リレーショナルデータベース (NoSQL)
MongoDB / Redis / Cassandra
├─ 長所: 柔軟なスキーマ、水平拡張
├─ 短所: 複雑な関係処理困難
└─ 適合: ソーシャルメディア、リアルタイム分析、キャッシング
Q3. インデックス(Index)とは?
A: データ検索速度を向上させるデータ構造です:
-- インデックスなし
SELECT * FROM users WHERE email = 'test@mail.com';
-- → 100万行すべて確認 (遅い)
-- インデックス作成
CREATE INDEX idx_email ON users(email);
-- インデックスあり
SELECT * FROM users WHERE email = 'test@mail.com';
-- → インデックスで直接検索 (速い!)
-- 欠点: データ挿入/更新時にインデックスも 更新 (書込み遅くなる)
比喩: 本の目次や索引のように、欲しい内容を素早く見つけられるようにしてくれます。
Q4. トランザクション(Transaction)とは?
A: 複数の操作を1つの単位としてまとめて処理すること:
// 銀行送金の例
async function transferMoney(fromId, toId, amount) {
const connection = await pool.getConnection();
try {
// トランザクション開始
await connection.beginTransaction();
// 1. 送信者の残高減少
await connection.execute(
'UPDATE accounts SET balance = balance - ? WHERE id = ?',
[amount, fromId]
);
// 2. 受信者の残高増加
await connection.execute(
'UPDATE accounts SET balance = balance + ? WHERE id = ?',
[amount, toId]
);
// すべて成功 → 確定
await connection.commit();
console.log('送金完了!');
} catch (error) {
// エラー発生 → すべてキャンセル
await connection.rollback();
console.log('送金失敗、ロールバック');
throw error;
} finally {
connection.release();
}
}
// ACID原則
// Atomicity (原子性): すべて実行 or すべてキャンセル
// Consistency (一貫性): ルール違反なし
// Isolation (独立性): 他のトランザクションと独立
// Durability (永続性): 完了後永久保存
Q5. SQL Injectionとは?
A: 悪意のあるSQLコードを注入する攻撃です:
// ❌ 危険なコード (SQL Injection脆弱)
const email = req.body.email; // "admin@mail.com' OR '1'='1"
const query = `SELECT * FROM users WHERE email = '${email}'`;
// 実行: SELECT * FROM users WHERE email = 'admin@mail.com' OR '1'='1'
// → 全ユーザー情報漏洩!
// ✅ 安全なコード (Prepared Statement)
const [rows] = await pool.execute(
'SELECT * FROM users WHERE email = ?',
[email] // 自動的にエスケープされる
);
// ORM使用 (自動防御)
const user = await User.findOne({
where: { email: email } // 安全
});
🎓 次のステップ
データベースを理解したら、次を学習してみましょう:
- SQL vs NoSQL - データベース選択ガイド
- Node.jsとは? - バックエンド開発
- APIとは? - データベースとフロントエンドの接続
実習してみる
# MySQL インストールと実行
brew install mysql # macOS
sudo apt install mysql # Linux
# データベース接続
mysql -u root -p
# データベース作成
CREATE DATABASE myapp;
USE myapp;
# テーブル作成とデータ追加
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
email VARCHAR(100)
);
INSERT INTO users (name, email) VALUES ('山田太郎', 'test@mail.com');
SELECT * FROM users;
🎬 まとめ
データベースはすべてのアプリケーションの核心です:
- データベース: 構造化されたデータ集合
- CRUD: 作成、読取、更新、削除 - 基本操作
- テーブル: 行と列でデータを構造化
- リレーション: テーブル間の接続 (JOIN)
- トランザクション: 安全なデータ処理
データベースをよく理解すれば 、安定した拡張可能なアプリケーションを構築できます! 💾✨