業務日報をSQLiteに貯める|ひとり経営者のための数字の見える化術

毎朝、前日の業務日報を3分だけ読む。それだけで事業全体が把握できるようになる。そう言われても、最初は信じられないかもしれない。日報なんて会社員時代に嫌々書かされたもので、ひとりで事業をやっている自分には関係ない。そう思う人も多いだろう。

でも、ここで言う日報は上司に見せるためのものではない。自分の事業の数字を、毎日自動で記録していく仕組みのことだ。手で書くわけでもない。業務の中で自然に貯まっていく数字を、1つの場所にまとめておくだけ。その場所として私が選んだのがSQLite(エスキューライト、1つのファイルで動く軽量なデータベース)だった。

300日以上この仕組みを回してきて、ようやく見えてきたことがある。ひとりで事業を回している人間にとって、数字の見える化は贅沢品ではない。生存装置だ。今日はその話をしたい。

この記事の前提

この記事は、ひとりで小さな事業をいくつか回している人に向けて書いている。従業員はいない。あるいはいても業務委託が数人。自分が止まったら事業も止まる、という状況で走っている人だ。

そういう立場にいると、数字を追いかける時間が取れない。会計ソフトを開くのは月末だけ、広告の数字を見るのは週末だけ、AIの利用料を確認するのは請求が来たときだけ。そういう運用になりがちだ。私自身もそうだった。

この記事で伝えたいのは、難しい分析ツールを入れろという話ではない。むしろ逆だ。SQLiteという無料で動く小さなデータベースに、業務の痕跡を毎日自動で貯めていく。そして毎朝3分、前日の様子を眺める。それだけで事業の健康状態が手に取るようにわかるようになる、という話だ。

エンジニアでなくても真似できるように書いたつもりだ。コード例も出てくるが、写経すれば動くレベルに落としてある。

なぜSQLiteなのか

数字の見える化ツール比較

図: 数字の見える化ツール比較

まず前提の話をさせてほしい。数字を貯める場所はいくつもある。Googleスプレッドシート、Notion、Airtable、会計ソフト、専用のBIツール(ビジネスインテリジェンス、数字を可視化する道具)。どれも悪くない。

でも、ひとり経営者には重すぎるものが多い。月額5,000円のツールを3つ契約すると、それだけで年18万円。使いこなせないまま解約する、というのを私も何度もやってきた。

SQLiteは違う。1つのファイルに全部が収まる。サーバーも要らない。月額費用もゼロ円。バックアップはそのファイルをコピーするだけ。パソコンにもスマホにもクラウドストレージにも置ける。データが自分の手元にあるという安心感は、クラウドサービスに預けるのとはまったく違う。

そして何より、Claude Codeのようなコード支援AIと相性がいい。「先月の広告費を事業別に集計して」と日本語で頼めば、AIがSQL(データベースに問い合わせる言語)を書いてくれる。自分でSQLを覚える必要はほぼない。

貯めるべき4つのテーブル

生存装置としての4テーブル構成

図: 生存装置としての4テーブル構成

私が300日回してきた中で、最終的に残ったテーブル(表)は4つだけだ。多すぎると続かないし、少なすぎると見えるものが少ない。この4つが私にとっての落としどころだった。

  1. agent_runs(エージェントの実行ログ)
  2. cost_ledger(コストの元帳)
  3. dialogue_logs(判断の対話ログ)
  4. daily_summary(1日1行の要約ビュー)

1つずつ説明していく。

agent_runs テーブル

私はいくつかの事業で、AIエージェント(自動で作業する小さなプログラム)に定型業務を任せている。メールの下書き、記事の校正、画像のリサイズ、レポートの生成。そういう細かい仕事だ。

このエージェントが動くたびに、1行のログを残すようにしている。設計はシンプルで、こんな形だ。

CREATE TABLE agent_runs (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  started_at TEXT NOT NULL,
  ended_at TEXT,
  business_tag TEXT NOT NULL,
  task_name TEXT NOT NULL,
  status TEXT NOT NULL,
  input_tokens INTEGER,
  output_tokens INTEGER,
  note TEXT
);

business_tag は事業ごとのタグだ。事業A、事業B、事業C、と分けておく。task_name は処理の名前。status は成功か失敗か。input_tokens と output_tokens はAIに渡した文字数と返ってきた文字数だ。これがそのままコストに響く。

300日間で貯まった行数は、だいたい3万行を超えた。1日平均100行前後。手で書いていたら絶対に続かなかった量だ。でも自動で書き込まれるので、存在すら忘れている。

cost_ledger テーブル

お金の出入りを貯めるテーブルだ。会計ソフトと重複するように見えるかもしれないが、役割が違う。会計ソフトは税務のためのもの。この cost_ledger は、事業判断のためのものだ。

CREATE TABLE cost_ledger (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  occurred_on TEXT NOT NULL,
  business_tag TEXT NOT NULL,
  category TEXT NOT NULL,
  amount_jpy INTEGER NOT NULL,
  source TEXT NOT NULL,
  memo TEXT
);

category はたとえば ai_api、ads、saas、outsourcing、server のような粗い分類だ。細かく分けすぎると続かない。source はどこから取ったデータか。Claude APIの請求書から手入力した、広告管理画面からダウンロードしたCSVから取り込んだ、など。

ポイントは、税務の正確さを目指さないことだ。10円単位でズレていても事業判断には影響しない。ざっくりでいいから、毎日の支出がどの事業で発生しているかが見える、という状態を目指す。

dialogue_logs テーブル

これは私が試行錯誤の末にたどり着いた、少し変わったテーブルだ。判断の記録を貯める。

ひとりで事業をやっていると、判断を人に説明する機会がない。誰にも相談せずに決めて、誰にも説明せずに実行する。すると半年後に「なぜこれをやることにしたんだっけ」と思い出せなくなる。同じ判断ミスを繰り返す。

そこで私は、AIと対話しながら重要な判断をするようになった。値上げをするかどうか、新しい広告媒体を試すかどうか、業務委託の単価を上げるかどうか。そういう話をAIと壁打ちする。その対話をまるごとテキストで保存しておく。

CREATE TABLE dialogue_logs (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  logged_at TEXT NOT NULL,
  business_tag TEXT NOT NULL,
  topic TEXT NOT NULL,
  decision TEXT,
  full_text TEXT NOT NULL
);

topic は「値上げ検討」「媒体Bの撤退判断」のような短いラベル。decision はそのとき何を決めたか。full_text に対話の全文を突っ込む。

300日経ってから、この dialogue_logs を読み返すと驚くことがある。半年前の自分が悩んでいた論点が、今も悩んでいる論点だったりする。逆に、半年前には致命的だと思っていた問題が、もう存在しないこともある。自分の判断の癖が見えてくる。

daily_summary ビュー

最後は、ビュー(複数のテーブルから欲しい情報だけを取り出す仮想の表)を1つだけ作る。これがこの仕組みの肝だ。

CREATE VIEW daily_summary AS
SELECT
  DATE(started_at) AS day,
  business_tag,
  COUNT(*) AS runs,
  SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors,
  SUM(input_tokens + output_tokens) AS tokens
FROM agent_runs
GROUP BY day, business_tag;

これを毎朝、私はたった1行のコマンドで呼び出す。前日の分だけ抜き出して眺める。事業Aで何回エージェントが動いたか、何回失敗したか、どれくらいトークン(AIが扱う文字のかたまり)を使ったか。それだけがわかる。

シンプルすぎると思うかもしれない。でもシンプルでいい。ビューを増やし始めると管理コストが跳ね上がる。1つだけに絞ることで、毎朝迷わず同じ画面を見る習慣が作れる。

参考になる事例

ここで少し、私が知っている他の人の運用を紹介したい。似た悩みを別のやり方で解いている人たちだ。

事例1|週次レビューに特化した個人事業主

ある個人事業主は、毎日ではなく週次で数字を見る運用にしている。月曜の朝に30分、前週の agent_runs と cost_ledger をざっと眺める。毎日見る時間は取れないが、週1回なら続く。

この人が言っていたのは、粒度は人によって違っていい、ということだった。毎日3分派もいれば、週1回30分派もいる。続けられる方を選べ、と。たしかにその通りだと思う。

事例2|夫婦で共有している事業者

別のある事業者は、SQLiteのファイルを夫婦で共有している。クラウドストレージに置いて、書き込みは片方だけが行う。もう片方は読み取り専用で眺める。毎週日曜の夜に5分だけ、一緒に数字を見て話す時間を作っているという。

ひとり経営と言っても、家族と話す機会はある。そのときに同じ数字を見ながら話せるのは、かなり効果が大きいと聞いた。

事例3|会計ソフトを捨てかけた人

ある人は、会計ソフトの使用頻度が月に1回以下まで落ちた時期があったそうだ。代わりに cost_ledger を見る頻度が上がった。税務は年1回、税理士に丸投げする。自分は事業判断のためだけに数字を見る、と完全に切り分けたのだという。

これは極端な例かもしれない。ただ、税務の正確さと事業判断のスピードは別物だ、という割り切りは私も同感だった。

具体的な始め方

ゼロから始める5ステップ

図: ゼロから始める5ステップ

ここから実際の手順を書く。非エンジニアでも真似できるように、順番に説明する。

ステップ1|SQLiteを手元に置く

macOSでもWindowsでも、SQLiteは実質標準で入っている。ターミナル(黒い画面のアプリ)を開いて、sqlite3 と打てば反応する。反応しなければ公式サイトからダウンロードすればいい。無料だ。

適当なフォルダを作って、そこに business_log.db という名前で1つファイルを作る。これだけで準備完了だ。

sqlite3 business_log.db

このコマンドを叩くと、SQLiteの対話モードに入る。.tables と打てば中にある表の一覧が出る。最初は何もない。

ステップ2|4つのテーブルを作る

さきほど書いた CREATE TABLE の文を順番に貼り付けていく。4つ貼ればテーブルが4つできる。このあたりは、Claude Codeに「さっきの4つのテーブルを作って」と頼めば一発で書いてくれる。

ステップ3|書き込み口を1つ用意する

ここが肝心だ。データは手で入れない。業務の中で自動で書き込まれるようにする。

私の場合、普段の業務をPythonやNode.jsの小さなスクリプトで回しているので、そこに1行だけ「このSQLiteにログを書け」というコードを足した。こんな感じだ。

import sqlite3
from datetime import datetime

def log_run(business_tag, task_name, status, tokens_in, tokens_out):
    conn = sqlite3.connect("business_log.db")
    conn.execute(
        "INSERT INTO agent_runs (started_at, business_tag, task_name, status, input_tokens, output_tokens) VALUES (?, ?, ?, ?, ?, ?)",
        (datetime.now().isoformat(), business_tag, task_name, status, tokens_in, tokens_out)
    )
    conn.commit()
    conn.close()

業務スクリプトの終わりに、この log_run を呼ぶ行を1行足すだけ。あとは勝手に貯まる。

ステップ4|毎朝3分の習慣を作る

朝のコーヒーを淹れる前でも後でもいい。パソコンを開いて、1つのコマンドを叩く。

sqlite3 business_log.db "SELECT * FROM daily_summary WHERE day = DATE('now', '-1 day');"

これで前日の要約が出る。数字が並ぶだけだ。絵も出ないし派手さもない。でもこれを300日続けると、異常値に気づくのが早くなる。

普段は事業Aの runs が80前後なのに、昨日は120だった。なぜだろう。調べると、ある自動処理がエラーを繰り返してリトライ(再実行)していた。気づかなければ月末にAPI料金が膨らんで初めて気づいていた、ということがよくある。

ステップ5|週1回だけ集計する

毎日は細かく見なくていい。週1回、日曜の夜にでも、過去7日分をざっと SELECT で集計する。

sqlite3 business_log.db "SELECT business_tag, SUM(amount_jpy) FROM cost_ledger WHERE occurred_on >= DATE('now', '-7 day') GROUP BY business_tag;"

事業ごとに過去7日のコストが出る。これを見て、どの事業に今お金が流れ込んでいるかを把握する。ここで赤信号が出たら、その週のうちに止める判断ができる。月末まで待つ必要がない。

よくある失敗・落とし穴

300日回してきて、自分が踏んだ罠を共有しておく。

落とし穴1|テーブルを増やしすぎる

最初の2ヶ月、私はテーブルを12個まで増やした。顧客別、プロジェクト別、曜日別、時間帯別。細かく分けた方が見える気がしたからだ。結果はひどかった。書き込み口が複雑になり、スクリプトが壊れ、だんだんログが歯抜けになった。

テーブルは4つまで。ビューは1つだけ。これが私の結論だ。物足りなく感じるくらいで、ちょうどいい。

落とし穴2|手入力に頼る

cost_ledger を毎日手で入力しようとしたことがある。3日で続かなくなった。人間は毎日ログを書く生き物ではない。

書き込みは必ず自動化する。自動化できないデータは、そもそも貯めない。これが鉄則だ。どうしても手入力したいデータは、週1回まとめて入れる日を決める。

落とし穴3|バックアップを忘れる

SQLiteは1ファイルで済む手軽さがあるが、裏を返すとそのファイルを失うと全部消える。私は一度、パソコンを買い替えるときに危うく失いかけた。

今は毎日自動で、クラウドストレージに business_log.db をコピーするようにしている。コマンドで言えばたった1行の仕事だ。これを忘れてはいけない。

落とし穴4|見ない

これが一番多い失敗だ。貯めることに満足してしまい、見なくなる。せっかく3万行貯めても、見なければ意味がない。

私は iPhone のリマインダーに「8時、日報を見る」と入れている。毎朝鳴る。鳴ったら黙って1コマンド叩く。これを儀式にしないと、1週間で忘れる。

落とし穴5|完璧なダッシュボードを作ろうとする

Grafana(グラファナ、数字を可視化する有名なツール)のような立派なダッシュボードを作りたくなる。私も作ろうとして、1週間溶かした。結局続かなかった。

ひとり経営者にとって、ダッシュボードは贅沢品だ。ターミナルに数字が並ぶだけで十分。見た目にこだわる時間があるなら、売上を作ることに使った方がいい。

落とし穴6|dialogue_logs を真面目に書きすぎる

dialogue_logs に正式な議事録を書こうとすると、重くて続かない。AIとの対話を雑にコピペするだけでいい。誤字脱字も直さない。口語のままでいい。

半年後に読み返すときに大事なのは、正確さよりも、そのときの自分の温度感だ。雑な文の方が温度感は残りやすい。

明日からやる3つのこと

長くなったので、明日から実行できる3つのことに絞る。

1つ目。SQLiteで business_log.db を作り、agent_runs と cost_ledger の2つだけテーブルを作ってみる。dialogue_logs と daily_summary はあとでいい。まずは2つだけ。

2つ目。いま自分の業務で、何か1つだけでいいから、動いたら1行ログを残す仕組みを入れる。Pythonでもシェルスクリプトでも、手元の環境で一番楽に書ける言語で構わない。Claude Codeに頼んで書いてもらうのが一番早い。

3つ目。明日の朝、コーヒーの前でも後でもいい、ターミナルで SELECT * FROM agent_runs; と打ってみる。1行でも入っていれば成功だ。その1行を眺めて、明後日も同じことをする。

300日先に何が見えるかは、やってみないとわからない。でも私には見えたものがあった。数字は嘘をつかない。そして数字を毎日見ている人間は、迷わなくなる。ひとりで事業を回すとき、迷わないことは何よりの武器になる。

明日の朝、3分だけ時間をくれないだろうか。その3分が、半年後の事業を静かに変えていく。私はそう信じている。