1

私のソフトウェアは数日前に製品化されましたが、データベース構造について少し議論したいと思います。

このソフトウェアは、船舶に関するデータを収集します。現在、船舶ごとに 174 の詳細があります。各詳細は、テキスト値、長いテキスト値、数値 (指定された長さ、指定された小数点以下の桁数の有無にかかわらず)、日付、日付のいずれかです。時間、ブール値フィールド、多くの値を持つメニュー、データのリストなど。

次の表で問題を解決しました

輸送する:
- ID - smallint、オートインクリメント ID
- IMO - int、船の寿命の間変わらない数

船の詳細タイプ:
- ID - smallint、オートインクリメント ID
- 説明 - nvarchar(200)、フィールドに含まれる値の説明
- 位置 - smallint, データ入力フォーム内のフィールドの位置
- ShipDetailGroup_ID - smallint、データ入力フォームでフィールドが属するグループへのキー
- タイプ - varchar(4)、上記のフィールドのタイプ

ShipDetailGroup
- ID - smallint、オートインクリメント ID
(をちょきちょきと切る...)

ShipMenuPresetValue
- ID - smallint、オートインクリメント ID
- ShipDetailType_ID - smallint、値が属する詳細へのキー
- 値 - nvarchar(100)、メニュー タイプの詳細に事前設定された値

ShipTextDetail
- ID - smallint、オートインクリメント ID
- Ship_ID - smallint、詳細が属する船のキー
- ShipDetailType_ID - smallint、値の詳細タイプへのキー
- テキスト - nvarchar(500)、詳細の値を含むフィールド
- ModifiedDate - smalldatetime
- User_ID - smallint、ユーザー テーブルへのキー

ShipTextDetailHistory
(をちょきちょきと切る...)
このテーブルは ShipTextDetail と同じで、詳細へのすべての変更が含まれています。

リスト詳細タイプのその他のテーブルには、リストに必要な指定されたフィールドがそれぞれあります...

この記事を読みました: http://thedailywtf.com/Articles/The_Inner-Platform_Effect.aspxおよびhttp://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID :10678084117056

記事には、これは問題を処理する正しい方法ではないと書かれています。

私の顧客は、詳細の説明を変更し、詳細を追加するため、詳細とグループの管理 GUI を持っています。

データ入力フォームは、DetailGroups および DetailTypes から構造を読み取ることによって動的に構築され、各詳細タイプは指定された入力コントロールを生成します。

コメントは、この問題を解決する別の方法は、テーブルから列を動的に作成および削除することであることを示唆しています。

どう思いますか?

図のスクリーンショット: http://img24.imageshack.us/my.php?image=66604496uk3.png

4

4 に答える 4

4

以前にこのアプローチを見たことがありますが、データ量が増えると、パフォーマンスの問題が大量に発生します。複数の項目を返し、where 句で複数の基準を使用する必要がある場合に、遭遇するような問題が発生します。Ship と ShipTextDetail の間を行ったり来たりして、選択したすべての列を取得します - おそらく、それを 10/20 回行う必要がありますか? その後、おそらく2〜3回、基準に対して同じことを行います。これで、非常に多くの結合を含むクエリがあり、実行が非常に遅くなります。次に、パフォーマンスを向上させるためにデータの一部を「事前調理」します。つまり、共通データを固定テーブル構造にドラッグします。これで、半正規化モデルに戻りました。

私のお勧めはこれです - あなたはコア属性である 174 のフィールドの情報を知っています。顧客がそのリストに追加したり、フィールドの説明を変更したりする場合がありますが、それでも出発点としては非常に適しています。それらに基づいて適切な DataModel を作成し、拡張メカニズムを組み込みます。メタデータ - フィールドの説明は、別のテーブルに存在するか、場合によってはリソース ファイル (国際化に役立ちますか?) に存在する可能性があり、既存のフィールドにある程度の柔軟性を与えます。

ジョーに同意します。DB が小さい場合、つまり 1000 隻未満の船で、選択が単純であれば問題はないかもしれません。174 の属性から選択できるとはいえ、そうは見えません。最初に「明らかな」フィールドのいくつかを変更する必要があると思います。つまり、Ship.Name、Ship.Owner、Ship.Weight、Ship.Registration があると仮定します...

幸運を。

于 2009-02-12T03:11:57.987 に答える
4

次の場合、コードをリファクタリングします。

  • お客様から苦情がありました
  • うまくいかないものを見つけた
  • 将来起こるとわかっていた変更をコードが処理できない方法を見つけました。

リファクタリングを可能にする単体テストを書くことを覚えていましたよね?

*あなたがそこに持っている構造に関する限り、私は以前にそのような構造を見てきました. 少し面倒ですが、多くの場所で標準になっています。覚えておくべきことの 1 つは、データベースの列を動的に追加および削除することは可能ですが、データベースの内部ストレージ メカニズムは、これらの列を継続的に追加および削除することを必ずしも想定していないということです。しかし、これは上記の点と比較するとあまり関係がないと思います

于 2009-02-12T00:50:09.013 に答える
0

私は同様のことをしましたが、この特定の実装にはいくつかの問題があります。

  1. 数値、ブール値、日付などを文字列として保存しています。これは理想的ではないかもしれません。別の方法は、異なるデータ型に対して個別のクラスを (ベースから継承して) 実装し、それらをデータ型用に作成されたテーブルに格納することです。
  2. 追跡するプロパティは頻繁に変更されますか? タンカーごとに異なるセットですか?そうでない場合は、すべてのデータを格納するプロパティ バッグではなく、オブジェクトを作成する方がよい場合があります。その後、これらのオブジェクトをデータベースに永続化できます。
于 2009-02-12T01:14:58.503 に答える
0

From a performance standpoint, either approach will be fine. How many ships could there possibly be? All the data is going to fit into RAM on any server.

于 2009-02-12T18:06:54.343 に答える