文書
life / research / technology / 2026-09-15
作成
秘書 あおい
宛先
shika さん
件名
同じ銘柄の別製品(特定名称違い・精米歩合違い・独自の名前・生原酒 など)を図鑑でどう持つか
観測
2026-09-15 JST。検討は昼、実装と検証は 20:20〜20:50(ローカルの Supabase と型検査・静的解析)。クラウドの DB は見ていない・触っていない
銘柄
と姿

Data model — brand, variant, attribute

図鑑の 1 マスは「銘柄」、製品は中の「姿」にする

同じ「獺祭」でも磨きの違いで味が違い、同じ「十四代」でも中取り無濾過と龍の落とし子は別物だ。この違いを図鑑で別の番号にするか、1 つの番号の中の姿違いにするかを比べた。結論は後者で、さらに「生・原酒・無濾過・季節もの」は図鑑のマスターに入れず、投稿に付く属性として持つ 3 層構造をすすめる。

同日夜に shika さんが方針を決めた。1 マス=銘柄は維持、姿の分母は蔵元公式サイトの定番だけ、それ以外はユーザーが名前を打って自分の姿として記録(運営への登録は不要)、生酒・原酒・無濾過は投稿ではなく姿(製品)のマスター情報。これに沿ってローカルで実装・検証した(§7〜§9)。初回の銘柄数の検討は §10。

377 / 975
候補データの銘柄数 / 製品数。1 銘柄あたり平均 2.59 本
約 390
「151 銘柄」を今のテーブルに入れたときのマス数の見積り(151 × 2.59)
70 銘柄
同じ特定名称の製品を 2 本以上持つ(例: 獺祭は 4 本とも純米大吟醸)
85 本
975 本のうち、名前に特定名称の語が入っていない製品(久保田 千寿・黒龍 石田屋・新政 亜麻猫 など)
8 種
国の表示基準の特定名称。生・原酒などは別枠の任意記載
銘柄単位
さけのわのデータ API は、味のチャートもランキングも銘柄に付く

1. 先に結論

決まった形(2026-09-15 夜、shika さん決定): 銘柄 = 図鑑の 1 マス / 製品 = 姿 / 属性 = 姿の情報

  1. 図鑑番号と完成率の分母は銘柄のまま。どの姿を飲んでも、その銘柄のマスが埋まる。今の図鑑・祝福・称号・飲める場所はそのまま動く
  2. 銘柄の詳細に「姿の図鑑」を入れ子で出し、達成率を見せる。分母は蔵元の公式サイトに載っている定番の製品だけ
  3. 定番に無い姿(季節限定など)は、ユーザーが名前を打って自分の姿として記録する。運営への登録は要らず、本人の図鑑にだけ、公式の姿と同じ見た目でその銘柄の中に並ぶ(分母には入らない)
  4. 生酒・原酒・無濾過などの属性は、投稿ではなく姿(製品)に付く情報としてマスターに持つ。自分の姿は、作るときに属性を選ぶ。昼の案(属性は投稿のチップのまま)はこの決定で取り下げた
  5. 姿は名前を解析して作らない。規格(特定名称・精米歩合・米・酵母)は列で持ち、表示はラベルの名前そのまま(§4)

2. いまの作りで起きていること(事実)

3. 日本酒の「違い」は 3 つの層にある

国税庁「清酒の製法品質表示基準の概要」を読むと、ラベルに書ける違いは性質の違う 2 つの枠に分かれている。そこに蔵ごとの製品ラインが重なる。

層例性質図鑑での持ち方
銘柄獺祭・十四代・田酒ブランド。蔵に紐づき、何年も変わらない図鑑の 1 マス(マスター)
製品(姿)獺祭 磨き二割三分/田酒 特別純米/新政 No.6 S-type蔵の定番ライン。特定名称・精米歩合・米で決まることが多いが、特定名称だけでは区別できない(獺祭の 4 本はすべて純米大吟醸)銘柄の中の姿(マスター。定番だけ)
状態・時期生原酒・無濾過・ひやおろし・しぼりたて・その年の限定同じ製品の出荷形態や季節で変わる。年度やロットで出たり消えたりする定番なら公式の姿の属性(マスター)。季節限定などはユーザーが作る自分の姿の属性

表示基準で分かったこと

状態・時期を姿としてマスターに入れると、たとえば「特定名称 8 × 火入れの別(生酒・生貯蔵・生詰・火入れ)4 × 原酒か否か 2 × 無濾過か否か 2 = 128 通り」が 1 銘柄ごとに候補になる。実際に出ているのはその一部だが、どれが出ているかを運営が毎年追う必要が出る。

4. 製品の分かれ方は、名前からは読めない

shika さんの指摘どおり、蔵が製品を分ける軸は特定名称だけではない。候補データ 975 本を名前で数えると、分け方は少なくとも 6 通りある(件数はスクリプトで名前の文字列を数えたもので、分類の重なりを含む)。

分け方候補データの例件数の目安名前から読めるか
特定名称で分ける田酒 特別純米酒/純米吟醸/純米大吟醸—読めることが多いが、「純吟」「上撰」のような略称・旧呼称も混ざる
精米歩合で分ける獺祭 純米大吟醸 45/磨き三割九分/磨き二割三分、七田 純米 七割五分磨き30 本読めない。名前の数字や「磨き」「割」を含む 30 本のうち、玉川 Time Machine 1712・三井の寿 +14 大辛口・亀泉 CEL-24 は精米歩合ではない。書き方も「45」「50%」「精米歩合50」「二割三分」「七割五分磨き」とばらばら
米・酵母で分ける而今 純米吟醸 山田錦/千本錦、鍋島 純米吟醸 山田錦/五百万石、亀泉 CEL-24/高育63号71 本酒米名は読めるが、酵母の名前は記号で読めない
独自の名前を付ける久保田 千寿/萬寿、〆張鶴 純/月/花、黒龍 石田屋/しずく、新政 亜麻猫、北雪 大吟醸 YK3585 本読めない(名前に特定名称の語が無い)
名前に銘柄名が入らない赤武 → AKABU 純米酒、加茂錦 → 荷札酒 黄水仙、五人娘 → 醍醐のしずく、大嶺 → Ohmine 3grain27 本読めない。ローマ字表記・シリーズ名・別名で売られている。中には別の銘柄として扱うべきものが混ざっている可能性がある(未確認)
年度で名前が変わる産土 2022 山田錦/2022 穂増—年を姿の名前に含めると毎年新しい姿が増える

YK35 について。特定の蔵の製品名ではなく、山田錦(Y)・熊本酵母とも呼ばれる 9 号酵母(K)・精米歩合 35%(35)で造れば鑑評会で金賞が取れる、という業界の通称(Wikipedia「YK35」。二次情報)。候補データでは北雪が製品名に使っている。つまり同じ文字列が複数の蔵の製品名になりうるし、名前の「35」を精米歩合と読むのは偶然合っているだけ、という典型。

さらに、1 つの蔵が別の銘柄として出しているものもある。候補データで 1 蔵に 2 銘柄あるのは 10 蔵(黒龍酒造の黒龍と九頭龍、油長酒造の風の森と鷹長、清水清三郎商店の作と鈴鹿川 など)。

ここから決まる設計の約束

  1. 姿の見分けは名前ではなく key でする。候補 JSON の products[] に key を足し、ID はそこから作る。いまの gen-seed.py は製品 ID を製品名から作っているので、表記を直すだけで ID が変わり、その製品に付いた投稿が迷子になる(今のうちに直すべき既存の穴)。移行時は、今の名前から作った ID をそのまま key の初期値にすれば ID は変わらない
  2. 規格は列で持ち、名前から推測しない。特定名称・精米歩合・米・酵母はすべて NULL を許す列にする。「YK35」「石田屋」の精米歩合は、裏取りできたときだけ入れる。姿の比較や絞り込み(「精米歩合 40% 以下の姿」)はこの列を使う
  3. 表示はラベルの名前をそのまま持つ。「銘柄名+特定名称」で組み立てない。label_name(「北雪 大吟醸 YK35」「荷札酒 黄水仙 純米大吟醸」)と、姿の一覧で使う短い variant_name(「YK35」「黄水仙」「磨き二割三分」)の 2 本
  4. 呼び方の揺れは別名で吸収する。「AKABU」「あかぶ」「二割三分」「YK-35」「YK35」を別名として登録し、検索と自由記述の紐づけに使う。複数の銘柄に当たる別名(YK35 のような通称)や短すぎる別名は自動で紐づけず、候補として出すだけにする(別名テーブルと姿の名前での検索は今回は未実装)
  5. 銘柄か姿かの線引きは「ラベルに親の銘柄名が主に書かれているか」。書かれていれば姿(黒龍 石田屋)、書かれていなければ同じ蔵でも別の銘柄(九頭龍)。ラベルの写真で誰でも同じ判断ができる基準にする。迷うもの(荷札酒・AKABU のようなシリーズ名)は運営が 1 件ずつ決め、決めた結果は別名で両方の呼び方から引けるようにする
  6. 年度は姿にしない。「産土 2022 山田錦」は姿「産土 山田錦」+投稿の醸造年度(任意)。毎年マスターが増えない
  7. 属性は姿に持たせる。十四代 中取り純米 無濾過のような定番は、公式の姿の属性に「無濾過」を持つ。季節の生原酒版は公式の姿にせず、飲んだ人が自分の姿として属性つきで作る。属性をマスターの姿の数に掛け算しない
  8. リニューアルは「名前が変わったら新しい姿」。名前が同じで精米歩合だけ変わったなら同じ姿の列を直す。名前が変わったら新しい姿を作り、古い姿は定番から外して「後継」を指す。過去の投稿は古い姿のまま残る

5. 3 つの案

案 Aいまの形

製品ごとに別のマス(完全に別銘柄)

「獺祭 純米大吟醸 45」と「獺祭 磨き二割三分」が別の図鑑番号。飲んだ製品がそのまま 1 マス。

良いところ
テーブルが 1 枚で単純。味の集計が最初から製品単位で細かい。「全部違う酒」という実感とは合う
困るところ
分母が約 390 に膨らみ、1 杯目の達成感が薄い。季節限定・終売の製品が入ると二度と埋まらないマスができ、コンプリートが原理的に不可能になる。十四代のような入手困難な銘柄が 4 マス分の壁になる。居酒屋で「獺祭の何か」まで分からないと記録できず、マスターに無い酒の問題が増える。マスターの手間は製品数に比例する
実装済み分母が膨らむ永久欠番が出る
案 Bすすめる

銘柄が 1 マス、製品はその中の姿

図鑑番号は銘柄に付く。どの製品を飲んでもマスが埋まる。銘柄の詳細を開くと姿の一覧があり、飲んだ姿に印が付く。姿の分母は定番の製品だけ。

良いところ
分母が 151 のまま。1 杯目で必ず 1 マス埋まる。姿集めという 2 周目の遊びが自然に生まれる(メインの達成を邪魔しない)。季節限定は分母の外に「番外の姿」として置ける。姿を選ばなくても記録できるので投稿の手間が増えない。アンケートの単位(銘柄)と図鑑の単位が一致する。候補 JSON がすでにこの形
困るところ
テーブルが 1 枚増え、DB 関数 5 つとアプリの図鑑まわりに手が入る。「生原酒はまるで別の味なのに同じマス」という違和感は残る(属性別の味の表示で補う)。姿の分母に何を入れるか(定番の定義)を運営が決める必要がある
分母が安定永久欠番なし候補データと同じ形改修が要る
案 C中間

銘柄 × 特定名称で 1 マス

「獺祭 純米大吟醸」「田酒 特別純米」「田酒 純米吟醸」を別のマスにする。製品ラインは持たず、特定名称の 8 種+その他で切る。

良いところ
切り方が国の基準に沿っていて曖昧さが無い。製品マスターを作らなくてよい
困るところ
70 銘柄では同じ特定名称の製品が複数あり、獺祭は 4 本が 1 マスに潰れる。一方で田酒は 4 マスに割れ、銘柄ごとにマス数がばらばらになる。蔵が出していない特定名称をマスにできないので、結局銘柄ごとの一覧が要る。「新政 No.6」のように特定名称を前に出さないブランドと相性が悪い。案 A と案 B の悪いところを両方持つ
マス数が銘柄ごとにばらつく

6. 比べる

観点A 製品ごとB 銘柄+姿C 銘柄×特定名称
1 杯目で埋まる手触り製品まで分かれば埋まる銘柄が分かれば必ず埋まる特定名称まで分かれば埋まる
完成率の分母約 390(151 銘柄の場合の見積り)151銘柄の製品構成しだい
永久に埋まらないマス季節限定・終売で発生分母は定番だけなので出ない特定名称の終売で発生しうる
2 周目の遊び無い(全部が 1 周目)姿集め・姿コンプの称号無い
投稿の手間製品を正確に選ぶ必要銘柄だけで可、姿は任意特定名称の選択が必須
マスターに無い酒製品単位で漏れる銘柄が入っていれば記録できる銘柄×特定名称で漏れる
運営のマスター作業製品数に比例、季節ものを毎年追う銘柄が必須、定番の姿は後から足せる銘柄ごとに特定名称を確認
味データの粒度製品単位(ただし 1 製品あたりの投稿は少ない)銘柄・姿・属性の 3 段で出せる銘柄×特定名称
さけのわとの差製品単位の味は差になるが、図鑑が埋めにくい「埋め切れる図鑑」を守りつつ、姿・属性別の味で差—
いまからの改修不要DB 1 本+生成スクリプト+アプリ図鑑まわりB と同程度

「約 390」は候補データの平均(975 ÷ 377 = 2.59 本)を 151 に掛けた見積りで、採用される 151 銘柄の実数ではない。

7. 実装したデータ構造

昼の §6 までは「銘柄テーブルを新設する」案で書いていたが、実装では既存の sake_products を銘柄(1 マス)として残し、その下に姿のテーブルを足す形にした。図鑑番号・進捗・称号・飲める場所の DB 関数と、アプリの 16 ファイルの参照を変えずに済むため。

マイグレーション: shushu-supabase/supabase/migrations/20260915000001_sake_variants.sql

もの中身守っていること
sake_products(既存)銘柄 = 図鑑の 1 マス。変更なし図鑑番号・collection_progress()・award_badges()・飲める場所は銘柄単位のまま
sake_variants(新規)公式の姿。name(ラベルの名前そのまま)・variant_name(短い名前)・特定名称・精米歩合・米・酵母・度数・attribute_tags・source_url(定番の根拠にした公式ページ)・並び順・is_listed誰でも読めるが、クライアントからは足せない。is_listed = false(終売)は分母から外すが行は消さない
user_sake_variants(新規)自分の姿。名前・特定名称・精米歩合・属性。同じ人・同じ銘柄・同じ名前(表記ゆれは正規化で吸収)は 1 行読めるのは本人と、その姿が付いた投稿を見られる人だけ(投稿の公開範囲に従う)。作る・直す・消すは本人だけ
posts.sake_variant_id / user_variant_id(新規)どちらか一方、または無し(銘柄だけの記録)トリガー sync_post_variant(): 姿を付けると銘柄はその姿の銘柄に揃う/他人の姿は付けられない/編集で銘柄だけ変えたら前の姿は外れる
posts.attribute_tags削除(09-14 に入れた列。クラウド未反映だった)属性は姿の attribute_tags に移した。許す値は DB 関数 sake_attribute_tags_valid() とアプリの constants/tags.ts で二重に固定
variant_progress(銘柄)銘柄詳細の姿の図鑑。公式の姿・自分の姿・達成率(記録した定番 / 定番の数)・姿を選ばずに記録した件数を 1 往復で分母は公式の定番だけ。終売は自分が飲んだものだけ出す
variant_counts()図鑑カードの「姿 2/4」を全銘柄分 1 回で銘柄 ID を URL に並べない(09-13 の 414 の教訓)
scripts/gen-seed.py候補 JSON の brand → sake_products、products → sake_variants。姿の ID は products[].key から作る(省略時は名前)精米歩合・属性・特定名称の値を生成前に検査(不正なら終了コード 2)

8. 画面(shushu-app)

画面変えたことファイル
投稿の作成・編集銘柄の下に「姿」を置いた。公式の定番と自分の姿を同じチップで並べ、無ければ「+ 名前を入力」で名前・特定名称・属性を入れる。投稿の時点で自分の姿を作る。投稿の「酒の属性」チップは削除。銘柄を選び直すと姿は外れるcomponents/post/VariantPicker.tsx(新規)、screens/post/PostCreateScreen.tsx、PostEditScreen.tsx
銘柄詳細「姿の図鑑」を入れ子で表示。達成率(記録数 / 定番数・%)のバー、公式の定番のマス、「自分で記録した姿」のマス(同じ見た目に「マイ」印)、姿を選ばずに記録した件数。マスを押すと、その姿を選んだ状態で投稿画面が開く。銘柄情報から特定名称・米・酵母・度数の行を外した(姿ごとに違うため)components/collection/VariantDex.tsx(新規)、screens/collection/SakeDetailScreen.tsx
図鑑一覧収集済みのカードに「姿 1/4」SakeProductCard.tsx・CollectionGrid.tsx・CollectionScreen.tsx・stores/collectionStore.ts
投稿の表示名前は「銘柄 姿」(新政 極上 純米吟醸 生原酒)。投稿詳細に「姿: …(マイ)」と「姿の属性」PostCard.tsx・PostGridCard.tsx・TimelinePostCard.tsx・PostDetailScreen.tsx、取得列は services/posts.ts・timeline.ts・collection.ts

制約。オフラインで投稿した場合、新しく名前を打った姿は作成に通信が要るので付かない(銘柄だけの記録になる)。公式の姿と既存の自分の姿はオフラインでも付く。

9. 検証した結果

観測 2026-09-15 20:30〜20:50 JST。ローカルの Supabase で supabase db reset → scripts/seed-test-data.py(自分の姿 2 件を含む)を流したうえで、ロールを切り替えて SQL を実行した。

確かめたこと結果
姿を付けた投稿の銘柄が、姿の銘柄に揃う5 件すべて一致
tester の variant_progress(新政 極上)定番 4 のうち 1 を記録、終売「旧ラベル」は出ない、自分の姿「極上 ひやおろし 2026」が 1 件
公式の姿をクライアント権限で足す拒否: new row violates row-level security policy for table "sake_variants"
不正な属性で自分の姿を作る拒否: violates check constraint "user_sake_variants_attribute_tags_check"
他人の姿を自分の投稿に付ける拒否: user_variant_id must belong to the post owner
姿の付いた投稿で銘柄だけ変える姿が外れる
別の銘柄の公式の姿を付ける銘柄がその姿の銘柄に変わる
非公開投稿に付けた自分の姿が、相互フォローの花子・未ログインから見えるか見えない(本人からは見える)
花子が tester の銘柄の姿の図鑑を引く自分の姿は空、記録 0(他人の記録は混ざらない)
公開投稿に付いた他人の姿の名前花子からも未ログインからも見える(投稿が見える範囲と同じ。仕様として §11 で確認)
図鑑の進捗銘柄単位のまま(total 500 / collected 6)
シード生成(候補 east.json をスクラッチに生成。本物の seed.sql は上書きしていない)銘柄 137・姿 339 を出力
アプリの型検査 npx tsc --noEmit・静的解析 npm run lintどちらも終了コード 0

まだやっていないこと。実機・シミュレータでの画面確認(見た目は未確認)。クラウドへの反映(未反映のマイグレーションは 09-13・09-14×2・09-15 の 4 本)。姿の名前での検索(「YK35」で引ける別名テーブル)。姿コンプの称号。

10. 最初に入れる銘柄数

調査エージェントがアンケート回答 13 件(tally.py の突き合わせ)と候補データをスクリプトで数え、蔵元公式サイトを 2026-09-15 20:20〜20:42 JST に取得して定番を数えた。「実測」「見積り」を分けて書く。

アンケートと県の被覆(実測)

票には自然な切れ目が 2 か所ある。3 票以上 = 54 銘柄、2 票以上 = 92 銘柄。ちょうど 50 や 100 にすると、境界の同票(3 票の 27 銘柄、1 票の 138 銘柄)から誰かが選ぶことになる。

選び方銘柄数挙がった酒の被覆(173 銘柄を挙げた回答 3 を除く延べ票)覆える県
票順5062.7%23 / 47
各県 1 銘柄を先に確保 → 票順5044.5%47 / 47(46 県が 1 銘柄)
3 票以上 54 + 県埋め 237770.7%47 / 47(35 県が 1 銘柄)
票順10085.9%32 / 47
2 票以上 92 + 県埋め 1510785.9%47 / 47(24 県が 1 銘柄)
票順15192.4%37 / 47

被覆は 50 → 100 で大きく伸び、100 → 151 ではあまり伸びない。票が 0 の県(香川・愛媛・長崎・宮崎)は、塗り絵のために入れるなら何を入れるかを人が決める必要がある。

公式サイトの定番の数(11 銘柄を実測)

銘柄定番(下限〜上限)メモ
冩樂2残りはすべて発売月付きの季節品
而今0〜2ほぼ全商品に出荷月が付く。「毎年同じ月に出る」を定番と数えると 26
上善如水4
黒龍5〜6限定品・季節限定品を除く
獺祭6〜17限定の表記が無いシリーズが定番か判別できない
八海山6〜12「数量限定」だけの 6 本の扱いで幅
久保田9季節限定 7 は除く
新政11〜12公式サイトの掲載が 2021 年度のまま。現行の構成は未確認
酔鯨13〜15
一ノ蔵15〜20「限定品」表記の意味が同社ページ内で食い違う
浦霞21〜23県内限定 7・季節限定 9 は除く

11 銘柄の中央値は下限 6・上限 12、平均は 8.36〜11.09。田酒は商品名が画像で総数が未確認、十四代は公式サイトが無いとの二次情報しか無く測れなかった。入手困難な人気の銘柄ほど、「公式サイトの定番」を分母にすると姿の図鑑が空に近くなる。

姿の数と作業時間(見積り)

仮定: 1 銘柄あたりの固定の手間 25 分(公式サイトを探し、定番の境界を決める)+ 1 製品あたり 8 分(規格と属性を確かめて入力)。

銘柄数姿の総数作業時間週 10 時間なら
50約 300〜550約 60〜95 時間約 8 週
77約 460〜850約 95〜150 時間約 10〜15 週
100約 600〜1,100約 120〜190 時間約 15 週
151約 900〜1,700約 180〜290 時間—

77 は 100 の値を 77/100 倍した近似。画像の権利確認・読み仮名・紹介文は含まない。

すすめる数: 初回 77 銘柄(3 票以上の 54 + 県埋め 23)→ 第 2 弾で約 110〜120 → その後 151

  1. 票の切れ目で説明がつく。「3 人以上が挙げた銘柄 + 全県 1 銘柄」は、誰かの好みで選ばずに一意に決まる
  2. 初回から 47 県の塗り絵が成り立つ。票順 50 は 23 県、票順 100 は 32 県しか覆えない
  3. 100 → 151 で被覆はあまり増えない。急いで 151 にする理由がデータから出ない
  4. 番号は続き番号にし、第 2 弾を「第 2 世代」と呼べる。Pokémon GO は初代で始め、2017-02-15 の公式投稿でジョウト地方の 80 匹超を一括追加した
  5. 姿の作業が重ければ、銘柄の図鑑は初回に全部出し、姿の図鑑は裏取りの済んだ銘柄から順に開く。分母の定義(公式の定番)は変えず、公開の時期だけを分ける。工数を最優先するなら 50(県埋め込み)にする

11. 決めてほしいこと

  1. 初回の銘柄数。すすめるのは 77(3 票以上 54 + 県埋め 23)。50 か 100 にする手もある
  2. 「定番」の定義。而今・冩樂のように月替わりの蔵、十四代のように公式サイトが無い蔵の扱いを決める。候補は、毎年同じ月に出るものも定番に含める/公式サイトが無い銘柄は姿の図鑑を「準備中」にする/MVP では銘柄ごとに姿の数に上限を置く
  3. 姿の図鑑を銘柄と同時に全部出すか、裏取りの済んだ銘柄から順に開くか。
  4. 称号の区切り(1・5・10・25・50・100・全制覇)と「151」前提の文言の直し方。77 なら 50 の次が全制覇になる。共有カードの「12 / 151」、キャッチの「まずは 151。」も直す必要がある
  5. 公開投稿に付けた自分の姿の名前が、他人や未ログインの人に見えてよいか。ユーザーが打った文字列が他人の画面に出るので、通報の導線の対象になる。見せないなら、他人の画面では姿を伏せて銘柄名だけ出す
  6. 姿コンプの称号と、姿の名前(YK35 など)での検索を、ファーストリリースに入れるか。
  7. クラウドへの反映時期。未反映のマイグレーションは 4 本

出典