データベース

SQLite

概要

SQLiteは、サーバーを必要としないセルフコンテインド型のSQLデータベースエンジンです。単一のファイルでデータベース全体を管理し、非常に軽量でありながら、多くのSQL機能をサポートしています。世界で最も広く普及しているデータベースエンジンの一つです。

詳細

SQLiteは2000年にDwayne Richard Hipp氏によって開発されました。「軽量」という名前とは裏腹に、フル機能のSQLデータベースエンジンであり、ACID特性を完全にサポートしています。サーバープロセスが不要で、アプリケーションに直接組み込まれるため、モバイルアプリケーション、デスクトップアプリケーション、IoTデバイスなどで幅広く使用されています。

SQLiteの主な特徴:

  • ゼロコンフィギュレーション(設定不要)
  • サーバーレス・セルフコンテインド
  • 単一ファイルでのデータベース管理
  • 完全なACID特性サポート
  • クロスプラットフォーム対応
  • 豊富なSQL機能
  • 小さなメモリフットプリント
  • 高い信頼性
  • パブリックドメインライセンス
  • ファイルレベルロック

メリット・デメリット

メリット

  • 軽量性: 非常に小さなフットプリント(数百KB)
  • シンプル: 設定やメンテナンスが不要
  • 高速: 小~中規模データに対する高いパフォーマンス
  • 信頼性: 徹底的にテストされた安定性
  • ポータビリティ: 単一ファイルで完結
  • 無料: パブリックドメインで完全に無料
  • 組み込み: アプリケーションに直接統合可能

デメリット

  • 同時書き込み制限: 同時に一つの書き込みプロセスのみ
  • 大規模データ: 非常に大きなデータベースには不向き
  • ネットワーク: ネットワーク経由でのアクセスに制限
  • ユーザー管理: 組み込み型ユーザー認証機能なし
  • レプリケーション: 組み込み型レプリケーション機能なし

主要リンク

書き方の例

インストール・セットアップ

# Ubuntu/Debian
sudo apt update
sudo apt install sqlite3

# Red Hat/CentOS
sudo yum install sqlite

# macOS (Homebrew)
brew install sqlite

# Windows (Chocolatey)
choco install sqlite

# Python組み込み(標準ライブラリ)
# Pythonインストール時に自動的に利用可能
python3 -c "import sqlite3; print(sqlite3.version)"

基本操作(CRUD)

-- データベース作成・接続
sqlite3 myapp.db

-- テーブル作成
CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- データ挿入(Create)
INSERT INTO users (name, email) VALUES 
('田中太郎', '[email protected]'),
('佐藤花子', '[email protected]');

-- データ読み取り(Read)
SELECT * FROM users;
SELECT * FROM users WHERE name LIKE '田中%';

-- データ更新(Update)
UPDATE users SET email = '[email protected]' 
WHERE name = '田中太郎';

-- データ削除(Delete)
DELETE FROM users WHERE id = 1;

-- データベース情報確認
.tables
.schema users
.exit

データモデリング

-- 外部キー制約(有効化が必要)
PRAGMA foreign_keys = ON;

CREATE TABLE orders (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER,
    amount REAL NOT NULL,
    order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id)
        ON DELETE CASCADE ON UPDATE CASCADE
);

-- インデックス作成
CREATE INDEX idx_user_email ON users(email);
CREATE INDEX idx_order_date ON orders(order_date);

-- ビュー作成
CREATE VIEW user_orders AS
SELECT u.name, u.email, o.amount, o.order_date
FROM users u
INNER JOIN orders o ON u.id = o.user_id;

インデックス・最適化

-- 複合インデックス
CREATE INDEX idx_user_date ON orders(user_id, order_date);

-- 部分インデックス
CREATE INDEX idx_active_users ON users(id) WHERE active = 1;

-- 実行計画の確認
EXPLAIN QUERY PLAN SELECT * FROM users WHERE email = '[email protected]';

-- 統計情報の更新
ANALYZE;

-- データベース整合性チェック
PRAGMA integrity_check;

-- データベース最適化
VACUUM;

実用例

-- JSON型の使用(SQLite 3.45+)
CREATE TABLE products (
    id INTEGER PRIMARY KEY,
    name TEXT,
    attributes JSON
);

INSERT INTO products (name, attributes) VALUES 
('ノートPC', json('{"brand": "Dell", "cpu": "Intel i7", "ram": "16GB"}'));

SELECT * FROM products 
WHERE json_extract(attributes, '$.brand') = 'Dell';

-- トリガー
CREATE TRIGGER update_user_timestamp 
AFTER UPDATE ON users
FOR EACH ROW 
BEGIN
    UPDATE users SET updated_at = CURRENT_TIMESTAMP WHERE id = NEW.id;
END;

-- 全文検索(FTS5)
CREATE VIRTUAL TABLE articles_fts USING fts5(title, content);

INSERT INTO articles_fts VALUES ('SQLite入門', 'SQLiteは軽量なデータベースです');

SELECT * FROM articles_fts WHERE articles_fts MATCH 'SQLite';

ベストプラクティス

-- トランザクション管理
BEGIN TRANSACTION;
INSERT INTO users (name, email) VALUES ('新規ユーザー', '[email protected]');
INSERT INTO orders (user_id, amount) VALUES (last_insert_rowid(), 1000.00);
COMMIT;

-- WALモード設定(同時読み取り改善)
PRAGMA journal_mode = WAL;

-- パフォーマンス設定
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = 10000;
PRAGMA temp_store = MEMORY;

-- データベース設定確認
.dbconfig

-- バックアップ作成
.backup backup.db
-- または
VACUUM INTO 'backup.db';

-- 設定最適化例
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = -1000;  -- 1MB
PRAGMA foreign_keys = ON;
PRAGMA recursive_triggers = ON;

Pythonでの使用例

import sqlite3

# データベース接続
conn = sqlite3.connect('myapp.db')
cursor = conn.cursor()

# テーブル作成
cursor.execute('''
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY,
        name TEXT NOT NULL,
        email TEXT UNIQUE
    )
''')

# データ挿入
cursor.execute('INSERT INTO users (name, email) VALUES (?, ?)', 
               ('田中太郎', '[email protected]'))

# データ読み取り
cursor.execute('SELECT * FROM users WHERE name = ?', ('田中太郎',))
user = cursor.fetchone()
print(user)

# 変更をコミット
conn.commit()

# 接続を閉じる
conn.close()