Help us understand the problem. What is going on with this article?

[DB/SQL]要件をテーブルに落とし込む手法のメモ書き(複式簿記のテーブル設計を例に)

この記事で書くこと

要件をテーブルに落とし込む手法のメモ書き(複式簿記のテーブル設計を例に)

前提条件

・SQLの基本的な文法(SELECT,INSERT等)を知っている

開発環境

開発環境は次の通り

項目
PC MacBook Air
OS MacOS Catalina
DB PostgreSQL
DB管理 pgAdmin4
Browser Google Chrome

「複式簿記」に興味を持った理由

・グーグル日本法人の社長を勤めた村上憲郎さん「エンジニアとしてキャリアを始めた時に簿記を勉強させられたがそれが後に役に立った」と書籍に書かれていたから。

そもそも「複式簿記」とは?

・どこからいくらお金を調達して(=負債または収益)、
・何にいくらお金を支払ったのか(=費用
・または、調達したお金をどういう形でいくら保管しているか(=資産)を記録する手法。

(目的)
・決算日における資産状況を把握する貸借対照表(B/S)を作成
・1年間の損益や当期純利益を把握する損益計算書(P/L)を作成

テーブル設計の流れ

①要件の把握 >> ②概念設計 >> ③論理設計 >> ④物理設計

要件の把握

要件
・複式簿記で家計簿を入力したい
・仕訳表を表示できるようにしたい
・例えば12000円の服をクレジットカードで10000円および現金で2000円支払って購入したような取引も入力できるようにしたい
・勘定科目はあとから追加できるようにしてほしい

(仕訳表のイメージ)

日付 借方科目 借方金額 貸方科目 貸方金額 摘要
2020-01-26 現金 10000 開始残高 10000 現金の開始残高
2020-01-26 普通預金 500000 開始残高 500000 普通預金の開始残高
2020-01-26 Suica 5000 開始残高 5000 Suicaの開始残高
2020-01-27 食費 129 現金 129 コンビニで緑茶を購入
2020-01-27 衣服・美容費 12000 クレジットカード未払金 10000 服を購入
現金 2000 服を購入
2020-01-27 交通費 230 Suica 230 梅田〜なんばを移動
2020-01-27 食費 110 普通預金 110 おにぎりを購入

概念設計

どういう情報を管理する必要があるか整理すること

必要な情報
仕訳表
勘定科目の一覧

論理設計

整理した情報の構造を具体化すること

・仕訳表を表示するためには、仕訳テーブル(journal)が必要
・勘定科目の一覧を用意するためには、勘定科目テーブル(accounts_title)が必要

・下記要件を叶えるためには、明細の情報を格納する必要がある。
・明細情報を格納するために、仕訳明細テーブル(journal_details)を用意

要件
・例えば12000円の服をクレジットカードで10000円および現金で2000円支払って購入したような取引も入力できるようにしたい

(ER図の例)
Untitled Diagram.png

物理設計

全てのテーブルの列について、データ型・インデックス・制約・デフォルト値を確定すること

仕訳テーブル(journal)

カラム名 データ型 制約
id SERIAL 主キー
date DATE NULL不可
memo VARCHAR(20)

仕訳明細テーブル(journal_details)

カラム名 データ型 制約
id SERIAL 主キー
journal_id INTEGER 外部キー(仕訳テーブル id)
debit_account_id INTEGER 外部キー(勘定科目テーブル id)
debit_amount INTEGER NULL不可
credit_account_id INTEGER 外部キー(勘定科目テーブル id)
credit_amount INTEGER NULL不可

勘定科目テーブル(accounts_title)

カラム名 データ型 制約
id SERIAL 主キー
name VARCHAR(10) NULL不可・重複不可
account_type INTEGER 設定可能な値:0,1,2,3,4のうち1つ※

0:資産 1:負債 2:費用 3:収益 4:純資産として勘定科目を区別

CREATE TABLE

仕訳テーブル(journal)
CREATE TABLE journal(
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
memo VARCHAR(20)
);
仕訳IDシーケンス(journal_id_sequence)
CREATE SEQUENCE journal_id_sequence;
仕訳明細テーブル(journal_details)
CREATE TABLE journal_details(
id SERIAL PRIMARY KEY,
journal_id INTEGER REFERENCES journal(id),
debit_accounts_id INTEGER REFERENCES accounts_title(id),
debit_amount INTEGER NOT NULL,
credit_accounts_id INTEGER REFERENCES accounts_title(id),
credit_amount INTEGER NOT NULL
);
仕訳明細IDシーケンス(journal_details_id_sequence)
CREATE SEQUENCE journal_details_id_sequence;
勘定科目テーブル(accounts_title)
CREATE TABLE accounts_title(
id SERIAL PRIMARY KEY,
name VARCHAR(10) NOT NULL UNIQUE,
accounts_type INTEGER CHECH(accounts_type in (0,1,2,3,4))
);
勘定科目IDシーケンス(accounts_title_id_sequence)
CREATE SEQUENCE accounts_title_id_sequence;

SQLを叩いて仕訳表を表示してみよう

勘定科目テーブルにデータを投入
insert into accounts_title(id,name,account_type) values(1,'現金',0);
仕訳テーブルにデータを投入
insert into journal(id,date,memo) values((select(nextval('journal_id_sequence'))),(SELECT CURRENT_DATE),'おにぎりを購入');
select * from journal;
仕訳明細テーブルにデータを投入
insert into journal_details(id,journal_id,debit_accounts_id,debit_amount,credit_accounts_id,credit_amount)
values((select(nextval('journal_details_id_sequence'))),3,3,5000,20,5000);
仕訳表を表示
select journal.id as 仕訳ID,
journal.date as 日付, 
(select accounts_title.name from accounts_title where accounts_title.id = journal_details.debit_accounts_id) as 借方科目,
journal_details.credit_amount as 借方金額,
(select accounts_title.name from accounts_title where accounts_title.id = journal_details.credit_accounts_id) as 貸方科目,
journal_details.credit_amount as 貸方金額,
journal.memo as 摘要 from journal_details
join journal
on journal_details.journal_id = journal.id;
勘定科目を一覧表示
 id |          name          | account_type 
----+------------------------+--------------
  1 | 現金                   |            0
  2 | 普通預金               |            0
  3 | Suica                  |            0
  4 | その他(資産)         |            0
  5 | クレジットカード未払金 |            1
  6 | その他(負債)         |            1
  7 | 食費                   |            2
  8 | 日用品費               |            2
  9 | 衣服・美容費           |            2
 10 | 交通費                 |            2
 11 | 光熱費                 |            2
 12 | 教育費                 |            2
 13 | 交際費                 |            2
 14 | 趣味・娯楽             |            2
 15 | 家賃                   |            2
 16 | その他(費用)         |            2
 17 | 給与                   |            3
 18 | 副収入                 |            3
 19 | その他(収益)         |            3
 20 | 開始残高               |            4
 21 | その他(純資産)       |            4
(21 rows)
明細を一覧表示
 id |    date    |         memo         
----+------------+----------------------
  1 | 2020-01-26 | 現金の開始残高
  2 | 2020-01-26 | 普通預金の開始残高
  3 | 2020-01-26 | Suicaの開始残高
  6 | 2020-01-27 | コンビニで緑茶を購入
  7 | 2020-01-27 | 服を購入
  8 | 2020-01-27 | 梅田〜なんばを移動
  9 | 2020-01-27 | おにぎりを購入
(7 rows)
表示結果(仕訳明細)
 仕訳id |    日付    |   借方科目   | 借方金額 |        貸方科目        | 貸方金額 |         摘要         
--------+------------+--------------+----------+------------------------+----------+----------------------
      1 | 2020-01-26 | 現金         |    10000 | 開始残高               |    10000 | 現金の開始残高
      2 | 2020-01-26 | 普通預金     |   500000 | 開始残高               |   500000 | 普通預金の開始残高
      3 | 2020-01-26 | Suica        |     5000 | 開始残高               |     5000 | Suicaの開始残高
      6 | 2020-01-27 | 食費         |      129 | 現金                   |      129 | コンビニで緑茶を購入
      7 | 2020-01-27 | 衣服・美容費 |    10000 | クレジットカード未払金 |    10000 | 服を購入
      7 | 2020-01-27 | 衣服・美容費 |     2000 | 現金                   |     2000 | 服を購入
      8 | 2020-01-27 | 交通費       |      230 | Suica                  |      230 | 梅田〜なんばを移動
      9 | 2020-01-27 | 食費         |      110 | 普通預金               |      110 | おにぎりを購入
(8 rows)

今後やりたいこと

① 複式簿記を採用した家計簿アプリ(WEBアプリ)を実装したい

(想定している開発環境)

項目
PC MacBook Air
OS MacOS Catalina
Container Docker
WEB Server Apache Tomcat
Server Side Java Servlet + JSP
Front End React Pivottable.js
DB PostgreSQL
DB管理 pgAdmin4
バージョン管理 GitHub
Browser Google Chrome

② 簿記2級を取得したい
・商業簿記や工業簿記を勉強することで、形のないものをどう現金化(=価値創出)するかのヒントを学習できる(はず)

参考資料

データベースのテーブル設計に関するもの
スッキリわかるSQL入門 第2版(株式会社インプレス)

複式簿記に関するもの
初歩から学ぶ簿記・経営分析(税務経理協会 三枝幸文・松井富佐男)
会計の世界史 イタリア、イギリス、アメリカ - 500年の物語(日本経済新聞出版社 田中靖浩)

エンジニアも簿記を勉強することでキャリアが広がることを示す記事
村上式シンプル仕事術―厳しい時代を生き抜く14の原理原則(ダイヤモンド社 村上憲郎)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした