はじめに
SQLiteとPostgreSQLをDockerで動かしながら、CLIでのDB操作を学び直したメモです。特に以下の2点にこだわりました。
docker execに頼らず、ホスト側のネイティブCLIクライアントから直接SQLを叩く方法- 普段MySQLを使っている人向けの、コマンド対比表
SQLiteとPostgreSQLはアーキテクチャがまったく違う(ファイル型 vs サーバー型)ので、「docker execを使わない」の意味もそれぞれで変わってきます。その違いも含めてまとめます。
SQLite編
SQLiteはそもそも「サーバー」ではない
MySQLやPostgreSQLと違い、SQLiteは常駐プロセス(デーモン)を持たず、ファイル1個がデータベースそのものです。ポート待受もありません。なので「SQLiteのDockerコンテナ」というのは、正確には「サーバーコンテナ」ではなく「sqlite3コマンドが使えるだけの箱」です。
Docker(学習用の最小構成)
# Dockerfile
FROM alpine:3.20
RUN apk add --no-cache sqlite
WORKDIR /data
CMD ["tail", "-f", "/dev/null"]
# docker-compose.yml
services:
sqlite:
build: .
container_name: sqlite-lab
volumes:
- ./data:/data
restart: unless-stopped
docker compose up -d --build
docker exec経由でSQLを打つならこう。
docker exec -it sqlite-lab sqlite3 /data/app.db
docker execを使わない方法
SQLiteはファイルさえ見えれば良いので、そのファイルパスを指定してホスト側のsqlite3コマンドを直接起動するだけで十分です。中継コマンドは一切不要です。
# バージョン確認(macOSには標準搭載されていることが多い)
which sqlite3 && sqlite3 --version
# 直接起動(ファイルが無ければ新規作成される)
sqlite3 /path/to/app.db
macOS標準のsqlite3が古い場合はHomebrewで最新版を入れられます。
brew install sqlite
# /opt/homebrew/opt/sqlite/bin/sqlite3 にインストールされる
GUIで触りたい場合は「DB Browser for SQLite」が定番です。
brew install --cask db-browser-for-sqlite
open -a "DB Browser for SQLite" /path/to/app.db
ワンライナー・ヒアドキュメント実行
# ワンライナー
sqlite3 /path/to/app.db "SELECT * FROM users;"
# ヒアドキュメント(mysqlと同じ書き方)
sqlite3 /path/to/app.db <<'EOF'
SELECT * FROM users;
.tables
EOF
プロンプトの抜け方
.quit または .exit(Ctrl+Dでも可)。ドット始まりである点に注意(\qではない)。
MySQL ⇔ SQLite 対比表
スキーマ・テーブル閲覧系
| MySQL | SQLite | 補足 |
|---|---|---|
SHOW DATABASES; |
(概念なし。ファイル=DB) | 複数ファイルATTACH時は.databases
|
USE db; |
(概念なし) |
ATTACH DATABASE 'x.db' AS x;で代用可 |
SHOW TABLES; |
.tables |
ビューも一緒に出る |
DESCRIBE table; |
PRAGMA table_info(table); |
列名・型・NOT NULL・PK |
SHOW CREATE TABLE table; |
.schema table |
CREATE文をそのまま出す |
SHOW INDEX FROM table; |
PRAGMA index_list(table); → PRAGMA index_info(idx名);
|
2段階になる |
information_schema.tables等 |
SELECT * FROM sqlite_master; |
全オブジェクトの定義元 |
データ定義(DDL)
| MySQL | SQLite | 補足 |
|---|---|---|
CREATE DATABASE db; |
(概念なし) | 新規ファイル作成で自動的にDBになる |
DROP DATABASE db; |
(概念なし) | ファイルをrmするだけ |
RENAME TABLE old TO new; |
ALTER TABLE old RENAME TO new; |
構文が違うだけ |
ALTER TABLE t ADD COLUMN c ...; |
同じ構文でOK | サポート済み |
TRUNCATE TABLE t; |
DELETE FROM t; |
専用コマンドなし |
実行・出力制御
| MySQL | SQLite | 補足 |
|---|---|---|
EXPLAIN SELECT ...; |
EXPLAIN QUERY PLAN SELECT ...; |
素のEXPLAINはVDBEバイトコードが出る |
SELECT * FROM t \G |
.mode line |
縦表示モード |
mysql -e "SQL" |
sqlite3 file.db "SQL" |
ワンライナー実行 |
source file.sql; |
.read file.sql |
SQLファイル一括実行 |
バックアップ
| MySQL | SQLite | 補足 |
|---|---|---|
mysqldump db > backup.sql |
sqlite3 file.db .dump > backup.sql |
CREATE文+INSERT文が出る |
概念自体が存在しないもの
SQLiteは「サーバー」ではなく「ファイル+ライブラリ」なので、以下はMySQL側の概念ごと存在しません。
-
SHOW PROCESSLIST;(プロセスの概念がない) -
SHOW GRANTS;/GRANT/REVOKE(権限管理はOSのファイルパーミッション任せ) -
SHOW ENGINES;(エンジンは1種類のみ) -
LOCK TABLES ...;(ファイルロックで自動処理)
PostgreSQL編
PostgreSQLは正真正銘のサーバー型DB
SQLiteと違い、PostgreSQLは常駐サーバープロセスがポートを開いて待ち受けます。なので「docker execを使わない」は、コンテナに入らず、ホスト側のネイティブpsqlからネットワーク越しに直接つなぐ、という意味になります。
Docker Composeでのセットアップ
# docker-compose.yml
services:
postgres:
image: postgres:16
container_name: postgres-lab
restart: unless-stopped
environment:
POSTGRES_USER: labuser
POSTGRES_PASSWORD: your_password
POSTGRES_DB: labdb
volumes:
- ./data:/var/lib/postgresql/data
ports:
- "5433:5432"
docker compose up -d
docker exec経由ならこう。
docker exec -it postgres-lab psql -U labuser -d labdb
docker execを使わない方法(ネイティブpsqlで直接接続)
# psqlクライアントの導入(Homebrewのlibpqパッケージに同梱)
brew install libpq
echo 'export PATH="/opt/homebrew/opt/libpq/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
psql --version
コンテナのポートさえホストに公開されていれば(ports: ["5433:5432"])、あとはホスト名とポートを指定してMacのターミナルから直接つなげます。
psql -h myserver -p 5433 -U labuser -d labdb
パスワード入力を求められるので、POSTGRES_PASSWORDで設定した値を入力します。docker execのようにコンテナ内に入る必要は一切ありません。
ワンライナー・ヒアドキュメント実行
# ワンライナー
PGPASSWORD=your_password psql -h myserver -p 5433 -U labuser -d labdb -c "SELECT * FROM users;"
# ヒアドキュメント(mysqlと同じ書き方)
PGPASSWORD=your_password psql -h myserver -p 5433 -U labuser -d labdb <<'EOF'
SELECT * FROM users;
\dt
EOF
-c "SQL"を付けず接続コマンドだけにすると標準入力から流し込まれます。\dtのようなメタコマンドも普通のSQLと混在させられます。<<EOFではなく<<'EOF'(クォート付き)にしているのは、SQL中の$やバッククォートをシェルに展開されないようにするためです。
プロンプトの抜け方
\q(バックスラッシュ始まり)。Ctrl+Dでも可。SQLiteの.quit(ドット始まり)と記法が違うので混同注意です。
MySQL ⇔ PostgreSQL 対比表
スキーマ・テーブル閲覧系
| MySQL | PostgreSQL | 補足 |
|---|---|---|
SHOW DATABASES; |
\l |
psqlのメタコマンド |
USE db; |
\c db |
接続先DBを切り替える |
SHOW TABLES; |
\dt |
|
DESCRIBE table; |
\d table |
列定義・インデックス・制約がまとめて出る |
SHOW CREATE TABLE table; |
\d+ table(簡易) / pg_dump -t table --schema-only(厳密) |
単一コマンドでのCREATE文再現はない |
SHOW INDEX FROM table; |
\di または \d table内のIndexes欄 |
|
information_schema.tables等 |
同じくinformation_schemaが使える |
両者とも標準SQL準拠 |
データ定義(DDL)
| MySQL | PostgreSQL | 補足 |
|---|---|---|
CREATE DATABASE db; |
同じ構文でOK | |
RENAME TABLE old TO new; |
ALTER TABLE old RENAME TO new; |
|
id INT AUTO_INCREMENT PRIMARY KEY |
id SERIAL PRIMARY KEY(またはGENERATED ALWAYS AS IDENTITY) |
自動採番の書き方が違う |
バッククォート `col`
|
ダブルクォート "col"
|
識別子エスケープの記法が違う |
ENGINE=InnoDB ...; |
(該当なし) | ストレージエンジンの概念がない |
実行・出力制御
| MySQL | PostgreSQL | 補足 |
|---|---|---|
EXPLAIN SELECT ...; |
EXPLAIN SELECT ...; |
同じキーワード。実測はEXPLAIN ANALYZE
|
SELECT * FROM t \G |
\x |
拡張表示トグル。一度打つと以後ずっと縦表示 |
mysql -e "SQL" |
psql -c "SQL" |
ワンライナー実行 |
source file.sql; |
\i file.sql |
|
IFNULL(a, b) |
COALESCE(a, b) |
PostgreSQLは標準SQLのCOALESCEのみ |
LIMIT 5,10(省略記法) |
LIMIT 10 OFFSET 5 |
PostgreSQLはこの省略記法がない |
バックアップ
| MySQL | PostgreSQL | 補足 |
|---|---|---|
mysqldump db > backup.sql |
pg_dump db > backup.sql |
|
LOAD DATA INFILE 'file' INTO TABLE t; |
COPY t FROM 'file' (FORMAT csv) / \copy
|
権限・プロセス管理
| MySQL | PostgreSQL | 補足 |
|---|---|---|
SHOW GRANTS; |
\du(ロール一覧) / \dp(テーブル権限) |
|
SHOW PROCESSLIST; |
SELECT * FROM pg_stat_activity; |
|
SHOW VARIABLES; |
SHOW ALL; |
個別ならSHOW パラメータ名;
|
SHOW ENGINES; |
(該当なし) | ストレージエンジンの概念がない |
まとめ
- SQLiteは「ファイル+ライブラリ」、PostgreSQLは「サーバー」という根本的な違いが、CLIクライアントの構え方にそのまま反映される
- SQLiteは
docker execすら不要で、ファイルパスさえ分かればホストのsqlite3で直接触れる - PostgreSQLは
docker execの代わりに、ポートを公開してネイティブpsqlから接続すればよい - どちらもmysqlと同じ感覚でワンライナー実行・ヒアドキュメント実行ができる
- 普段MySQLに慣れている人ほど、対比表で「あれの、これ」がすぐ分かると学習コストが下がる