データ補正自動化システム企画の背景
どんなに完璧なシステムを作ろうとしても、
アップデートを重ねている生きているシステムなら、
なんだかんだでデータ補正は必要になりますよね。
- システムだけでは制御しきれないデータ不整合
- その不整合を直すための補正作業
- リリース時などのイレギュラー対応
皆様は、こういったデータ補正をどのように行っていますか?
Kintone → S3 → EventBridge → SQS FIFO → Step Functions → Fargate(Java) → Kintone
手動SQL実行の怖さ
ざっくりですが、
私の部署では下記フローでデータ補正を行なっています。
1. 申請者がクエリを書いて依頼
2. 実行者がレビュー
3. 二人で確認してから実行(Rollback→Commit)
ただ、実行部分は手動です。どんなに気をつけていても...
1. SSMSを開いて本番DBに接続
2. SELECTで対象データを確認
3. 二人で確認「OK、これで合ってるね」
4. UPDATEを実行... ドキドキ...
5. 「あ、WHERE句コピーし忘れた」 ← 全件UPDATE
最後の行、笑えないですよね。二人で確認しても、実行時のミスは防げません。
時にはシステム障害も起こるものです。
実際に起きうるリスクを表にまとめてみました。
| リスク | 発生確率 | 影響度 |
|---|---|---|
| WHERE句の書き忘れ | 中 | 致命的 |
| 本番/検証環境の取り違え | 中 | 致命的 |
| トランザクション忘れ | 高 | 大 |
| 作業ログも手動でしか残せない | 確実 | 中 |
| 誰が何をしたか不明 | 確実 | 中 |
皆様の現場でも、ヒヤリハットはあるのではないでしょうか。
工数問題も深刻
単純なUPDATE 1件でも、二人体制でちゃんとやると意外と時間がかかります。
【申請者】
1. 依頼内容の確認・ヒアリング 20分
2. 対象データの調査(SELECT) 15分
3. SQL文の作成 10分
4. 実行者への依頼 5分
【実行者】
5. レビュー・確認 15分
6. 申請者と一緒に最終確認 10分
7. 本番接続・実行 10分
8. 実行結果の確認・報告 5分
─────────────────────────────────────
合計: 約1.5時間(申請者 + 実行者の合計工数)
1日に30件あったら? → 組織全体的に考えたら最低45時間は消えます
しかも、実行者は「他の人の依頼で手を止められる」ストレスがあります。
解決策:既存の運用フローをシステム化
手動実行の問題点
ペア作業の仕組みがあっても、実行が手動だと以下の問題が残ります。
- 確認したはずなのにWHERE句を忘れて実行してしまう
- 検証環境で確認したつもりが本番だった
- 実行ログが残らない(誰が何を実行したか後から追えない)
- 二人で確認する工数がかかる
ポイント
「申請→承認→ドライラン→実行」の流れはそのまま、実行部分だけを自動化する
これを実現するために、Kintone + AWSの構成を選びました。

なぜKintoneとAWSか?
データ補正自動化の実現方法は色々あります。
専用ツールを導入する、内製でWebアプリを作る...選択肢を挙げればキリがありません。
ただ、新しいツールを導入すると、契約・学習・運用のコストがかかります。
そこで、社内ですでに利用中の外部製品を活用することにしました。
| 製品 | 社内での利用状況 |
|---|---|
| Kintone | ワークフローツールとして導入済み |
| AWS | S3、Lambdaなどすでに全チームで利用中 |
追加の契約や環境構築なしで始められるのが大きなメリットです。
自動化後の流れ
Kintoneのワークフロー機能を使って、以下の流れを目指しました。
ポイントはドライラン(試し実行)の仕組みです。
いきなりCommitせず、まずRollbackで結果を確認してから本実行します。
a. テンプレートクエリの場合
📥 事業部メンバーの申請(実行時間指定可)
⬇
👤 事業部承認者 + 上長の承認①
⬇
♻️ Rollback実行・結果通知 ← ドライラン
⬇
👤 事業部承認者 + 上長の承認②(結果確認)
⬇
✅ Commit実行・結果通知 ← 本実行
b. 自由クエリの場合
📥 開発メンバーの申請(実行時間・優先度指定)
⬇
👤 開発承認者の承認①
⬇
♻️ Rollback実行・結果通知 ← ドライラン
⬇
👤 開発承認者の承認②(結果確認)
⬇
✅ Commit実行・結果通知 ← 本実行
この仕組みにより、「実行してみたら想定と違った」を防げます。
Rollbackで結果を見て、問題なければCommit。問題があれば差し戻し。
実は手動実行でも同じルール(Rollback→Commit)で運用しています。
ただ、手動だとこのフローを守るのも人の意識次第になってしまいます。
システム化することで、ドライランを必ず通る仕組みにできるのがポイントです。
2種類のクエリパターンを用意
データ補正には、定型的なものとイレギュラーなものがあります。
そこで、2種類のパターンを用意しました。
パターン1: テンプレートクエリ(定型業務向け)
よくある補正パターンをテンプレート化しました。
ポイント:
- Kintoneはパラメータを渡すだけ
- SQLファイルはバッチサーバー側でGit管理
- 新しいテンプレート追加時は、改修不要でSQLファイルを追加するだけ
- 1時間に1回まとめて実行(Kintone API節約のため)
-- マスタ登録用テンプレート
-- パラメータ: CategoryID, ItemID, Rate
-- 実行前確認(Confirm Query)
SELECT * FROM ItemMapping
WHERE CategoryID = CAST(JSON_VALUE('{{.Parameters}}', '$.CategoryID') AS INT)
-- 本処理
INSERT INTO ItemMapping (CategoryID, ItemID, Rate)
VALUES (
CAST(JSON_VALUE('{{.Parameters}}', '$.CategoryID') AS INT),
CAST(JSON_VALUE('{{.Parameters}}', '$.ItemID') AS INT),
CAST(JSON_VALUE('{{.Parameters}}', '$.Rate') AS DECIMAL(5,2))
)
-- 実行後確認(Confirm Query)
SELECT * FROM ItemMapping
WHERE CategoryID = CAST(JSON_VALUE('{{.Parameters}}', '$.CategoryID') AS INT)
Kintone側では、こんなJSONを入力するだけです。
{
"CategoryID": "123",
"ItemID": "456",
"Rate": "0.15"
}
パラメータを入れるだけで、安全にSQLが実行されます。
WHERE句を書き忘れる心配もありません。
パターン2: 自由クエリ(イレギュラー対応向け)
テンプレート化できない補正用には、自由クエリを用意しました。
ポイント:
- Kintone申請時にSQL文を直接記載
-
rollback/commitはバッチ側で制御(クエリには書かない)
→ 手動運用でのトランザクション開きっぱなしリスクを解消 - 実行時間の指定が可能(指定時間より前には実行されない)
- 実行優先度も指定可能
- 緊急時はタスクスケジューラから即時実行も可能
-- カスタムSQL実行用テンプレート
{{.CustomSQL}}
Kintone側では、SQL文そのものを入力します。
{
"customSQL": "UPDATE Users SET Status = 'ACTIVE' WHERE UserCode = 'USR001' AND Status = 'PENDING'"
}
こちらは承認フローでしっかりレビューしてもらう運用です。
2つのパターンの使い分け
| 項目 | テンプレートクエリ | 自由クエリ |
|---|---|---|
| 用途 | 定型業務(マスタ登録等) | イレギュラー・リリース対応 |
| 入力 | パラメータのみ | SQL文そのもの |
| 安全性 | 高(SQL固定) | 中(レビュー必須) |
| 柔軟性 | 低 | 高 |
| 承認 | 簡易 | 厳格 |
期待される効果
このシステムで、以下の改善が期待できます。
Before(手動SQL実行):
├── WHERE句忘れのリスク → After: テンプレートで防止
├── 環境取り違えリスク → After: 設定で制御
├── 作業ログなし → After: 全履歴DB記録
├── 誰が何をしたか不明 → After: Kintoneで追跡可能
├── 承認なしで実行可能 → After: ワークフロー必須
└── 工数: 1件1時間〜 → After: 申請5分、あとは自動
AWS構成の検討
Kintone + AWSで実現するにあたり、いくつかの構成案を検討しました。
構成検討にあたり下記2つの条件がありまして
・着手可能な開発メンバーは私1人
・リリース後には他のチームに運用を引き継ぐ
案1: EKS + SQS + Java
他部署で稼働中の構成をそのまま採用する案です。
Kintone → S3 → SQS → EKS (Java Pod / CronJob)
案2: Lambda + Java
サーバーレスでシンプルに。
案3: Step Functions + Fargate + Java
AWSマネージドサービスを最大限活用する案です。
結論から言うと、案3を採用しました。
その理由を説明します。

なぜEKS案を見送ったか
他部署と同じ構成なら、ノウハウも共有できて良さそうですよね。
しかし、よく検討した結果、見送ることにしました。
構成図
┌─────────┐ ┌─────────┐ ┌─────────────────────┐
│ Kintone │ ──→ │ S3 │ ──→ │ SQS │
└─────────┘ └─────────┘ └─────────────────────┘
│
↓
┌─────────────────────┐
│ EKS │
│ ┌───────────────┐ │
│ │ Java Pod │ │
│ │ (CronJob) │ │
│ └───────────────┘ │
└─────────────────────┘
問題点1: Kubernetes知識の引き継ぎが必要
EKSを運用するには、以下の知識が必要です。
- Pod、Deployment、Service、CronJob
- kubectl操作
- マニフェストファイル(YAML地獄)
- リソース管理(requests/limits)
また、下記のようなYAMLを理解・保守する必要があります。
apiVersion: batch/v1
kind: CronJob
metadata:
name: data-update-job
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: batch
image: xxx.dkr.ecr.ap-northeast-1.amazonaws.com/batch:latest
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
restartPolicy: OnFailure
これではK8sの知識が必要になってしまいます。
このままリリースしては、きっと保守対応が属人化してしまい、
全部署からの運用変更依頼に追われる身になってしまいます。
問題点2: 開発工数が大きい
| フェーズ | 工数 |
|---|---|
| 設計 | 5人日 |
| インフラ構築(EKS/SQS/CI/CD) | 10人日 |
| Java実装 | 35〜45人日 |
| テスト | 10〜15人日 |
| 移行 | 5人日 |
| 合計 | 65〜80人日(3〜4ヶ月) |
さすがに重いです。1人ではきついです。
問題点3: 自前実装が多い
EKS案でも、以下は全て自前実装が必要です。
| 機能 | 実装方法 |
|---|---|
| キュー管理 | SQS + 自前ポーリング |
| 排他制御 | 自前実装 |
| リトライ | 自前実装 |
| ワークフロー管理 | なし(コードで制御) |
インフラは既存流用できても、コードは全部書き直しです。
結局、コードも仕組みも複雑なままでは、誰も引き継いでくれません。
なぜLambdaを見送ったか
次に検討したのがLambdaです。
サーバーレスでシンプル、良さそうですよね。
15分タイムアウト問題
Lambdaの最大実行時間は15分です。
データ補正の運用についていろんなチームにヒアリングしましたが、
あるチームから
「重いクエリは20分以上かかるものも...」
はい、終了です。
コスト比較も意外な結果に
「Lambdaは安い」というイメージがありますが、
実際に試算してみると意外な結果になりました。
前提条件
- 1回の処理: 平均10分
- 1日の実行回数: 50回
- メモリ: 1GB
Lambda
月間実行時間 = 10分 × 50回 × 30日 = 15,000分 = 250時間
Lambdaコスト = 250時間 × 60秒 × $0.0000166667/GB-秒 × 1GB
≒ $15/月 (約2,250円)
※ただし15分超えたら動かない
Fargate(タスク実行時のみ課金)
月間実行時間 = 250時間
Fargateコスト(0.25vCPU, 0.5GB) ≒ $7〜10/月 (約1,000〜1,500円)
※タイムアウトなし
Fargateの方が安くて制限もないという結果でした。
Lambdaの方が安いパターンは一瞬で実行終了するコードに限る話でした。
採用案:95%ノーコード構成
そこでたどり着いたのが、Step Functions + Fargate + Java の構成です。
アーキテクチャ
Kintone
│
↓ (JavaScript カスタマイズ - 既存流用)
┌─────┐
│ S3 │ ← ノーコード(既存)
└─────┘
↓
┌─────────────┐
│ EventBridge │ ← ノーコード(S3イベント→SQSへルーティング)
└─────────────┘
↓
┌───────────┐
│ SQS FIFO │ ← ノーコード(排他制御・二重実行防止が自動)
└───────────┘
↓
┌─────────────────┐
│ Step Functions │ ← ローコード(Workflow Studio GUIで設計)
└─────────────────┘
↓
┌─────────────┐
│ Fargate │ ← 設定はノーコード
│ ┌─────────┐ │
│ │ Java │ │ ← コード(ここだけ!)
│ └─────────┘ │
└─────────────┘
│
↓
Kintone (結果通知)
なぜ「95%ノーコード」と言えるのか
各レイヤーの設定方法を見てみましょう。
| レイヤー | 設定方法 | 備考 |
|---|---|---|
| S3 | ノーコード | ファイル保存 |
| EventBridge | ノーコード | イベント検知・ルーティング |
| SQS FIFO | ノーコード | 排他制御・順序保証が自動 |
| Step Functions | GUI設定 | リトライ・分岐がGUIで設定可能 |
| Fargate(設定) | ノーコード | コンテナ実行環境 |
| Java(処理) | コード | ビジネスロジックのみ |
コードを書くのはJavaのビジネスロジック部分(約500行)だけです。
排他制御、リトライ、キュー管理...これらは全てAWSに任せられます。
95%ノーコード案のメリット
この構成の良いところをご紹介します。
メリット1: 排他制御がAWS任せ
排他制御を自前で実装しようとすると、DBロックやステータス管理など数百行のコードが必要になります。
この構成では、SQS FIFOが自動で排他制御してくれます。
SQS FIFOの機能:
├── Visibility Timeout → 処理中は他から見えない
├── FIFO順序保証 → MessageGroupIdで制御
├── 重複排除 → 5分間の重複を自動排除
└── 全部コンソールでポチポチ設定するだけ
コードを書かずに、設定画面のポチポチで済みます。
メリット2: リトライがGUI設定
リトライ処理を自前で実装すると、エラー判定やカウント管理が必要になります。
Step Functionsでは、こんな設定をGUIで入れるだけです。
{
"Retry": [
{
"ErrorEquals": ["States.ALL"],
"IntervalSeconds": 3,
"MaxAttempts": 3,
"BackoffRate": 2
}
]
}
しかもこれ、Workflow StudioでGUIポチポチで設定できます。
メリット3: ワークフローが可視化される
Step Functionsでは、処理の流れが視覚的に見えます。
┌─────────┐
│ 開始 │
└────┬────┘
↓
┌─────────┐
│ SQSから │
│ 取得 │
└────┬────┘
↓
┌─────────┐
│ Fargate │ ← 実行状況がリアルタイムで見える
│ 実行 │
└────┬────┘
↓
┌─────────┐ ┌─────────┐
│ 成功? │ ──→ │ リトライ │
└────┬────┘ └─────────┘
↓
┌─────────┐
│ 完了 │
└─────────┘
エラーが起きたとき、どこで失敗したかわかりやすいです。
これは障害対応のときに非常に助かります。
メリット4: コード量が少ない
排他制御、リトライ、キュー管理...これらをAWSに任せることで、
Javaで書くのはSQL実行ロジックだけになります。
コード量が少なければ、保守も引き継ぎも楽になりますよね。
Javaで実装する部分(5%のみ)
Javaで書くのは、純粋なSQL実行ロジックだけです。
Javaで実装する処理:
├── S3からファイル取得
├── ファイル名パース(メタデータ抽出)
├── SQLテンプレート処理
├── DB実行(Rollback/Commit制御)
└── Kintone通知
排他制御、リトライ、キュー管理はコードに書きません。
全てAWSに任せます。
だからこそ、約500行程度のシンプルなコードで済みます。(Claude予測)
工数・コスト比較
最後に、各案の比較をまとめます。
開発工数
| 案 | 工数 | 引き継ぎ(属人化回避) |
|---|---|---|
| EKS + SQS + Java | 65〜80人日 | 大変 |
| 95%ノーコード案 | 25〜32人日 | 簡単 |
月額コスト(1日平均35件処理の場合)
| 項目 | EKS案 | 95%ノーコード案 |
|---|---|---|
| コントロールプレーン | 約$73(EKS固定費) | $0 |
| コンピュート | 〜数千円 | 〜数百円(Fargate) |
| キュー・イベント | 〜数十円(SQS) | 〜数十円(SQS+Step Functions) |
| その他 | 〜数百円 | 〜数十円 |
| 合計 | 〜1.5万円 | 〜数百円 |
EKSはコントロールプレーンだけで月$73(約1万円)かかります。
95%ノーコード案は実行時間のみ課金なので、この規模だと数百円で済みます。
機能比較
| 機能 | EKS案 | 95%ノーコード案 |
|---|---|---|
| 排他制御 | 自前実装 | SQS自動 |
| リトライ | 自前実装 | GUI設定 |
| キュー管理 | SQS+自前 | SQS自動 |
| ワークフロー可視化 | なし | あり |
| タイムアウト | なし | なし |
| K8s知識 | 必要 | 不要 |
| 保守対象コード | Java 3,000行 | Java 500行 |
まとめ
本記事では、手動SQL実行の課題を解決するための「95%ノーコード」構成についてお話しました。
この構成のポイント
課題: 手動SQL実行のリスク・工数
├── WHERE句忘れ、環境取り違え...
├── 作業ログなし、誰が何をしたか不明
└── 二人体制でも1件1時間以上かかる
解決策: Kintone + AWS(95%ノーコード構成)
├── 既存の申請→承認フローはそのまま
├── 実行部分だけを自動化
├── ドライラン(Rollback→Commit)で安全に
└── 排他制御・リトライはAWSに任せる
この構成から得た学び
-
既存資産を活用する
- 新しいツールを導入するより、すでに使っているものを活かす
- Kintone + AWSの組み合わせで追加コストを抑えられる
-
AWSマネージドサービスは「コードを書かない」選択肢
- 排他制御、リトライ、キュー管理...全部AWSに任せられる
- 自前実装を減らすことで保守範囲を狭められる
-
GUI設定だから属人化しない
- Step FunctionsもSQSもコンソールでポチポチ設定
- 特定の言語やフレームワークの知識がなくても引き継げる
- 「この人しか触れない」がなくなる
-
K8sは強力だが、必要ないなら使わない
- 学習コスト・運用コストを考慮すると、Fargateで十分なケースも多い
現在、この95%ノーコード構成の実装に向けて準備を進めています。
実装が完了したら、また続編を書きたいと思います。
皆様の現場でも、似たような課題を抱えているかもしれません。
本記事が何かの参考になれば幸いです。
最後までお読みいただき、ありがとうございました。