<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>データベース on 或る阿呆の記</title><link>https://hack-le.com/tags/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/</link><description>Recent content in データベース on 或る阿呆の記</description><generator>Hugo -- gohugo.io</generator><language>ja</language><lastBuildDate>Wed, 14 Oct 2026 16:49:30 +0900</lastBuildDate><atom:link href="https://hack-le.com/tags/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9/index.xml" rel="self" type="application/rss+xml"/><item><title>【バイブコーディング】AIがデータを捏造していた</title><link>https://hack-le.com/vibe-coding-ai-data-fabrication/</link><pubDate>Sun, 18 Oct 2026 00:00:00 +0900</pubDate><guid>https://hack-le.com/vibe-coding-ai-data-fabrication/</guid><description>&lt;p&gt;最近こんなのばっかりですが、以前&lt;strong&gt;AIに機能を捏造されていた&lt;/strong&gt;記事を書きましたが、&lt;strong&gt;今回はデータの捏造&lt;/strong&gt;です。しかも&lt;strong&gt;完全にデタラメの値ではなく、取り込んだ値を使って何か勝手なロジックにより勝手な値を算出するというもの&lt;/strong&gt;で、それによってパッと見の傾向がなんとなく正しそうに見えて、気づくのに遅れました。&lt;strong&gt;コイツほんとにそれらしさを作る天才&lt;/strong&gt;だな。&lt;/p&gt;&#10;&lt;h2 id="よくもぼくをォだましたなァ"&gt;よくもぼくをォ！！だましたなァ！！&#10;&lt;/h2&gt;&lt;p&gt;対象アプリケーションは、私がダイエット日誌のために作り始めたHealth Dashboardという自作Webアプリです。体重などは私が元々つけていたスプレッドシートを読み込ませ、また手動による入力をしていました。これは問題ありませんでした。&lt;/p&gt;&#10;&lt;p&gt;問題が生じたのは、Fitbitのデータを、APIとGoogleからのエクスポートしたCSVで過去分のデータを取り込もうとした時です。特に歩数および睡眠時間のデータを取り込もうと考えました。これは指示するとなんとなくそれらしいものが出来たように見えました。&lt;/p&gt;&#10;&lt;p&gt;嘘でした。確認できただけで、以下のような複数の問題がありました。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;睡眠スコアを勝手に独自のアルゴリズムで捏造する&lt;/li&gt;&#10;&lt;li&gt;睡眠時間の解釈が独特&lt;/li&gt;&#10;&lt;li&gt;時計をしなかった時などのデータゼロを勝手な値で補完する&lt;/li&gt;&#10;&lt;li&gt;データ取り込み経路のみ、JSTとUTCで混ざっている（API経由のときは問題ない）&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;これらはけっこう厄介で、&lt;strong&gt;パッと見はけっこうそれっぽい&lt;/strong&gt;んです。睡眠スコアは一応睡眠時間にもとづきます。睡眠時間の解釈は独特ですが一貫しているため傾向はあっています。ゼロデータの時はレアだしいつ歯抜けがあるべきかなんて覚えちゃいませんので、そこをそれらしく補完されているとどうにもなりません。また過去の値はCSV取り込みだが最新値はAPIなど経路が異なっており、かつCSV取り込みのみで起きる不具合（フォーマッタの不具合）についても、これも最新値はそれっぽいので騙されやすい。&lt;/p&gt;&#10;&lt;h2 id="やめて森の中に木を隠すのやめて"&gt;やめて…森の中に木を隠すのやめて…&#10;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;破綻に気づいたのは直近の睡眠スコアの捏造というホームラン級のファウルがあったから&lt;/strong&gt;ですね。直近の値はさすがに確認するでしょう。で、明らかに数値が異なるので、これは気づきました。そしてその原因調査の過程で、過去データなども直接参照・比較するなどして、芋づる式におかしさに気づいた、という感じです。&lt;strong&gt;こっちが指摘するまでAI言わないこと多い&lt;/strong&gt;ですよ本当に。でも&lt;strong&gt;全然言わないわけでもない&lt;/strong&gt;んです。だから余計に気づきづらい。&lt;strong&gt;木を隠すなら森の中メソッドやめろ&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;ついでに調べている中で、&lt;strong&gt;データベース設計自体が正規化されていないクソ設計であることも発覚しました&lt;/strong&gt;。これも「なんで正規化されてないのか」と言って「おっしゃるとおりです！正規化しますか？」と返され確かな殺意を感じました。&lt;/p&gt;&#10;&lt;p&gt;この部分の直接的な原因は、元々の体重入力データと、あとからきたFitbit経由の歩数・睡眠時間データの考え方をあわせる調整が必要だったから、という感じでしたかね。実際、再設計にあたって固定カラムにするかEAVにするか…ということはちょっと考えさせられました。まぁAIの「固定カラムのテーブルいっぱい作ってアプリケーションでなんか適当に帳尻あわせってそれっぽくするぞ💪」は許されませんが…設計悩むところは聞いてくれ…。&lt;/p&gt;&#10;&lt;p&gt;実はちょっと大丈夫かなぁと思ってはいたんですけどね。以前DB設計は見るべきとか言ってましたがめんどくさくなってた🥺&lt;/p&gt;&#10;&lt;p&gt;こんな感じでパンドラの箱でも開けたのかというほど悍ましい何かが次々と飛び出てきたので、対応はだいぶ時間がかかりました。内部設計の抜本的な変更、さらにその確認、その適用に、3日くらいわけでやったと思います。疲れました。仕事かよ。まぁ仕事だったら許されんエラーなのですが…。&lt;/p&gt;&#10;&lt;h2 id="そんな過去は嘘である"&gt;そんな過去は嘘である&#10;&lt;/h2&gt;&lt;p&gt;しかし思ったことは、&lt;strong&gt;恐らく仕事でも同じことになっている現場、けっこうあるんじゃないですか&lt;/strong&gt;ね。特にエンジニアのいない、少ない現場だと本当にありそう。しかもこれ、&lt;strong&gt;時限爆弾&lt;/strong&gt;ですからね。&lt;/p&gt;&#10;&lt;p&gt;この&lt;strong&gt;AIによるデータ捏造問題はけっこう深刻&lt;/strong&gt;ですよ。&lt;strong&gt;ロジックは修正できますが、データの修正は必ずしもできません&lt;/strong&gt;。たとえばデータにする過程で、計算した結果を正規データとして保存し計算元を破棄するようなものだと、あとで嘘だったとわかったときにもはや再現不可能です。&lt;/p&gt;&#10;&lt;p&gt;理想的にはデータの入力元はすべて残せ！となりますが膨大なデータになる可能性もあり、その負荷は必ずしも現実的ではありませんし、場合によっては物理的に不可能です。またデータの取得プログラムレベルで混入されていたら終わりです。とはいえ、&lt;strong&gt;可能な限り入力ソースは可能な限り信頼できるところからの一次データを残すべき&lt;/strong&gt;でしょう。&lt;/p&gt;&#10;&lt;p&gt;しかしそうした対応をしたところで、何をどうしても、&lt;strong&gt;間違えたデータにもとづいて決断されたアクションを巻き戻すことはできません&lt;/strong&gt;。時間ばかりは不可逆です。自分一人なら罪も自分一人で引き受ければいいですけれど、これが他人を巻き込んだものだと、どうにもなりませんやね。&lt;/p&gt;&#10;&lt;p&gt;真面目な話、データを取り込む系の機能をAIに書かせたやつ、一度ちゃんと見たほうがいいと思いました。&lt;strong&gt;特に仕様改修を重ねているものなんかは、前の仕様に引きずられる可能性が高くなるので、要注意&lt;/strong&gt;ですね。&lt;/p&gt;&#10;&lt;p&gt;一応軽く対応をまとめますと、チェックポイントは以下ですかね。&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;入力ソースはどこからどう取得したか。どこで保存されるか&lt;/li&gt;&#10;&lt;li&gt;直近のデータと過去のデータでそれぞれ、1単位でズレがないか&lt;/li&gt;&#10;&lt;li&gt;欠損や異常値が再現するか&lt;/li&gt;&#10;&lt;li&gt;入力経路が複数ある場合それぞれ実行し、再現性と同一性はあるか&lt;/li&gt;&#10;&lt;li&gt;（エンジニアは）DB設計の適切さ&lt;/li&gt;&#10;&lt;li&gt;（エンジニアは）システムの入力と出力を完全に、処理を定性的に説明できるか&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;まぁ基本といえばそうなんですが、これの実行は言うは易しでめんどくさいですよ本当に。&lt;strong&gt;結局最後は手間をどれだけかけるか&lt;/strong&gt;なんだなぁ……。&lt;/p&gt;&#10;&lt;p&gt;&amp;lt;関連記事&amp;gt;&lt;/p&gt;&#10;&lt;div class="blog-card-wrapper"&gt;&#10; &lt;a href="https://hack-le.com/vibecoding-jenga/" class="blog-card"&gt;&#10; &lt;div class="blog-card-content"&gt;&#10; &lt;div class="blog-card-label"&gt;&#10; &lt;svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"&gt;&lt;/path&gt;&lt;path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"&gt;&lt;/path&gt;&lt;/svg&gt;&#10; &lt;span&gt;あわせて読みたい&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-title"&gt;バイブコーディングでジェンガが崩壊したらどうするのか？&lt;/div&gt;&#10; &lt;div class="blog-card-url"&gt;/vibecoding-jenga/&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-thumbnail"&gt;&#10; &lt;img src="https://hack-le.com/images/uploads/2026/09/eyecatch_52262_1789490744.webp" alt="バイブコーディングでジェンガが崩壊したらどうするのか？" loading="lazy" /&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;div class="blog-card-wrapper"&gt;&#10; &lt;a href="https://hack-le.com/vibecoding-db/" class="blog-card"&gt;&#10; &lt;div class="blog-card-content"&gt;&#10; &lt;div class="blog-card-label"&gt;&#10; &lt;svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"&gt;&lt;/path&gt;&lt;path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"&gt;&lt;/path&gt;&lt;/svg&gt;&#10; &lt;span&gt;あわせて読みたい&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-title"&gt;バイブコーディングでDB不整合が生じる&lt;/div&gt;&#10; &lt;div class="blog-card-url"&gt;/vibecoding-db/&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-thumbnail"&gt;&#10; &lt;img src="https://hack-le.com/images/uploads/2026/09/eyecatch_52493_1789622562.webp" alt="バイブコーディングでDB不整合が生じる" loading="lazy" /&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;/div&gt;&#10;&#10;</description></item><item><title>バイブコーディングでDB不整合が生じる</title><link>https://hack-le.com/vibecoding-db/</link><pubDate>Fri, 18 Sep 2026 00:00:00 +0900</pubDate><guid>https://hack-le.com/vibecoding-db/</guid><description>&lt;p&gt;バイブコーディングで破綻したらどうなるかなぁという記事を先日書いたばかりなのですが、なんか自分用アプリで早速破綻？しました。&lt;/p&gt;&#10;&lt;h2 id="データベース不整合"&gt;データベース不整合&#10;&lt;/h2&gt;&lt;p&gt;まぁ破綻というほどではないのですが、データベースで仕様上あってはならない不整合が生じた形ですね。具体的には、10の要素のうち1つのみenabledでほかはdisabledになる仕様のものがありましたが、最近追加した機能の利用により、意図せずして複数のenabledが生じる状態になりました。&lt;/p&gt;&#10;&lt;p&gt;そもそものデータベース設計に問題があるような気はしつつ、とりあえず修正し、そのうえでそもそもコードの行数が大きすぎないだろうか、とAIに聞いたところ例によって「まったくそのとおりです。リファクタリングが必要です」などと供述し…。&lt;/p&gt;&#10;&lt;p&gt;まぁこんな状態でした。&lt;/p&gt;&#10;&lt;p&gt;&lt;img loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://hack-le.com/images/uploads/2026/09/image-1.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;oh&amp;hellip;。1000行以上が複数、最大で3000行近くのものもあり、といったところですね。さらに聞いてみるともっとも肥大化したdb.tsは15のドメインが単一ファイルに含まれているとのことで、どうしてこんなになるまで放っておいたんだみたいな状態でした。&lt;/p&gt;&#10;&lt;p&gt;ということで大規模なリファクタリング計画が実施されます。その計画自体はAIにさせましたが、十回以上に分割して、都度挙動を確認しながらやることになりました。修正自体はAIがやったとはいえ、確認はありますし、またけっこうな時間かかりましたね。&lt;/p&gt;&#10;&lt;h2 id="そもそも設計がおかしい"&gt;そもそも設計がおかしい&#10;&lt;/h2&gt;&lt;p&gt;リファクタリングをした後に、そもそも論としてデータベース設計がおかしいよなぁということで、見直しました。状態は10のレコードがあって、それぞれstatusとしてenabled/disabledのboolをもち、1つだけenabledになる、という奇妙なものでした。この排他制御はアプリケーション側でやらざるを得ず、データベース上は不整合が生じうる状態です。&lt;/p&gt;&#10;&lt;p&gt;なのでこれは設計を変更し、一つのレコードのIDをactiveとして指定するようにしました。これによって、データベース上も不整合は生じなくなります。&lt;/p&gt;&#10;&lt;p&gt;最初からそうしとけばいいじゃないかという話なんですが、これもまた歴史的経緯によります。このアプリケーションは大昔自分がCLIで手作りしていたものがベースになっており、当時データはJSONファイルを扱うだけの簡易的なもので、IDの概念もリレーショナルの概念もありませんでした。&lt;/p&gt;&#10;&lt;p&gt;で、AIのおかげでGUIにできるし、DBもSQLiteにしたほうがいいぞなということで、いつだったか移行したんですけれど、その時に従前の仕様もかなり引きずられることになりました。正直この設計はよろしくない、とは思っていたのですけれど、なんか動いているんでまぁいいかと放置していました。&lt;/p&gt;&#10;&lt;p&gt;で、バグが生まれたってわけ。&lt;/p&gt;&#10;&lt;h2 id="それが僕には面倒くさかったから"&gt;それが僕には面倒くさかったから&#10;&lt;/h2&gt;&lt;p&gt;まぁ、マイグレーションの時点で以前の設計はとりあえず残しておくのはいいと思うんですよ。まぁでも、おかしいよなと思った時点でさっさと手を付けるべきではありました。ただ設計変更ってどうしても考えてプロンプト打たないといけないので、結局面倒くさいんですよね…で、その結果もっと面倒くさいことになるといういつものあれ。&lt;/p&gt;&#10;&lt;p&gt;なので、バイブコーディングでDB不整合が生じたというより、&lt;strong&gt;人間がサボったので不整合が生じた&lt;/strong&gt;というほうがいいのかもしれないんですが、しかし、&lt;strong&gt;移行などに伴って、以前の設計が現在適切ではないにも関わらず残ってしまう、はAIプログラミング時代において、気付ける人が限られるという点でけっこう深刻なんじゃないでしょうか&lt;/strong&gt;、と強引にまとめて終わり。&lt;/p&gt;&#10;&lt;p&gt;&amp;lt;関連記事&amp;gt;&lt;/p&gt;&#10;&lt;div class="blog-card-wrapper"&gt;&#10; &lt;a href="https://hack-le.com/vibecoding-jenga/" class="blog-card"&gt;&#10; &lt;div class="blog-card-content"&gt;&#10; &lt;div class="blog-card-label"&gt;&#10; &lt;svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"&gt;&lt;/path&gt;&lt;path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"&gt;&lt;/path&gt;&lt;/svg&gt;&#10; &lt;span&gt;あわせて読みたい&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-title"&gt;バイブコーディングでジェンガが崩壊したらどうするのか？&lt;/div&gt;&#10; &lt;div class="blog-card-url"&gt;/vibecoding-jenga/&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-thumbnail"&gt;&#10; &lt;img src="https://hack-le.com/images/uploads/2026/09/eyecatch_52262_1789490744.webp" alt="バイブコーディングでジェンガが崩壊したらどうするのか？" loading="lazy" /&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;div class="blog-card-wrapper"&gt;&#10; &lt;a href="https://hack-le.com/2022-11-21-22-vaccine/" class="blog-card"&gt;&#10; &lt;div class="blog-card-content"&gt;&#10; &lt;div class="blog-card-label"&gt;&#10; &lt;svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"&gt;&lt;/path&gt;&lt;path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"&gt;&lt;/path&gt;&lt;/svg&gt;&#10; &lt;span&gt;あわせて読みたい&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-title"&gt;ワクチンは4回までらしい&lt;/div&gt;&#10; &lt;div class="blog-card-url"&gt;/2022-11-21-22-vaccine/&lt;/div&gt;&#10; &lt;/div&gt;&#10; &lt;div class="blog-card-thumbnail"&gt;&#10; &lt;img src="https://hack-le.com/images/uploads/2026/09/eyecatch_10566_1789618330.webp" alt="ワクチンは4回までらしい" loading="lazy" /&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;/div&gt;&#10;&#10;</description></item></channel></rss>