DB+CSV形式での情報サイト開発のデメリットとは?

このQ&Aのポイント
  • PHP+MySQLで情報サイトの開発を行っている際、お客さんからの仕様変更が頻繁にあります。
  • 共通項目は20カラムほどあり、非共通カラムは60〜70カラムあります。
  • 非共通カラムをCSV形式で管理することを考えていますが、この設計にはデメリットがあります。
回答を見る
  • ベストアンサー

DB+CSV

今、仕事を受注してPHP+MySQLで情報サイトの開発を行っているのですが お客さんが結構頻繁に仕様を変更を要求してきたり ・共通項目は20カラムほど ・非共通カラムは60~70カラム 計80~90(100)カラムx7種類って感じになりそうです。 でこの非共通カラム部分をCSV形式で管理するのはどうかな?っと思ったのですが (正規化して共通部分とそうでない部分をわけろって言われそうですが) デーブル設計を 主キーカラム(オートナンバー) 共通項目Aカラム 共通項目Bカラム 共通項目Cカラム 情報タイプ(7種類ほど) CSVを格納するカラム CSV部分の設計は 「項目名(値)」って感じにそればいいかなって思いました。 (や)や仕切り部分「,」に関してユーザが入力した場合はPHP上で全角に置換してデータベースに格納 例) A(1),B(あいうえお),C(0)・・・・・・ A(0),B(かきくけこ),C(0)・・・・・・ A(0),B(たちつけと),C(1)・・・・・・ A(1),B(かきくけこ),C(0)・・・・・・ で検索時にはWhere部分を 非共通項目のカラム名をitemとしたら item like '$A(1)%' And item like '$C(0)%' って感じで検索させればいいかな?と思ったのですが ・そもそもこういう設計(DB+CSV)は駄目ですか? ・もしこういう設計でやった場合のデメリットはなんですか? ・やはり項目ごとにカラムを作った方がいいですか?

  • MySQL
  • 回答数4
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

1つの意見として。。 リレーショナルデータベースのカテゴリに書いている以上、「そのデザインでもいい」とは誰も言わないと思いますが、 現実問題として、正規化を進めるほど仕様が固まらない上に、手戻りのコストも負えない以上、そこの部分の正規化はあきらめて進むしかないのでは? CSVと書くと奇異に映りますが、その発想自体は要はXML DBと同じです。リレーショナルの世界でも項目数不定のケースで XMLをテーブルに収録するアプローチは使うことがあります。 このアプローチでデメリットがあるのは、 ・1カラムにどれだけ長いデータが入っても、一部分でも更新するときにはカラム全体を取り出して更新しなくてはならないこと ・整合性・データ型などについて、データベースで保証できなくなること ・範囲検索はもちろん、データに対する一部検索も前方一致以外はできなくなること ・フィールド名にも制約が生じること(住所と自宅住所があったらダメ) ・万一、検索が遅いと言われても打つ手がないこと(インデックスも効かないし) ・後でメンテナンスするのが大変、また蓄積したデータを転用したくなっても容易にできない など。。 別のアプローチとして、テーブル分割はダメなんでしょうか? 属性を自由に追加変更削除できることをウリにしているシステムでは、属性データを縦持ちしているケースも多いです。 メインテーブル (主キー、共通項目、情報タイプなど) サブ項目属性テーブル (項目番号、項目名) サブ項目テーブル   (主キー、項目番号、文字、数値、日付) もちろん、個別項目に対する参照整合性は捨てた上でのアプローチであることは変わりませんけど、存在しない属性は登録できないですし、 データ型は保証されます。インデックスも張れますし、検索の柔軟性もかなり上がります(複合検索のクエリがやや書きづらくはなります)。

pokopoko_0
質問者

補足

>・1カラムにどれだけ長いデータが入っても、一部分でも更新するときにはカラム全体を取り出して更新しなくてはならないこと 今回のシステムにおいて&更新画面では一通りの項目を出して更新して 変更ある部分と内部分の差分チェックをして更新部分のみUPDATEを発行する予定はありません。 >・整合性・データ型などについて、データベースで保証できなくなること 今回のシステムにおいてデータ整合性をチェックしないといけないのは数値部分だけですね。後はほとんど通常のテキストタイプとリストボックスとチェックボックスですので数字部分はPHP側でctype_digitやis_numericで判別して入力チェックは実装します。 >・範囲検索はもちろん、データに対する一部検索も前方一致以外はできなくなること 各項目部分は「項目名(値)」を利用しますから範囲比較はできなくても 前方一致「%項目名(%値)%」 のほかに後方一致も「%項目名(値%)%」では駄目ですか? >・フィールド名にも制約が生じること(住所と自宅住所があったらダメ) これに関しては各種プロトコルの開始コード/終了コードみたいなものを項目名(値)の頭と最後につけて「^」を制御コードとして使って ^項目名(値)^みたいにすればいいかなって思っています。 そのかわり^は項目名で使えなくはなりますが >万一、検索が遅いと言われても打つ手がないこと(インデックスも効かないし) 検索に使うカラムはよく使いそうな物は個別のカラムとして用意してやるつもりです。 >存在しない属性は登録できないですし、 どっちにしてもシステムでデータベースエラーが出るのはまずいのでどのようなシステムを作るにしても入力チェックはPHP側でする必要があります。

その他の回答 (3)

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.4

#2です。 現在の状況に鑑みればデザインを根本的に変えるつもりはなく、要は誰かに背中を押してもらいたい状態なのかな、と推測しています。良し悪しの判断基準は所詮「今回のシステムで、データベースにどこまでの役割を期待するのか」により変わるものです。 最初から必要最小限の検索とデータ保管庫の役割以上を期待しないのであれば、今のデザインは1つの考え方だと思いますしね。 蛇足になりますが。。 >前方一致「%項目名(%値)%」のほかに後方一致も「%項目名(値%)%」では駄目ですか? これはだめだと思いますよ。質問者さんの例で、 「A(1),B(あいうえお),C(0)・・・・・・」 に対して、「%A(%うえお)%」は通常Trueになります。 >どっちにしてもシステムでデータベースエラーが出るのはまずいのでどのようなシステムを作るにしても入力チェックはPHP側でする必要があります。 データベースの正規化や各種制約の設定は、極論すればアプリケーションがどんな誤作動をしても、データベースが独立した存在として整合性を失わないためにするものだと私は思います。したがって、アプリ側だけでチェックするのも、データベース側だけでチェックするのも本来は不正解です。

pokopoko_0
質問者

補足

>最初から必要最小限の検索とデータ保管庫の役割以上を期待しないのであれば まぁ検索が遅くなった場合は相手にあきらめてもらうしかないですね。 後からいろいろ追加したり言うことが変わってきた代償としてね。 (実際今日もこれ以上追加があるとプログラムの方に入れないし仕様変更ばかりだと作業が遅れるだけです。と昨日の時点でもう一回受元の経由で受注元の方に言ってもらったのですが今日も追加を出してきましたから) >これはだめだと思いますよ。質問者さんの例で、 >「A(1),B(あいうえお),C(0)・・・・・・」 >に対して、「%A(%うえお)%」は通常Trueになります。 確かに言われてみればそうですね。 しかも自分が書いたの前方一致と後方一致が逆になっていたですね。 ただ今回のシステムの場合、検索に必要なのは主に数値そのものの範囲検索(ここは独立カラムにする)とリストボックスやチェックボックスで登録したデータの検索でリストボックスやチェックボックスに関してはValue値は数字だけですからなんとかなると思います。

  • hisappy
  • ベストアンサー率46% (184/392)
回答No.3

「仕様が完全には確定しない」のと 「動くものを作る必要がある」という状況においては 質問文にある設計は実は最適な解の1つだと思います。 外野の意見となりますが、 そのような暫定的な設計で進行するのであれば PHPであるのを利用して管理コンソール(仮称)のような画面を用意して 本来ならドキュメントに詳細を記載すべき部分を 画面表示させるように対応してみてはどうでしょう。 つまり、これから先の仕様変更におけるDB設計のややこしさを システム側に管理させてることで いわゆる「ドキュメントの不備」を 「コレコレの画面参照」で逃げられる(??)ようにするのです。 応用すると、項目の追加とかリレーションの変更が その管理コンソール(仮称)をウニウニと操作するだけでできるので 稼動後の仕様変更にもコストがドカンでチョコンのボコンと…おっとと。。。 その一方で、「本来の仕様の設計」と 「暫定的仕様の設計」が併走するような格好になるので その点を理解してないと メンテナンスの際に摩訶不思議なロジックに見えてきます。 理想論からいえばそのような設計は駄目なのかもしれませんが、 システムとしては今動かせるものが作れることが大事だと思いますので 併走しながらその手法も成熟させてみるのは良いでしょう。 成功したら一冊本が書けそうな汎用的システムになりそうです。

pokopoko_0
質問者

補足

>応用すると、項目の追加とかリレーションの変更が >その管理コンソール(仮称)をウニウニと操作するだけでできるので >併走しながらその手法も成熟させてみるのは良いでしょう。 納品を遅くとも4月いっぱいでしないといけないのと作業人数も今回はフリーでの仕事で 要求の都度データベース設計を何回もやり直している余裕も無いですし (すでに要求の変更で2回データベース設計をやり直していますし これ以上データベース設計の変更ややり直しに時間がとれないというのもありますけど) そんな細かいエンジンを作る余裕は無いのですが 各タイプごと異なる項目部分で毎回言うことが変わることが多いので 1.各タイプすべて共通部分は独立カラム 2.各タイプで共通項目ではないが検索で範囲指定(数値)が必要な項目は独立したカラム 3.各タイプで非共通なその他の部分に関しては一つのカラム内でCSV形式で管理 って感じになりそうですね。 で1と2の部分と3の部分の判別をテーブル一つ用意して 項目管理テーブル ・主キーカラム:2桁のテキストもしくはtinyint ・独立項目情報カラム:ここもCSV形式で独立させるカラムを書く 例) (主キー00はすべての情報タイプで共通部分として) 00:Uid,Name,Day 01:Number1,Number2 02:Number3,Number5,Number1 03:Number4,Number2 こんな感じでデータベースで管理してそれをPHPに渡して データベース側の独立カラムと一つのカラムにまとめる項目を判断させて入力フォームから入ってきた値を各フォーム項目のNAME属性をそのまま利用して(セキュリティー上データは最低限のエスケープ処理をして)処理する簡易エンジンを作ろうと思っています。

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

> (正規化して共通部分とそうでない部分をわけろって言われそうですが) 私もそう言います。 一旦こういう設計にしてしまうと後々のメンテナンスが大変な上に、検索 の際にパフォーマンスも上がらず、いいことあまり考えられないんですが。

pokopoko_0
質問者

お礼

>検索の際にパフォーマンスも上がらず、いいことあまり考えられないんですが。 実際の所、各カラムを別々にしてインデックスを使わないでやった場合 各カラムを検索させるの自分のやろうとしている方法で 一つのカラムから検索させた場合のパフォーマンスってそんなに変わりますか? 問題はお客さんが昨日と今日で言っていることが変わるし で後から変更になると金額的にもあがりますなど言うと それじゃあ困ると言われるので DB内でCSV方式でデータ管理させれば楽かな?と思ったのです。 問題は数字の範囲指定(不等号)による検索がこのCSVを採用したらできないってことです。(できるなら教えていただければ助かります。) その部分は別途独立したカラムを考えないと駄目ですね。 >メンテナンスが大変な上に 元々70~100項目を7タイプ用意するシステムですので作っているシステム外からメンテナンスをするとなるとメンテナンスは大変なんですよね。 項目が増えたり減ったりしてもこのCSVをカラムに格納するやり方なら DBをいじらずにPHP側の変更だけですみますし

pokopoko_0
質問者

補足

検索に使う項目は独立したカラムにしたとしてそうでない表示だけにしか使わないカラムを一つのカラムにまとめて CSV形式で管理するのはありですよね?

関連するQ&A

  • powershellでcsvの順次読みこみ

    powershellでcsvの順次読みこみ powershellで下記のような事はできますか? <in_file.csv> a,1,A b,2,B c,3,C これを読み込み <out_file.csv> =1=《A》【a】 =2=《B》【b】 =3=《C》【c】 のように個別の項目を編集して出力

  • 複数のcsvファイルをマクロ(VBA)で取り込みたい

    複数のcsvファイルをマクロ(VBA)で取り込みたい csvファイルの中身が、 20090507 120508 osaka 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 b1,b2,b3,・・・・・,b10 c1,c2,c3,・・・・・,c10 や 20090507 132529 hokkaido 項目1,項目2,項目3,・・・・・,項目10 d1,d2,d3,・・・・・,d10 e1,e2,e3,・・・・・,e10 f1,f2,f3,・・・・・,f10 となっているcsvファイルが特定のフォルダの中に100以上あります。 このcsvふぁいるの5行目だけをaccessに書き込んでテーブルに追加していきたいと思っています。 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 d1,d2,d3,・・・・・,d10 このようなテーブルができればいいのですが・・・ csvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する)→次のcsvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する) この流れでいいと思うのですが方法が分かりません。 丸投げですがよろしくお願いします。

  • CSVの特定のフィールドをインポート

    load data local infileでcsvをインポートしているのですが ヘルプなどを見ても特定のフィールドのみを選択する方法がよく分かりません たとえば csv:フィールドA、フィールドB、フィールドC、フィールドD、フィールドE、フィールドF MySQL:カラム1、カラム2、カラム3、カラム4、カラム5 だとします、それを フィールドA→カラム2 フィールドC→カラム3 フィールドD→カラム4 フィールドF→カラム5 という風に選択したいのですがどういう風に指定したらいいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • MySQL
  • PHPでSQLiteのデータをCSVに出力するときの0埋めについて

    phpでSQLiteに格納させたデータをCSVに出力しています。 とある項目のデータの型は“CHAR”にしているのですが、 CSVに出力すると、 “0888” ⇒ “888”という風に頭の0がカットされてしまいます。 0埋めするためにはどのようにしたらいいでしょうか、 恐れ入りますが、どうか教えてください。

    • 締切済み
    • PHP
  • CSV編集について(VB6)

    VB6初心者です。 例として下記のCSVファイルがあります。 a,1,2,3,4,5,b,1,2,3,4,5,6,c,1,2,3,c,1,2,3,c,1,2,3,c1,2,3 a,1,2,3,4,5,b,1,2,3,4,5,6,b,1,2,3,4,5,6,c,1,2,3,c,1,2,3,c,1,2,3,c,1,2,3,c,1,2,3c,1,2,3 上記を下記のように編集して別のCSVへ保存をしたのですがご教授ください。 a,1,2,3,4,5 b,1,2,3,4,5,6 c,1,2,3 c,1,2,3 c,1,2,3 c,1,2,3 a,1,2,3,4,5 b,1,2,3,4,5,6 b,1,2,3,4,5,6 c,1,2,3 c,1,2,3 c,1,2,3 c,1,2,3 c,1,2,3 c,1,2,3 上記の各a,b,c内の項目数は固定です。 a以降のb,c内の配列はランダムに複数となります。

  • VBSにてCSV読み込みし比較

    ある場所に比較するCSVファイルを2個格納しております。 ただしCSVファイル名は可変であります。 その場合 Set objTextA = objFSO.OpenTextFile("C:\" & "A.csv")と特定して呼び出せません。 名前が可変なときのため、そのパスにあるCSV2個を順に呼び出すにはどうすればよいのでしょうか。 また呼出し後、split関数により、配列に入れます。A配列とB配列に格納したとします。 一つ一つ比較していきたいのですが、 以下のような構文の場合、比較で違ったときテキストに書き込みとなりますでしょうか? for i=0 to i=10 step 1 if strcomp(a(i) ,b(i))) = 1 then テキストに書き込み endif next

  • CSVからエクセルへの取り込み

    エクセル・マクロ初心者です。 CSVファイルの一部分を、エクセルで読み込みたいのですが、 マクロでの作成は可能でしょうか。 (例) ・CSVファイル(読み込み側)  ABCDE 1 2 3 4 5 ・EXCELファイル(書き込み側)  ABCDE 1 2 3 4 5 ・CSV側は、複数のファイルがあります。 ・EXCEL側は、1つのシートにCSVのデータを書き込みます。 ・CSVファイルAの1B、2B、3B、4B、5Bを読み込み、EXCELファイルの、1A、1B、1C、1D、1Eに書き込みます。 ・CSVファイルBの1B、2B、3B、4B、5Bを読み込み、EXCELファイルの、2A、2B、2C、2D、2Eに書き込みます。 ・CSVファイルCの1B、2B、3B、4B、5Bを読み込み、EXCELファイルの、3A、3B、3C、3D、3Eに書き込みます。 というような事をやりたいのです。 どなたか、ご指導のほどよろしくお願いします。

  • SQL 部分一致検索について

    カラムAとカラムBはそれぞれ文字列が格納されているとします。このとき、カラムAには「ABC」カラムBには「ABC(株)」があるとした場合、カラムAとカラムBが部分一致しているかをSQLで検索する場合、どのようなSQL文になるかご存知でしょうか? 勿論予め、検索したい文字列が判っている場合は、like '% nnnnn %' ですが、文字列が判らずカラム同士で部分一致するカラムを選択したいのです。

  • CSVの印刷

    よろしくお願いします。 CSVデータを印刷したいと思います。 そのCSVの中身なのですが、画像のハイパーリンクがあります。 こんな感じのCSVです。 ------------------------------------------------ A B C D 1|img/hoge01.jpg|hoge-001|\600|COLOR:MIX 27cm| ------------------------------------------------ ですので、印刷したい内容ですが、 (1)リンク先の画像が印刷できること (2)レイアウトは縦に画像(A1)、コメント(B1)、コメント(C1)・・・ のような感じで3列ずつ (3)A4サイズで印刷できること このようなことはVBAで可能なのでしょうか? どうかご教示よろしくお願いします。

  • excel2010でcsv結合について

    ご教授お願い致します。 2つのCSVファイルがあり、それを結合したいと考えています。 2つのファイルの中で1列同じ項目があるので、その列をキーに と考えています。 (ファイル1)A,B,C (ファイル2)a,b,c 上記のようなイメージでA列とa列を結合し A,B,C,b,cと表示したいです。 何か簡易な方法はありませんでしょうか?