2026年11月7日
2026年11月7日
MySQLのjson_tableで配列データを行に展開する方法
ステップ1: JSON配列のテーブル作成
# JSON形式でユーザーログイン情報を保存するためのテーブルを作成します。
CREATE TABLE user_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
log_data JSON NOT NULL
);
# 以下はサンプルデータを挿入します。
INSERT INTO user_logs (user_id, log_data) VALUES
(1, '{"login_times": [1623456789, 1623456800, 1623456810], "ip_addresses": ["192.168.1.1", "192.168.1.2"]}');
ステップ2: json_tableを使用して配列データを展開
# login_times配列を各ログイン時間としてテーブル形式で展開します。
SELECT
ul.user_id,
lj.login_time
FROM user_logs ul
JOIN JSON_TABLE(
ul.log_data, -- JSONデータの場所
'$.login_times[*]' -- 配列のパス
COLUMNS (
login_time BIGINT PATH '$' -- 配列要素のカラム名とパスを指定します。
)
) lj ON TRUE;
ステップ3: ip_addresses配列も展開
# ip_addresses配列を各IPアドレスとしてテーブル形式で展開します。
SELECT
ul.user_id,
lj.ip_address
FROM user_logs ul
JOIN JSON_TABLE(
ul.log_data, -- JSONデータの場所
'$.ip_addresses[*]' -- 配列のパス
COLUMNS (
ip_address VARCHAR(45) PATH '$' -- 配列要素のカラム名とパスを指定します。
)
) lj ON TRUE;
ステップ4: 検索や更新操作
# ログイン時間で特定のログイン時間を検索します。
SELECT
ul.user_id,
lj.login_time
FROM user_logs ul
JOIN JSON_TABLE(
ul.log_data, -- JSONデータの場所
'$.login_times[*]' -- 配列のパス
COLUMNS (
login_time BIGINT PATH '$' -- 配列要素のカラム名とパスを指定します。
)
) lj ON TRUE
WHERE lj.login_time = 1623456789;
# ログイン時間を更新します。
UPDATE user_logs ul
JOIN JSON_TABLE(
ul.log_data, -- JSONデータの場所
'$.login_times[*]' -- 配列のパス
COLUMNS (
login_time BIGINT PATH '$', -- 配列要素のカラム名とパスを指定します。
old_login_time BIGINT GENERATED ALWAYS AS (1623456789) STORED -- 更新前の値も保持します。
)
) lj ON TRUE
SET ul.log_data = JSON_SET(
ul.log_data, -- JSONデータの場所
'$.login_times[0]', -- パスで指定した配列要素を更新します。
'1623457890' -- 新しい値を設定します。
);
注意事項
- JSONデータの解析はJOINを使用するため、パフォーマンスに影響を与える可能性があります。大量のデータがある場合は十分なテストが必要です。
- json_tableの使用にはMySQL 5.7以降が必要です。旧版では機能が制限されています。
- json_tableは配列要素を個別の行として展開しますが、複数の配列を持つ場合や特定の条件で要素を選択する必要がある場合はJOINを使用しながらさらにフィルタリングを行う必要があります。
まとめ
1. テーブル作成: JSON形式でデータを保存するためのテーブルを作成します。
2. json_tableの使用: json_tableを使ってJSON配列を個別の行に展開し、SQL文で操作します。
3. 検索と更新: 検索や更新を行う際もjson_tableを使用して効率的に処理できます。
関連記事:
- [MySQLでのJSONデータの基本的な操作]
- [パフォーマンスを考慮したMySQLのデータ設計]