4

質問

1) Web アプリケーション、具体的にはデータベース スキーマを設計する適切な方法を探しています。これにより、特定のサービスのすべてのコア フィールドを含むベース テーブルを作成できるようになり、サービスの種類に応じて、サービスに関連付ける追加のフィールド セットが必要になります。

検索の実行が簡単で、妥当なパフォーマンスが得られるような方法でこれを行う必要があります。私はおそらくある種の全文検索を検討していますが、アプリケーションの同時ユーザーはせいぜい 5 人しかいないでしょう。

このアプリケーションの最終的な目標は、データベース全体で任意のキーワードを検索し、関連するすべてのレコードを返すことです。最初は、サービスの種類ごとに設定されたフィールドを、独自の列を持つ個別のテーブルに分割することを検討していましたが、そうすることで、より複雑な検索クエリ (多くの JOIN) や、より多くのクエリが実行される可能性があると考えています。検索ごと。

提案された解決策について、これが適していると考える理由を教えてください。

2) 私のもう 1 つの問題 (うまくいけば以下で明らかになるように) は、私の設計が現在、各製品のコア タイプを定義する「サービス タイプ」テーブルで構成されており、各サービスが特定の製品の「インスタンス」であることです。 .

ここでの問題は、製品とサービスの種類のテーブルの両方がある場合、ほとんどの重複が発生する可能性があるということです。したがって、この重複を避けることは、私が設計で達成しようとしているもう 1 つの主なことです。

詳細

私は現在、請求 (請求サイクル、開始日/終了日、価格) だけでなく、それらのサービスの文書化 (関連するユーザー アカウント、IP住所、物的資産など)。

各サービスは、基本製品の名前、価格、請求期間、説明などを定義する「製品」テーブルに基づいています。タイプ)。たとえば、次の製品があります。

  • 共有 Web ホスティング プラン 1
  • 共有 Web ホスティング プラン 2
  • 共有 Web ホスティング プラン 3
  • 専用サーバープラン
  • 仮想専用サーバー プラン1
  • 仮想専用サーバー プラン 2

現在、私が抱えている問題は、特定のサービスに共通するフィールドがいくつかありますが、追跡されるサービスの「タイプ」に応じて変化するフィールドもいくつかあるということです。サービスの種類に応じて、すべてのサービスの基本フォームを表示しますが、追加/編集などに適したフォームも表示します...

たとえば、次のサービス タイプがあり、各製品 (上記のように) はこれらのコア サービス タイプのいずれかに関連付けられます。

  • 共有ウェブホスティング
  • 専用ホスティング
  • 仮想専用ホスティング
  • ADSL
  • ...

私の可能な解決策

現在のソリューション - 複数のテーブル

現在、私のデータベースには次のものがあります。

サービスの種類

  • ServiceTypeID INT PK
  • タイプ VARCHAR(40)

製品

  • 製品 ID INT PK
  • 名前 VARCHAR(40)
  • 説明 テキスト
  • 価格小数
  • BillingDuration INT
  • TypeID INT (FK ServiceTypes.ServiceTypeID)

サービス

  • ServiceID INT PK
  • ProductID INT (FK: Product.ProductID)
  • 名前 VARCHAR(40)
  • 説明 テキスト
  • 価格小数
  • BillingDuration INT
  • アクティブビット
  • 開始日DATETIME
  • 終了日DATETIME

これらはすべてのサービスのメイン テーブルであり、拡張プロパティ用の追加テーブルがあります。

サービスADSL情報

  • ServiceADSLInfoID INT PK
  • ServiceID INT (FK: Service.ServiceID)
  • FNN VARCHAR(10)
  • ユーザー名 VARCHAR(20)
  • パスワード VARCHAR(20)
  • LocationID INT (FK: Locations.LocationID)
  • ModemAssetID INT (FK: Assets.AssetID)

ServiceVirtualServerInfo

  • ServiceVirtualServerInfo INT PK
  • ServiceID INT (FK: Service.ServiceID)
  • サーバー名 VARCHAR(20)
  • IPAddress INT (FK: IPAddresses.AddressID)
  • HostServer INT (FK: Assets.AssetID)
  • ユーザー名 VARCHAR(20)
  • パスワード VARCHAR(20)

ServiceSharedHostingInfo

  • ServiceSharedHostingInfoID INT PK
  • ServiceID INT (FK: Service.ServiceID)
  • ホスト名 VARCHAR(50)
  • HostServer INT (FK: Assets.AssetID)
  • DiskSpaceQuotaINT
  • 帯域幅クォータ INT

その他の解決策 - 単一のテーブル

サービスの種類に関係なく、すべてのサービス関連情報を単一のテーブルに格納し、その特定のサービスに必要ない場合は値を NULL にすることを考えています。

  • ServiceID INT PK
  • ProductID INT (FK: Product.ProductID)
  • 名前 VARCHAR(40)
  • 説明 テキスト
  • 価格小数
  • BillingDuration INT
  • アクティブビット
  • 開始日DATETIME
  • 終了日DATETIME
  • ユーザー名 VARCHAR(20)
  • パスワード VARCHAR(20)
  • FNN VARCHAR(10)
  • LocationID INT (FK: Locations.LocationID)
  • AssetID INT (FK: Assets.AssetID)
  • ...

サービス関連のデータを提供するために、単一のテーブルで全文検索を使用するだけでよく、レコードを結合することを心配する必要がないため、これは検索の観点からも扱いやすいソリューションであると思います。

ここでの私の主な懸念は、30 列以上のテーブルになってしまうことです。もう 1 つのことは、特定の検索にどのフィールドを使用する必要があるかを把握するためにコアの serviceTypes テーブルが必要であるため、両方の懸念が解決されないことです。

products テーブルとのある程度の重複は避けられないのでしょうか?

エンティティー属性値モデル

このデザインも検討しました。全体として、物事をそれほど柔軟で動的にする必要がないので、これはやり過ぎだと感じています。サービスの種類に応じて一連のフィールドのグループが必要になりますが、コア サービスの種類ごとに収集する必要があるデータはすぐに変更されるとは思えないため、これは静的である可能性があります。

また、このレベルの柔軟性を実装するために必要なアプリケーション ロジックは、それがもたらすメリットに対して複雑すぎるように思えます。

データベースなどから照会されたフィールドのタイプに応じて、表示する HTML フォーム フィールドのタイプを決定しなければならないということは、苦痛に思えます。

私が提供できる詳細があれば教えてください!すべてが明確であることを願っています。

ありがとう!

4

1 に答える 1

2

これはすべて、特に新しいサービスがシステムに導入された場合にどのように前進するかをどのように想定するかにかかっていると思います。すべて有効なアプローチですが、すべてに長所と短所があります。

最初のアプローチでは、よりクリーンなメイン テーブルが得られますが、サービスごとに個別のテーブルを作成する必要があります。新しいサービスでは、これを継続する必要があり、アプリケーションでは、各サービスが独自のテーブルを必要とするため、複雑さが増す可能性があります。データをプルするためのクエリのセット (あなたのアーキテクチャがここにあるかわからないので、暗闇の中で突き刺します.個人的には、これは最終的に傷つくと感じています.

非正規化されたテーブル アプローチの方がクエリは簡単ですが、特定のタイプの不要なデータを大量に含むモンスター テーブルを作成する可能性があります。わずかに異なるアプローチは、数値を保持する numX (x は 1 ~ 10) と呼ばれる 10 個のフィールド、textx と呼ばれる 10 個のフィールドなどの一般的なフィールドを追加することです。Salesforce は、顧客のカスタム フィールドにこのアポローチを使用すると思います。

キー値フィールドのアプローチは、あなたが最も柔軟だと言っているようですが、型認識などを失います。少なくともデータベース内のすべてが同じ型である必要があります。

アプリの性質にもよりますが、5 人の同時ユーザーのパフォーマンスは問題にすべきではないため、実装の容易さは気にする必要があります。一般的なアプローチの概要 (セールス フォース アプローチ) はここで機能し、前進する他のサービスや将来の証拠を少しカバーする可能性がありますが、それはあなたがどの程度の変化を想定しているかによって異なります。

変更が一貫している場合は、サービスが異なるフィールドなどをロードする場合、おそらくキー/値アプローチが最善の策ですが、その段階では、ここでの請求に適合する可能性があるため、いくつかの nosql アプローチを検討することもできますが、mysql はまだ機能しており、議論を開始するだけです。

アップデート

コメントに沿って、サービスであまり頻繁に変更することを想定していない場合は、noSQL をスキップします。開発が複雑になり、おそらくメリットがないからです。

述べたように、サービスの種類はおそらくあまり変わらないので、非正規化された一般的なアプローチがうまくいくと思います。このようにして、アプリケーションはサービス用の 1 つの領域を持つことができ、追加のプロパティを「カスタム フィールド」として扱い、必要に応じて追加することができます。そうすれば、アプリは汎用的です。不幸な副作用の 1 つは、アプリケーション内でそれが存在するかどうかをテストするロジックを介して何らかの形で管理する必要があることです。また、現在のニーズでは、フィールドが入力されているかどうかに関係なく、すべてのフィールドをプルする必要があります。大きなトレードオフ。

一般的なアプローチのサンプル (非常に単純な) 例。

ここに画像の説明を入力

  • 汎用フィールドは、すべてのサービスで共有される主力フィールドです。

(メカニズムによっては)検索にすべてのフィールドを含める必要がある場合があるため、これにより検索が少し面倒になる可能性があります。

于 2012-11-02T08:44:12.397 に答える