【ノウ】DBアプリ開発ノウハウ【ハウ】

このエントリーをはてなブックマークに追加
>873がどうなったのか気になる。
>>922 うちの母もだ。いっても全然直らん。

925922:03/08/25 17:07
オレのほうも女性です。そんなもんなのかw
うちの母はCPUの事をIntel insideと呼ぶw
例のステッカーのせいw
>>922,924
昔の知り合いにもいたなぁ・・・
やっぱり女だった。
でも、元は知り合いの男の影響ぽかった。
話しててものすごく違和感あった。
928デフォルトの名無しさん:03/10/25 23:11
すいません、ちと質問させてください。
静的SQL、動的SQLっていう言葉をよく聞くけど、
これって一般的にそれぞれどういう意味なんでしょうか。
なんか、いろんなところでばらばらの意味で使っているような気がして、
混乱してきました。
俺はハードコートされたSQLと状況に応じて変化するSQLだと思ってるが。
動的SQLは実行時にSQL文が確定するもの。
静的SQLはデザイン時にSQL文が確定するもの。
性的SQLは…
動的SQL、静的SQL というのはいくつかの使われ方をしてるからね。
どれが正しいとか間違っているとかいうことじゃないと思う。

(1)
まず、昔はプログラミング言語では、SQLをソースコードに記述して
プリプロセッサで処理をするというものがあった。
これらは、SQL構文チェックがその段階で行われる。これが静的。

それに対して、0040,DAO,RDO,ADO などライブラリにSQLを文字列として
渡すタイプ。これは実行時まで構文チェックされない。これが動的。

(2)
技術的な話ではなく、プログラマが意味的に使い分けることがある。
ユーザーの選択に応じて Where句などが変化するものを動的SQL、
常に同じSQLが発行される場合に静的SQLという。

(3)
データベースおよび呼び出しライブラリによっては,
プリコンパイル(プリペアド)SQLというものをサポートしている。
これは、構文解析・オプティマイズしたクエリを保持しておくもの。
プリコンパイル(プリペアド)SQLを静的SQL。
毎回、構文解析・オプティマイズを行うクエリを動的SQLという。
ようは >>930 でいいんじゃん
933デフォルトの名無しさん:03/10/27 21:59
>>930 が言ってるのは (2) だけじゃないの?
934デフォルトの名無しさん:03/10/29 01:06
こちらにはプロのDB屋さんが大勢いると思うので質問させて下さい。

Yahooのようにカテゴリーが階層になっているデータをうまいこと
DBに格納するにはどのようにするのが良いやり方なのでしょうか?
自分で考えたやり方なんですが、サイトのデータを入れるテーブルと
カテゴリの階層を表すテーブルに分けてみました。
ちょっと簡単に書くと以下のようになります。

サイトデータテーブル
サイトID,カテゴリーID,URL,タイトル,コメント

カテゴリテーブル
カテゴリーID,親カテゴリーID,カテゴリー名

サイトデータテーブルとカテゴリーテーブルはカテゴリーIDで
リレーションを張ります。
階層構造はカテゴリーテーブルの親カテゴリーIDを再起的に
辿っていくことで表すことができます。

DBの設計に関しては独学で誰かに教えてもらったことがないので
これでいいのかどうか不安です。
他に良いやり方などあったら教えてほしいのですが・・・。
よろしくお願いします。
>934
カテゴリ3階層のショッピングサイトを作ったときは、そんな感じで作ったなぁ。

カテゴリテーブルに何階層目かもいれると、検索しやすい?
936デフォルトの名無しさん:03/10/29 03:10
>>984
Webサイトはお遊びだからいいけど、積算等の基幹業務系になると
再起呼出しでは高速に集計できなくなるので、フルパス的な方法の方がいいかも。
ツリーの操作や探索なんてRDBじゃムダすぎ。
ファイルに落としてメモリマッピングしてRAMディスクの要領で扱うべきかと。
938デフォルトの名無しさん:03/10/29 09:27
>>937 同感
メモリ 4G 積めば、そこそこの操作はオンメモリーでできるので;
ツリー情報は自前で処理だね。
939934:03/10/29 16:55
確かに再起で何回もDBにアクセスするのでそこがネックでした。
ただ、DBだとWeb上の管理画面からブラウザで階層構造の変更が
できたりと良い面もありましたが。

>ファイルに落としてメモリマッピングしてRAMディスクの要領で扱うべきかと。
つまり多次元配列などにカテゴリの階層を記述し、DBを介さずに
階層構造を扱うということでよろしいでしょうか?
>>937
更新・削除を考えたら、ただのファイルの方がムダが大きい可能性も
大きいと思うけどね。メモリマップで扱えて部分更新が可能でしかも
検索が速いファイルフォーマットなんて考えていたら、自分でDB作る
ようなもんだし。
941デフォルトの名無しさん:03/10/30 13:13
>>934
どんなDBMSを使っているかにもよるけど、ストアドにしたり、再帰時の
呼び出し方を工夫することでいくらでもパフォーマンスは上げられる。
OracleなどはSQLで階層構造の検索ができるようになっているし。

使用しているDBMSとミドルウェア、再帰の部分のコードを貼り付ければ
もう少し現実的なアドバイス(RAMで云々などでなく)が貰えると思うよ。
ファイルシステムっつっても基本はファイル割り当てテーブルで
ディレクトリ/ファイルのツリーを管理してんだから、そんな感じ
のテーブル定義しとけば良いんじゃない? だめっすか?
943934:03/10/31 23:05
現在のカテゴリのパスを表示するときなど
再帰処理で親カテゴリーIDがNULLになる(ルート)まで
辿る(階層分問い合わせる)ということをしているのですが、
このような部分をストアドプロシージャにすると一般的には
パフォーマンスは上がるのでしょうか?

ちなみに今の開発環境はPerl+DBI+MySQLでやっております。
MySQLは現在のバージョンではストアドプロシージャは未実装ですが、
近々出る次のバージョンでは実装されるそうです。
MySQLにこだわっているわけではないのでPostgreSQLにしてもいいんですけど。
>>943
> このような部分をストアドプロシージャにすると一般的には
> パフォーマンスは上がるのでしょうか?

DBMSにもよるけど、かなりのパフォーマンス向上が見込めるよ。
ストアド言語が再起処理可能でないとダメだけど。
945943:03/11/02 20:53
>>944
なるほど。ストアド言語って素晴らしいですね。
色々有益なアドバイスありがとうございました。
今取引を記録していくシステムを考えているのですが、繰り返し発生する取引の登録の簡略化を考えています。

取引DB
ID 取引日 得意先C
1 11/01 A000
2 11/01 A001
3 11/01 A002

4 12/01 A000
5 12/01 A001
6 12/01 A002
としてIDをキーとして登録しようとしています。

今はクライアント側で転記を行っていますが、SQLを使って
何とかサーバー側で行えませんか?
InsertSelect文では同じテーブルでの操作はできないので
それに代わるものを考えています。

このような実装はどのようにするとスマートに行えますか?
取引の実績を記録したいのか?それとも計画を記録したいのか?
>947
取引の実績を記録しようとしています。

今回の取引内容が前回と同じ場合に、前回の取引から内容を複写
したいわけです。
たとえばA社(A000)の12/1の取引は11/1の取引と同じ内容で登録
とできないかと考えています。

946では 取引DBの列を簡略化していますが、他にも列があります。

実際にはできませんがこんな感じでSQLで処理できればと
INSERT INTO 取引DB
(取引日,得意先C,取引内容)
SELECT #12/1#,得意先C,取引内容
FROM 取引DB
WHERE 取引日=#11/1# AND 得意先C='A000';
>>948
いや、なんでわざわざ過去の履歴から情報を複写したいの?
ぜんぶ初回取引とおなじ処理じゃだめなの?

もし一連の「繰り返し取引」に固有の情報があるなら、別テーブルに分けるべき。
>949

>いや、なんでわざわざ過去の履歴から情報を複写したいの?
オペレータの入力の負担を軽減するためです
業務にもよると思いますけど「過去の取引を検索して複写する」って
あまり使われないのでしょうか

> ぜんぶ初回取引とおなじ処理じゃだめなの?
駄目ですわ
実際のところ毎回同じ取引内容で動いてる訳ではないですから

>>950
クライアント側のフォームか何かに必要な情報を入力して、それを
エントリしているわけだよね?その入力の手間を省くというなら、
前回の取引内容をクライアント側に取り出せば、あとのエントリは
初回だろうが繰り返しだろうがおなじ処理でできるだろう?
サーバー上で複写云々なんて考える必要はない。

>駄目ですわ
>実際のところ毎回同じ取引内容で動いてる訳ではないですから

それって入力内容が違うってだけの話だしょ?
それとも取引ごとに入力項目が不定で毎回変わるとか?
952デフォルトの名無しさん:03/12/26 18:11
レコードをソートするためだけのフィールドを作るのですが、
数字型と文字列型どちらがいいでしょうか?
識者のご意見をお聞かせ下さい。
SQLでソートすればいいじゃん
>>952
型とか何とかよりまずインデックスを張ることを考えるけど

何の順でソートする?
追加するフィールドの値はどうやって導出する?

そっちのほうが気になる
955デフォルトの名無しさん:03/12/27 00:01
952じゃないけど、たぶん human interface を作るときに表示する順番を
レコードに持たせたりするんじゃない?
例えば受注投入画面でお得意さんを上に表示して選びやすくするとか。

ちなみに数値型でいいでしょ。
>>955
言葉足らずですいません。そうゆうことです。
表示する時の並び順の為だけのソートIDです。

数値型にしてみます。ありがとうございました。
957デフォルトの名無しさん:03/12/27 00:23
お前らあほか

ぱんてぃーは昔から白色いうてきまっとんのじゃ

赤とか黒とかは萌えんのじゃ

ましてやのぉ くもの巣みたいなんはいてみぃや しばくど

のぉ梅宮
958デフォルトの名無しさん:04/01/21 07:41
すいません、ちょっと相談に乗ってください。
ユーザーテーブルに10000人分のレコードがあります。
また、10000件ほどのドキュメントがあり、各ユーザーがそのドキュメントを

読んだかどうかのデータを保存したいんですが、どういう設計にすればいいでしょうか。

各ユーザーが各ドキュメントごとに未読既読を保存するテーブルを作って・・・
と考えていたんですが、よく考えるとそのテーブルには100,000,000件も
レコードができてしまって、ちょっとこれは心配。

ドキュメントのテーブルにひとつフィールドを設けて、ユーザー分の既読フラグを
バイナリ化して入れてもいいんですが、バイナリ化はプログラム側で行うため、
複数のユーザーが同時に既読フラグを立てようとするとタイミングによって、
フラグが消えてしまうユーザーが出てきそうで・・・

こういう場合、どうすればいいんでしょうか。
959U ◆CZtFsGiu0c :04/01/21 12:49
>>958
>各ユーザーが各ドキュメントごとに未読既読を保存するテーブルを作って・・・
と考えていたんですが、よく考えるとそのテーブルには100,000,000件も
レコードができてしまって、ちょっとこれは心配。

下手なこと考えるより、これでやってみたほうがいい。
>>958
>各ユーザーが各ドキュメントごとに未読既読を保存するテーブルを作って・・

これが正解です。
ユーザと未読ドキュメントの組み合わせではレコードを作らず
ユーザがドキュメントを読んだときに既読レコードを作れば
実際のレコード数は100,000,000件よりずっと少ないでしょう。
レコード数増加に伴う検索時間増加はインデックスで解決できます。

>ドキュメントのテーブルにひとつフィールドを設けて、ユーザー分の既読フラグを
>バイナリ化して入れてもいいんですが、バイナリ化はプログラム側で行うため、

RDBをRDBとして使うにはデータが正規化されている必要があります。
ユーザ数は不定でしょうからこの設計は第一正規形すら満たしておらず
RDBを単なるランダムアクセスファイルとして使うことになります。
これではいったい何のためにRDBを使うのかわかりません。

的外れな心配を間違った解決策で回避しようとせずに、
RDBの基本的な仕組みに合わせた素直な設計をする事をお勧めします。
961デフォルトの名無しさん:04/01/22 06:31
>>959
>>960
なるほど、一度やってみます。
ありがとうございます!
962デフォルトの名無しさん:04/01/22 19:54
Oracleで全てのSQLをストアド化しようとすると
SELECT系のものはカーソルを返す関数をいちいち書かなきゃならないような
気がするのですが、皆さんはどうされていますか?
「サーバ側で一元管理しなきゃ!」と思ってやり始めたのですが
面倒くさくて挫折しそうです。。。
963デフォルトの名無しさん:04/01/30 10:52
ディレクトリ構造を表す以下のような構造のテーブルがあるのですが、

[テーブル1]
ディレクトリID,親ディレクトリID,ディレクトリ名

ショートカットの概念を入れることになり、ディレクトリなら0、
ショートカットなら1が入るフィールド(ディレクトリタイプ)を
追加することになりました。

[テーブル1]
ディレクトリID,ディレクトリ名

[テーブル2]
ディレクトリID,親ディレクトリID,ディレクトリタイプ

すると今までディレクトリIDがユニークなIDだったのですが、
テーブル2のディレクトリIDがユニークなIDではなくなってしまいました。
一応、ディレクトリIDと親ディレクトリIDとの組み合わせでレコードを
特定できるのですが、この場合ユニークなIDを設けるべきでしょうか?
964U ◆CZtFsGiu0c :04/01/30 13:29
>>963
ショートカットには名前いらないの?
もしかしたら要件満たしてないかもしれないけど、

[テーブル1]
ディレクトリID,ディレクトリ名,親ディレクトリID,ディレクトリタイプ,実ディレクトリID

のようにショートカットにも独自のディレクトリIDを振って、ポイントしている
ディレクトリは実ディレクトリIDで示すのはどうですか?
965963:04/01/30 17:13
>>964
ショートカットは単独で名前を持ちません。
(Yahooのカテゴリのような非常に単純な構造なので)
元ディレクトリの名前が変わるとショートカットの名前も一緒に変わるように
テーブルを分けた方が都合がいいのです。

それにしても独自のIDを振った方がいいのでしょうか?
複数のIDからレコードが特定できるなら独自のIDを振らなくても
いいのでしょうか?
いまいちそこら辺のセオリーが分からないです。
966デフォルトの名無しさん:04/01/31 17:32
自動で重複しないIDを振る方法を考えています。
自分で思いつく限りでは以下のような方法があると思うのですが
皆さんならどうしますか?

・オートナンバー型を使う
・アプリ側で重複しない文字列を生成
・ストアドで重複しない文字列を生成
967966:04/01/31 17:34
自動でというのはINSERTする際にということです。
968デフォルトの名無しさん:04/01/31 18:40
トリガを使う。
969デフォルトの名無しさん:04/02/03 00:39
SQLでSELECTに続けてカラム名書くやつはすげーむかつく。

SELECT COL1, COL2
FROM TABLE1
WHERE ...

こう書け
SELECT
COL1,
COL2
FROM
TABLE1
..
上のは美しいが、死ぬほどメンテしづらい...
>>969
氏ね
>969
SQLでカラム名に続けてカンマ書くやつはすげーむかつく。

COL2をコメントアウトしたときに上の行までいじらないといけない、死ぬほどメンテしづらい...
>>971
実行するまで気づかないってパターン多いよな(w