トラン系とかマスタ系とかやめた

この仕事を始めた時から、データベースの御世話になってる訳ですが、「トラン系」と「マスタ系」って言葉はその当初から教えられて、自分でも使って来ました。

この言葉はどうやら一般教養らしく、今の会社に移ってからも普通に通じました。よって何の疑問も感じないで今まで使ってきたんですが。

もうやめた。やめやめ!

あまりにもシステムっぽ過ぎる響き。多分これが悪影響を及ぼしてる気がする。

仕入データを、仕入先・部門・勘定単位で月次で集計するテーブルがあるんですけど、それに対して支払指示をかける業務がありまして。これが当初、このテーブルに支払支持金額がカラムとしてありまして。単純化するとこんな感じ。

  • 年月
  • 仕入
  • 部門
  • 勘定科目
  • 仕入金額
  • 支払指示金額

つまり、この月次集計明細と支払支持が1対1でしかありえないようになってる。多分最初のヒアリング時はそんな話で進んだんでしょう。始めに見せて貰った帳票なんかがそんな作りになってて、そこから類推して設計しただけかも知れません(多分これだな)。

当然、変更要件が入ります。支払指示は、仕入先から請求書が来たタイミングで登録されます。じゃあ請求書ってのはどう云う単位で来るか。部門?勘定?そんなもん仕入先はしったこっちゃない。請求書として一遍にドカーンと来ます。

つまり、この月次集計テーブルと支払指示データは多対1な訳です。まあ普通そうだよな。

画面の一覧表示部もこんな感じで変更が入りました。

■元々

仕入先 部門 勘定         仕入金額 支払指示金額 差異金額
------ ---- ------------ -------- ------------ ---------
AAAA   001  商品仕入高       1000         1000         0
AAAA   001  原材料仕入高      500          300       200
AAAA   002  商品仕入高       1200         1200         0
BBBB   001  原材料仕入高      900          500       400
BBBB   002  商品仕入高        800          800         0

■変更後
仕入先 部門 勘定         仕入金額 支払指示金額 差異金額
------ ---- ------------ -------- ------------ ---------
AAAA   001  商品仕入高       1000                       
AAAA   001  原材料仕入高      500                       
AAAA   002  商品仕入高       1200                       
AAAA合計                     2700         2500       200
BBBB   001  原材料仕入高      900                       
BBBB   002  商品仕入高        800                       
BBBB合計                     1700         1700         0

まずこの時点で(本当は最初から)、新しく支払指示テーブルってのを作らなきゃいけなかった。で、合計行はSQLを工夫して、SUM関数使ったSELECT文(支払指示テーブルとJOIN済み)をUNIONして、ソート順を上手い事やっていっぺんにもってくればいい。説明するとややこしそうだけど、やってみると割りと簡単です。

パフォーマンス度外視してざっと単純に考えてこうかな。勿論支払指示が月に複数回とかもうちょっと複雑な場合もあり。

SELECT
    仕入先   AS 仕入先,
    部門     AS 部門,
    勘定     AS 勘定,
    仕入金額 AS 仕入金額,
    NULL     AS 支払指示金額,
    NULL     AS 差異金額,
    0        AS ソートキー
FROM
    仕入集計テーブル
WHERE
    年月 = '2005/11'
UNION ALL
SELECT
    仕.仕入先        AS 仕入先,
    NULL             AS 部門,
    NULL             AS 勘定,
    SUM(仕.仕入金額) AS 仕入金額,
    支.指示金額      AS 支払指示金額,
    NULL             AS 差異金額,
    1                AS ソートキー
FROM
    (SELECT
         仕入先        AS 仕入先,
         SUM(仕入金額) AS 仕入金額
     FROM
         仕入集計テーブル
     WHERE
        年月 = '2005/11'
     GROUP BY
         仕入先
    ) 仕
    INNER JOIN 支払指示テーブル 支
    ON  仕.仕入先 = 支.仕入先
    AND 仕.年月   = 支.年月
ORDER BY
    仕入先,
    ソートキー,
    部門,
    勘定

でもやらなかった。どうしたか。

月次集計ってのがミソで、その集計処理のタイミングでなんと!仕入先合計行を1レコードとして突っ込んでんですよ。部門・勘定はダミーコードにして。わざわざダミーコードを部門・勘定マスタに設定して。経験年数15年以上の俺の上司が。

上の画面イメージのまま、SELECT文一発で取って来れるから、そりゃ便利っちゃ便利ですよ。でもこれは最悪です。データに業務ロジックが混在しているからです。ある一つのカラムが、ある条件ではこう云う値を示し、違う条件ではこう云う値を示す、って作り方は絶対にやるな、データとは静的なものだからである、これを保証する為にアプリケーション側で最大限の努力をしなくてはならない、と「いろは」として教わったんですが。

なんでこう、目の前のタスクを手っ取り早く潰す事しか考えないんだろう。いっつもいっつも。

まあこの状態で、出向先から帰って来たばかりの私めに火消し役が回って来た訳です。

で、お客様から更に要望。この月次集計データに新規追加したい、及び削除もしたい、だって。変更前は出来てたんだって。変更したら出来なくなったって。そりゃそうだ、月次集計処理で仕入先合計行作ってんだもん、追加削除されたら狂っちゃうじゃん。No Exit。

DOAの人達が兎に角データモデルをデータモデルをとおっしゃるのは、こう云う悲劇を散々目撃されてるからじゃないですかね。単純に画面の見たまんまをデータモデルとしちゃう。

俺も就職してからずっと、データモデルさえ押さえておけばあとはどうにかなる、と云う中で働いて来ました。

だからこそ、画面モックとユーザーマニュアルが外部仕様書だ、と云うGOYAの考え方は、へぇぇぇと思ったもんです。確かにお客様に優しい。でもこれをやれば優しくなれるってもんじゃないと思いました。そのバックボーンに確かな設計の指針があるから、お客様に優しい方法が取れるって話で。

で最初の話に戻ると、「トラン系」「マスタ系」ってなんじゃい。日々の業務の中でバンバン更新されるからトラン系ですか。されないからマスタ系ですか。実にシステム的ネーミングです。だから設計を誤るんだと思います。

一覧に出したときに、仕入金額と支払指示金額が一緒に出てる、つまり1トランザクションだから1つのテーブルにしちゃえって発想に対して、抑止出来ません。つか、背中押してる気がしないでもない。

だから、もうこれからは「イベント」「リソース」って呼びます。ぐっと業務寄りの響きに思えます。本当はもっと業務っぽいのがいいんですけど、割とスタンダードなようなので、これにします。

「イベント」と呼べば、「仕入月次集計」と「支払指示」が1つのイベントだとは思いにくいはずです。ちょっとだけ頭を使えば、「テーブル2つ要るんじゃないか」と思ってくれる可能性が格段に高くなるでしょう。多分。だと良いな。名前重要。もう社内で徹底させようと思います。相手は上司ですけど、もう直訴。どうせ火消しは俺だから。