ユニケージとは何か、いま作るならどうするか
参考: USP研究所 ユニケージ
まとめ
- ユニケージは、テキストファイルとシェルのテキスト処理(grep / awk など)でバッチ処理を組み、DB を使わない開発手法
- 技術の中心は「途中の段がすべてファイルとして残るパイプライン」で、POS の集計のような読み取り中心の業務に向き、多数のユーザーが同時に更新する SaaS には向かない(推定)
- いま同じものを作るなら、S3 と Lambda、Athena で同じ構造を組める
- 持ち帰る価値があるのはシェルという技術ではなく、生データを消さずに段ごとの結果を残すというデータの持ち方
ユニケージは何を決めているか
ユニケージは、USP研究所が提唱する「UNIX 系 OS とシェルスクリプトだけで業務システムを作る」開発手法だ。 名前は Unix Command Package に由来する。 公式の説明ページは7章に分かれていて、決めている範囲はコードの書き方より広い。
表1: ユニケージが決めていること
| 層 | 決めていること |
|---|---|
| 使う技術 | UNIX 系 OS とシェルだけを使う。標準コマンドに独自コマンド数十個(列を選ぶ self、結合する join1 など)を足す |
| データの持ち方 | LEVEL1〜5 の段に分ける。生のデータを消さず、小分けのテキストに整理し、出力ごとに専用のコピーを作る |
| 設計の決まり | 共通ルーチンを持たない。1つのプログラムには1つの処理の流れだけを書き、シェル関数も原則使わない |
| 進め方 | 要件定義より先に実データを全部受け取る(一休さん方式)。目的を果たす最低限の仕様で一度完成させ、便利機能は2度目の依頼で足す(床屋方式) |
| 書類 | 各処理に入出力のレイアウトを必ず書かせ、チェッカーで守っていないスクリプトのリリースを止める。書類はそこから自動で出力する |
| 人と商売 | 1人で1システムを作れる技術者を訓練で育てる。USP研究所の商売は教育、初期構築、サポートとライセンス |
作業の進め方は表1の1行にすぎない。 その進め方も「シェルとテキストなので作り直しが速い」という技術側の前提の上に立っている。
例: 店舗×時間帯の売上を集計する
データの持ち方は、例で見たほうが早い。 以下はコンビニの「店舗ごと、時間帯ごとの売上」を集計する場合を想定して私が作った例で、実在のシステムの中身ではない。
LEVEL1 は、レジで1回会計するごとに1ファイルできる生データだ。 届いたファイルは消さず、書き換えもしない。
/LV1/POS/20261113/0123/093512_0001
0123 093512 4901234 2 300 # 店舗 時刻 商品 数量 金額LEVEL2 は、決まった時刻に全店分を1本のテキストにまとめたものになる。
cat /LV1/POS/20261113/*/* | sort > /LV2/URIAGE/20261113LEVEL3 は、業務上の意味で整理した段で、ここでは店舗と時間帯で合計する。
awk '{print $1, substr($2,1,2), $5}' /LV2/URIAGE/20261113 |
sort |
awk '{s[$1" "$2]+=$3} END{for(k in s) print k, s[k]}' |
sort > /LV3/URIAGE_JIKAN/20261113LEVEL4 は、画面ごとの専用ファイルだ。 本部の画面と店長の画面で中身が重複するが、ユニケージはこれを許す。
join /MASTER/TENPO /LV3/URIAGE_JIKAN/20261113 > /LV4/HONBU/20261113
awk '$1=="0123"' /LV3/URIAGE_JIKAN/20261113 > /LV4/TENCHO/0123/20261113ユニケージの独自コマンドを使えば、LEVEL3 の集計は self 1 2.1.2 5 | msort key=1/2 | sm2 1 2 3 3 のように短く書ける(コマンドを公開した Open usp Tukubai の記法)。
普通のパイプラインと何が違うか
ここまでの例は、Unix のパイプラインそのものに見える。 ただ、普通のパイプラインとは途中結果と元データの扱いが違う。
表2: 一般的なパイプラインとの違い
| 観点 | 一般的なパイプライン | ユニケージ |
|---|---|---|
| 途中結果 | パイプで流して残さないことが多い | LEVEL ごとに決まった場所へファイルで残す |
| 元データ | 処理したら捨てるか、要約して残す | 生データ(LEVEL1)を持ち続ける |
| 出力ごとの違い | 同じデータを出力ごとに違う処理で読む | 出力ごとに専用のファイル(LEVEL4)を作っておく |
途中がすべてファイルで残るので、どの段からでも作り直せるし、各段の中身を cat で確かめられる。
どんな業務に向くか
ユニケージは2010年代に小売や流通の企業で採用例が報じられた。 ローソンの約8500店舗の時間帯別売上管理や、良品計画のマーチャンダイジングシステムがその例だ(Impress IT Leaders)。 記事が挙げる採用理由は「システム内製化」と「効率よくスクラッチ開発する」ことで(Impress クラウド Watch)、業種との相性を論じた資料は見つからなかった。 次の表は、手法の設計から私が推定したものだ。
表3: 業務の性質と向き不向き(推定)
| 業務の性質 | 向き不向き | 理由 |
|---|---|---|
| 起きた事実が大量に積み上がり、後から書き換えない(POS の売上など) | 向く | 生データを消さずに残す LEVEL1 の形そのもの |
| 集計と帳票が中心で、帳票が頻繁に変わる | 向く | 帳票ごとに LEVEL4 を作り足せば、他の帳票に影響しない |
| 多数のユーザーが同じデータを同時に更新する(予約、在庫引当、決済) | 向かない | RDB を使わないので、排他制御とトランザクションを自前で作ることになる |
| 1つのコードを多数の顧客に配り、共通機能を一斉に直す | 向かない | 共通ルーチンを持たないので、同じ修正をすべてのコピーに入れることになる |
いま作るならどうするか
USP研究所は2023年のプレスリリースで、ユニケージに30年の実績があるとしている(dreamnews)。 AWS Lambda の公開は2014年なので、それより前はサーバー上のシェルとファイルでこの構造を作るのが自然だった。 いまなら同じ構造を、マネージドサービスの上に組める。
表4: 選定フロー
| 手順 | 判断すること | 結果 |
|---|---|---|
| 1 | 多数のユーザーが同じデータを同時に更新するか | する場合は RDB を中心に設計する。この構造は集計の部分だけに使う |
| 2 | ファイルが1つ届くたびの小さな変換か | Lambda(1回の実行は最大15分) |
| 3 | 全店、全期間をまとめる重い集計か | Athena か Glue |
既定は「S3 に生データを置き、取込は Lambda、集計は Athena」になる。 シェルとテキストファイルを選ぶ理由は、すでにサーバーとシェルの運用があってクラウドを使わない場合くらいしか残っていない。
表5: LEVEL ごとの置き場と処理
| LEVEL | AWS での置き場 | 処理 |
|---|---|---|
| LEVEL1 生データ | S3 の raw 用プレフィックス | 置くだけ。バージョニングとライフサイクルで保持する |
| LEVEL2 取込 | S3 | ファイル到着のイベント、または EventBridge の定期起動で Lambda が変換する |
| LEVEL3 整理 | S3(Parquet) | Athena か Glue で集計する |
| LEVEL4 出力ごとの専用データ | 集計済みテーブル、または DynamoDB | 画面や API ごとに作る |
| 段のつなぎ | Step Functions / EventBridge | cron とシェルの代わり |
生データを残し、加工した結果を段ごとに別の層として持つ形は、いまのデータ基盤でも bronze、silver、gold の層に分ける作り方として広く使われている。 ユニケージから持ち帰れるのは、シェルという技術よりも、このデータの持ち方のほうだ。