複式簿記のテーブル設計:仕訳ヘッダ・明細、勘定科目マスタ、貸借一致

確認日 2026-10-31(調べ方)・制度は変わることがあります。個別の判断は公式の資料と専門家に確かめてください。

複式簿記のデータは、仕訳ヘッダ、仕訳明細、勘定科目マスタの3つのテーブルが基本です。1つの取引を1つのヘッダで表し、借方と貸方の各行を明細で持ちます。明細の借方合計と貸方合計は、伝票ごとに必ず一致させます。

このページでは、その土台の設計を説明します。法令が帳簿に求める項目と、編集部の設計の例は分けて書きます。テーブル名と列名は説明用で、特定の製品の構造を示すものではありません。

法令が帳簿に求めていること

法人税法施行規則は、青色申告法人について次のように定めています。

  • 取引を複式簿記の原則に従い、整然と明瞭に記録する(第53条)
  • 仕訳帳と総勘定元帳などを備える(第54条)
  • 仕訳帳には、発生順に取引の年月日、内容、勘定科目、金額を書く(第55条第1項)
  • 総勘定元帳には、勘定ごとに記載の年月日、相手方勘定科目、金額を書く(第55条第2項)

別表二十四は、売掛金や売上などの項目ごとの記載事項を定めています。たとえば売掛金は、相手方別に年月日、品名、数量、単価、金額などです。これらはテーブルの形を決めたものではありません。どの項目を持てるかの確認項目として読みます。

上の仕訳帳と総勘定元帳は、システムではテーブルごとに別々に持つ必要はありません。多くの設計では、仕訳明細を発生順に出せば仕訳帳、科目別に出せば総勘定元帳になります。

仕訳ヘッダと仕訳明細

なぜ分けるかは、1つの例で分かります。消費税つきの売上は、借方1行、貸方2行です。

1つの取引が3行になる

J-1 売上計上
借方金額貸方金額
売掛金110,000売上100,000
仮受消費税10,000
journal_lines
idjournal_idline_nosideaccount_codeamount
L-1J-11D1130110,000
L-2J-12C4100100,000
L-3J-13C215010,000
ヘッダは1行、明細は3行です。借方110,000円と貸方の合計110,000円が一致します。

全体の形は次のとおりです。

複式簿記の基本のテーブル

journal_headers

  • id PK
  • ledger_id FK
  • journal_no
  • entry_date
  • description
  • source_type
  • source_id
  • reversal_of FK
  • created_by
  • created_at

journal_lines

  • id PK
  • journal_id FK
  • line_no
  • side
  • account_code FK
  • sub_account_code
  • department_code
  • partner_id
  • tax_code
  • amount

accounts

  • code PK
  • name
  • category
  • normal_side
  • requires_sub
  • valid_from
  • valid_to
  • journal_headers 1 — N journal_lines
  • accounts 1 — N journal_lines
source_type と source_id は元の業務データへの参照、reversal_of は取り消す相手の伝票です。

列を置く場所の考え方は次のとおりです。

場所 列 持つ理由
ヘッダ entry_date 計上日。帳簿の年月日
ヘッダ created_at 入力日時。計上日とは別に自動で付ける
ヘッダ description 取引の内容
ヘッダ source_type・source_id 元の業務データまでたどる
ヘッダ reversal_of 訂正の相手を特定する
明細 account_code・sub_account_code 勘定科目と補助科目
明細 department_code・partner_id 部門別の損益、取引先別の残高
明細 tax_code 消費税の区分。科目だけでは決まらない
明細 amount 金額。整数か固定小数点で持つ

計上日と入力日を分けるのは、月次の締めのためです。reversal_of は赤伝のためです。どの業務イベントで仕訳を作るかは仕訳連携で扱います。

金額の持ち方は3通りあります。

形 例 長所 短所
side+正の金額 side=‘D’, amount=110000 帳簿の見た目に近い 残高の計算で符号の変換が要る
借方列・貸方列 debit=110000, credit=0 帳票に出しやすい 両方に値が入らない制約が要る
符号つきの1列 amount=110000 または -110000 集計が SUM だけで済む 借方を正にする決まりの周知が要る。マイナス伝票と区別しにくい

このサイトの例では side と正の金額で書きます。マイナス伝票を許すなら、amount の正の制約は外します。

勘定科目マスタ

勘定科目マスタは、集計の軸です。分類(category)で貸借対照表と損益計算書に分かれ、残高の側(normal_side)で残高の増える向きが決まります。

accounts
codenamecategorynormal_siderequires_sub
1110普通預金assetD銀行口座
1130売掛金assetD取引先
2150仮受消費税liabilityCNULL
3100資本金equityCNULL
4100売上revenueCNULL
5100売上原価expenseDNULL

設計で押さえる点です。

  • コードは体系を決める。桁で分類を表す形が一般的です。ただし、コードの体系はあとから変えにくいので、経理と最初に決めます
  • 補助科目を分ける。売掛金の取引先別、預金の口座別のように、科目の下の内訳です。必須かどうかを requires_sub で検査します
  • 科目を物理削除しない。過去の仕訳が参照しています。valid_to で使えなくします
  • 名称の変更は履歴を持つ。国税庁の一問一答の問18は、単価などのマスターデータは期中に改定されるので、取引記録に関連するものを全部保存する必要があるとしています。課税期間の終わりの時点だけでは足りません
  • 税区分は別のマスタにする。同じ科目でも税率や課税区分が分かれるためです。消費税の端数処理も見てください

貸借一致のチェック

伝票の借方と貸方の合計が一致することは、このテーブルの不変条件です。1行ずつの INSERT の途中では一致していないので、CHECK 制約では書けません。トランザクションの終わりに検査します。PostgreSQL の例です。

CREATE FUNCTION assert_journal_balanced() RETURNS trigger AS $$
DECLARE diff numeric;
BEGIN
  SELECT SUM(CASE side WHEN 'D' THEN amount ELSE -amount END)
    INTO diff
  FROM journal_lines
  WHERE journal_id = NEW.journal_id;

  IF diff <> 0 THEN
    RAISE EXCEPTION '伝票 % の貸借が一致しません(差額 %)', NEW.journal_id, diff;
  END IF;
  RETURN NULL;
END $$ LANGUAGE plpgsql;

CREATE CONSTRAINT TRIGGER trg_journal_balanced
AFTER INSERT ON journal_lines
DEFERRABLE INITIALLY DEFERRED
FOR EACH ROW EXECUTE FUNCTION assert_journal_balanced();

この検査は、確定の段階でも通します。

段階 検査 失敗したとき
入力画面 借方と貸方の合計を表示し、差があれば登録を止める 利用者が直す
連携の取り込み 伝票ごとに合計を比べる 保留、または拒否
DB トランザクションの終わりにトリガーで検査 ロールバック
月次の締め 全伝票と試算表の合計を確認 締めを止めて調査

複数通貨を扱うなら、外貨の金額と円換算の金額の両方を持ち、貸借の一致は記帳通貨で見ます。円換算の端数で差が出たときの調整の扱いは、経理と決めます。

試算表は、明細の集計で作れます。

SELECT a.code, a.name,
       SUM(CASE l.side WHEN 'D' THEN l.amount ELSE 0 END) AS debit_total,
       SUM(CASE l.side WHEN 'C' THEN l.amount ELSE 0 END) AS credit_total
FROM journal_lines l
JOIN journal_headers h ON h.id = l.journal_id
JOIN accounts a ON a.code = l.account_code
WHERE h.entry_date BETWEEN '2026-10-01' AND '2026-10-31'
GROUP BY a.code, a.name
ORDER BY a.code;

この例は当月の発生額です。残高まで出すなら、前月までの繰越を足します。

件数が増えて集計が遅くなったら、月次の残高テーブル(期間、科目、補助、部門ごとの増減)を持ちます。残高テーブルは計算の結果にすぎないので、明細の集計と一致することを定期的に検査します。

訂正と履歴

確定した仕訳は、行を書き換えず、取り消しの仕訳を足して直す設計がよく使われます。理由と法令の範囲は赤伝の記事で説明しています。

電子帳簿保存法の優良な電子帳簿では、訂正削除の事実と内容を確認できること、通常の期間を過ぎた入力を確認できることなどが要件です(電帳規則第5条)。ヘッダの reversal_of と created_at は、この要件の検討にも関わる列です。自社がどの要件を目指すかは、経理に確認します。

帳簿は保存の期間も長くなります。法人税法施行規則第59条は起算日から7年の保存を定めています。パーティションで古い期間を分けるなど、データが増え続ける前提で設計します。

判断の練習

会計システムの設計と連携の図解記事

よくある質問

仕訳テーブルはなぜヘッダと明細に分けるのですか?
1つの取引が3行以上になることがあるからです。伝票全体の情報をヘッダに、借方と貸方の各行を明細に置きます。貸借の一致も伝票単位で確かめます。
借方と貸方は別の列にすべきですか?
どれでも作れます。side と正の金額で持つ形、借方列と貸方列の形、符号つきの1列の形があります。集計のしやすさと、マイナス伝票を許すかで決めます。
貸借一致のチェックはアプリと DB のどちらで行いますか?
両方が安全です。入力時にアプリで検査し、DB ではトランザクションの終わりに伝票単位で検査する形が考えられます。
残高は毎回集計しますか?
件数が少ないうちは集計で足ります。多くなったら月次の残高テーブルを持ちます。その場合も明細の集計と一致するかを定期的に検査します。

出典

調べ方・間違いのお知らせ