今まで見た中で最もひどいDBのテーブル設計は? 107
ストーリー by hylom
女将を呼べ 部門より
女将を呼べ 部門より
あるAnonymous Coward 曰く、
今まで見たもっともクソなテーブル設計というブログ記事が話題になっている。
ここで言及されている「クソなテーブル」は、ありとあらゆるデータが1つのテーブルに放り込まれており、また各行にどのようなデータが納められているかを区別するための列が設けられているというものだったそうだ。
見方を変えれば最近普及が進んでいるKey-Valueストア型データベースのようにも見えるが、通常のSQLデータベースでこのような使い方をするのは確かにひどい。
ちなみにこのような設計は、SQLアンチパターンにて「Entity-Attribute-Value」として紹介されている。
1テーブルに全部格納するのは時として必要 (スコア:5, 興味深い)
後半部は兎も角、前半部(=1つのテーブルで済ます)は、通常のSQLデータベースでもそういう使い方することあるよ
殆どのフィールドを検索条件に用いることがあって、しかもテーブル全部見ないといけない検索をする時はそれが一番速いから
設計としては美しくないかもしれないけど、実用上はそのほうがいい、ってことはある
自分が見た中で一番酷かったのは、おそらくシステムの拡張への対応を手抜きするためだったんだろうけど、たとえば「電話番号」のフィールドに「携帯電話」を付け足して、「000-000-0000|000-0000-0000」みたいに「|で区切って格納すること」とかいう変な要件加えてる、みたいなDBかな。至るところにそういうフィールドが混在してるの
関係ないけどDBのテスト用IDが「scott」ではなく「tiger」とだけ書かれていたので
パスワードが「scott」なのかな、と思ったらログインできず、発行者に問い合わせたら「bunny」だったことはある
「パスワード書かなくても類推できると思った」じゃねえよ馬鹿
Re:1テーブルに全部格納するのは時として必要 (スコア:1)
「パスワード書かなくても類推できると思った」じゃねえよ馬鹿
腐った女子種目のタイ&バニの情報共有強要するのはセクハラだと訴えるべきところですね。
Re:1テーブルに全部格納するのは時として必要 (スコア:1)
長瀬智也はジャニオタよりもオッサンに人気がありそうだけどな。
Re:1テーブルに全部格納するのは時として必要 (スコア:1)
制作側がそういうつもりでも女性陣が盛り上がっているのも事実です。
Re: (スコア:0)
POSレジの伝票テーブルで1レコードに128カラムも項目があって、行番0がヘッダレコードになっていて、明細項目が行番1以降にずらずら並んでいる。1伝票処理するのに馬鹿でかいレコードを複数処理しなければならない上に、ストアドプロシージャで簡単には処理できないデータ形式だったんで、大した処理ではないのにステップ数ばかりが増える。その上開発言語がVB2だったから地獄だった。
Re: (スコア:0)
そもそも、外部のデータフォーマットそのままだったりするしね。
見易く整理するのも良いけど、ジャーナル的に使われていたりする生に近いデータだと、フォーマットを弄る方が後々祟ったりするし。
Re:1テーブルに全部格納するのは時として必要 (スコア:3, 参考になる)
Oracle触ったことがあればscott/tiger [wikipedia.org]なんて基礎知識。
元記事はエクセルに立ち向かうデータベース第一部完みたいな感じだが (スコア:2)
-- 哀れな日本人専用(sorry Japanese only) --
著者名(1)←丸1 (スコア:2)
Re:著者名(1)←丸1 (スコア:1)
予約語と衝突するカラム名使いまくり、っていうのは見たことあります。
エスケープすりゃ使える(というかカラム名は基本エスケープして書けばいい)ので、別に最悪ではないんですが…
Re:著者名(1)←丸1 (スコア:1)
Re:"開始〜終了" みたいに (スコア:1)
予備項目 (スコア:2)
今後、項目が増えたときのために、
"予備1", "予備2" ...
という列が定義されている。
実際、その項目が使われても、ドキュメントの更新がされず、何が入っているか判らなくなる。
Re:予備項目 (スコア:4, すばらしい洞察)
それはドキュメントのアップデートをきちんとしていないという、DBテーブルの設計が悪いこととは別の問題じゃないかな
項目が必要になるたびに本番でALTER TABLE叩くっていうのもそれはそれでリスクがあるわけだし、予備を定義しとくこと自体はそう間違いではないと思う
#逆に言うとどれだけ綺麗にDBテーブルの設計をしていても、改修に伴ってドキュメントのアップデートをきちんとしてなければ、それは「酷いDB」になるんだしさ
Re:予備項目 (スコア:2)
何かある度にカラム増やすのはどうかと。
Re:予備項目 (スコア:1)
そもそもストーリーで挙げられてた例もCOBOLではよくあったこと。DB設計者の方がPGより年食ってるのかも。
---- 何ぃ!ザシャー
Re: (スコア:0)
「○○を保存するようにしたいけど、カラムがないですねぇ」→「△△が使ってませんから、そこに入れることにしましょう」なんていう、カラム名と中身がまったく一致していない状態に比べれば、予備の方が格段にマシです。
説明が分かりにくいけど、このDBの真骨頂は (スコア:2, 参考になる)
> また、普通なら一行で済むデータをinsertする際にも数行ひどいときには十数行insertが必要で、
ブログをざっと見た感じだと別にそこまでひどくもないように見えたけど、よくよくこの二行みると
年と月と日で 3レコード
時と分と秒で 3レコード
内容で1レコード
の7レコード(IDは全部同じ)ていうテーブルなのかな?
こんなのだったらたしかにクソだ。というか悪夢。
1商品1テーブル (スコア:1)
新商品作るごとに新しいテーブルも作成。
でもテーブル構造は全てまったく同じ。
新商品は年に何度も発生するので都度開発依頼。
全商品の直近価格一覧表示しようとすると大量のDBアクセスが発生してやたら重い。
どうしてこうなった?
何故造った? (スコア:1)
予算の問題で設計ドキュメントが皆無だったので言迷のまま、
LDAPのstrings属性?の移植??的に延々とVARCHAR2が続く
RDBテーブル設計書(走召糸色木亥火暴)
そのままLDAP使えば良いハズなのだが…(闇)
"castigat ridendo mores" "Saxum volutum non obducitur musco"
Re:何故造った? (スコア:1)
内容には全然関係ないけど、これだけは言わせてくれ。
> ---------------------------------------- Everythings must be changed.
20世紀の伝統芸能を今に残すあんたがそのシグネチャって、ナイスジョークすぎるww
EVE Onlineの (スコア:1)
#関係ないカテゴリが混じったテーブルではないですが
アイテムの属性の種類やら数は不定なので理にかなってると思いました。
http://wiki.eve-id.net/Category:CCP_DB_Tables
SQLは結構ややこしくなりますが・・・
どことは言いませんがレセコンで… (スコア:0)
Oracle DBのレコードがvarchar2(256)の固定長。
アクセスは先頭からn文字が○○で、次のm文字が××で…。
そして、一月=1テーブル。
これでパフォーマンスを上げろと言われても。
というか、素直にCOBOLのままでええやん。
Re:どことは言いませんがレセコンで… (スコア:2)
> varchar2(256)の固定長
oracle8の頃はvarcharは可変長文字列でしたけど、最近は固定長になったのかしらん。
それはそれとして。大昔の事ですが、レセプトじゃないけど国保絡みの案件。oracle8でdecimalのフィールドをado+vbsで受けると明示的な型変換を行わないと演算出来ないのはつらかったです。
そのニ次開発で、データベースのスペシャリストと称する方の設計は、30個位ある文字列フィールドが全部固定長のchar(1024)になってて。これでストレージ足りるんですか?と聞いたら、おっとり刀で容量試算を始める始末。結果30TB位って、HDD1台で60GBとかの頃なんですけど。Sunのミッドレンジじゃ無理でしょ。
DBだけが理由では無かったですが、プロジェクトは崩壊しました。
Re: (スコア:0)
バッチをCOBOLから .Net に移植したら処理時間が2倍になったあのレセコンですね?
Re: (スコア:0)
基本設計から作り直そうとしたけど大炎上、
でもサーバリプレースは必要だからとりあえず設計は現行のままでJava,JSP,SVF,Oracleでとりあえず構築しました
とか?
ああ・・・ (スコア:0)
テーブル名が半角全角英数スペース日本語入り乱れている。
本気で馬鹿かと思ったのは (スコア:0)
インデックスが張られていない
Re:本気で馬鹿かと思ったのは (スコア:2)
その上で、フィールドは固定長の上で配列変数のような構成
こんなDB押しつけて置いて、出来上がったPGの処理が遅いと文句言われても・・・・
テーブルリンクもさせずに全フィールド取得しかさせない癖に・・・
で、正規化やらインデックス追加、テーブルリンクによる普通のSQL使用で圧倒的に早くなったサンプル見せても却下した癖に・・・
火を噴く前にスキル的な事で他プロジェクトへ回ったんで助かったけど
Re: (スコア:0)
プライマリキーすら無いよりマシ
Re: (スコア:0)
# 全部合わせて複合主キーなんだって
# 別の表は先頭32カラムだけが主キーだったけど、単にOracleの制限なだけで後ろのカラムも心の中では主キーなんだって
フィールド (スコア:0)
うーん (スコア:0)
>ありとあらゆるデータが1つのテーブルに放り込まれており、また各行にどのようなデータが
>納められているかを区別するための列が設けられているというものだった
IPAの未踏か何かでそんなのを見たような見なかったような....
心が痛い (スコア:0)
ああ、Entity-Attribute-Value作っちゃったことあります。
めったに使わない部分だったせいかこの問題はスルーされて開発は進み、後で気付いたものの言い出せなくなり・・・
運用まで見守りましたが、その後どうなったのかは知りません。
Re:心が痛い (スコア:1)
俺も。だって客が項目動的に増やせるようにしたいとか言い出すから・・・会社的な事情により、システム自体がほぼ使われなくなったらしいので、犠牲者が出なかったことだけが幸い。
あれは動的にテーブル作っちゃえばよかったのかなぁorz
# さっきSQLアンチパターンの電子書籍版買ったとこなので、これからセルフ反省会。
Re:心が痛い (スコア:2)
システム用のプロテクト掛けたファイルとユーザ用の編集可能なファイルに分け、初回実行時にPCの命名規則から前者のファイルを使ってシステム用の初期メニュー生成させていた。
ユーザ用はその後に自由にファイルや実行ファイルの登録も出来るようにして。
#Windows+VBの荒技
Re:心が痛い (スコア:1)
うんうん。動的に項目を増やしたいときにはつかっちゃうよね。
Redmine のテーブルも、チケットのカスタム項目のところはそんな風になってる。
Re: (スコア:0)
俺も。
懺悔するしかない。ごめんなさい。
Re: (スコア:0)
XMLそのまま突っ込んで、取得後パースしていた私も同罪か・・・
Re:心が痛い (スコア:1)
これ見ると、準構造化ということでセフセフみたい、俺もやっている最中なので良かった
http://penguinlab.jp/wiki/SQL_%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%... [penguinlab.jp]
「最近普及が進んでいる」とか言いますが, (スコア:0)
じつは dbm とか Berkeley DB あたりから引き継がれているデータベースだったりして…
Re:「最近普及が進んでいる」とか言いますが, (スコア:1)
いやいや、オリジナルはDOS上のdBASEやInformixだったりして。
# 糠床とか秘伝のタレ状態。
Re:うんこ (スコア:2)
Re:うんこ (スコア:2, おもしろおかしい)
DBのデータじゃなくてプログラムだけど、コメントに
ってのを見つけた時はどうしようかと思ったんだがね
まあ品質は悪くなかったけど精神的ダメージが……
Re:うんこ (スコア:2)
自分が遭遇したらかなり嫌なケース
第73回 ヌルいプログラマ [gihyo.jp]
Re:気持ちは判るが... (スコア:1)
あー数値なのに文字列型を使われてるのはあったなー。ソートすると
1
10
11
12
2
3
4
とかになりやがる。いちいちcastとかアホかと。
Oracleのカラム数上限は1000であることを体感する貴重な機会を得た (スコア:1)
メインフレーム側のデータを丸々移行するんだ!というプロジェクトに携わった際に、
DB設計者が作ったDDLによるテーブル構築時にこのエラーをたたき出したことがあります。
------------------
ORA-01792 2 表またはビューに指定できる最大列数は1000 です。
原因: 1001 列以上ある表またはビューを作成しようとしたか、列を追加しすぎたため許容できる最大の列数1000 を超えました。表にある未使用の列も最大列数1000 に含まれることに注意してください。
------------------
300カラム?まだまだっすよ。エラーが出たから2分割して500x2~ですよ。
初めて見る事例だったので、ブログに書いて記録してあります(笑)
自分は直接そのテーブルは見ないサブシステム担当だったので直撃は免れましたが、
当時、直接関与してたグループはよくモチベーション維持できたな……とw
Re:300カラムに主キー1つのテーブル (スコア:1)
元のテーブルもまじめに設計されてれば、多少のことはビューとかで何とかなるような気がします。
元々のテーブル設計が悪いなら、アプリも含めて改修したほうがよさそうです。
Re:通常のSQLデータベースでこのような使い方をするのは確かにひどい。 (スコア:1)
SQLデータベースって書いてあるんだから、RDB じゃないの?
RDB じゃないなら、SQL よりも適合性が高く効率のよいクエリ方法があるでしょう。
Re:新しい列を既存列の間に追加 (スコア:1)
列順に依存したコードって、もしかして select * して、結果配列は数値添字でアクセスですか?
DB設計ではなくコード設計の範疇ですが、素人丸出し過ぎる。。。