プログラムで解決できるという問題がありますが、個人的な(テスト)プロジェクトでは、リレーショナルモデルで修正できるかどうかを確認しようとしています。
これらのプロパティを寸法として持つ複雑なファッション製品のパンツを想像してください。
だから4*4*5*3*3 = 720
製品のバリエーション。私はこれが極端であることを知っていますが、私のシステムが後のフェーズでそれを処理できるかどうかを即座にテストするために純粋にこれを行っています。
だから私は持っています:
製品
id
name
プロパティ
id
name
RDBMSロジックを別にすると、次のようなテーブルが得られます。もちろん、常にプロパティを追加し、nullを大量に追加するため、これは不可能です。
製品バリエーション
id
product_id
property_1_id
property_2_id
property_3_id
...etc.
したがって、これは、通常の製品で使用している通常の色/サイズの組み合わせよりも少し難しいです。
これで、この方法を偽造して、次のようにProductvariantsの1つのフィールドにプロパティIDのシリアル化をダンプできます。
製品バリエーション
id
product_id
properties {1, 2, 3}
..そして、それらを私のORMで分割しますが、これにより、将来必要なクエリが大幅に増加し(数万の製品バリエーションがあるため)、最適化はその方法では不可能と思われます。
誰かがこれについての経験を持っていますか? MySQLを使用しています。
私は、似たような(私は信じている)何か、何千もの異なるフィールドタイプと常に新しいフィールドタイプが存在する可能性のある科学データベースを使用した経験があります。これは、あなたが試みているように見えるのと同様に、私たちがそれを解決する方法です。問題は、(誰かが示唆したように)行を適切な形式に再構築し、アプリケーションに表示することです。これは2回のスイープで行いました。最初に、データベースに保存されたデータ(フィールドの場所やタイプなど)から画面を動的に作成し、次に利用可能な値からデータを入力しました。
まず、各フィールドの値を格納する値テーブルを作成しました。このテーブルはすべての値を保持するため、次のようになります。
ValueID
ItemID
FieldID
Value (e.g. "32" for size 32, "White" for a colour field etc)
次に、各フィールドの説明を保持するフィールドテーブルを作成しました。
FieldID
FieldName (e.g. Colour,size)
ScreenID
FieldDisplayName (used for displaying the name on the screen)
FieldDisplayNameXLocation (these next 4 define the location on the screen of the label and editing field)
FieldDisplayNameYLocation
FieldXLocation
FieldYLocation
FieldSize
FieldType (this is used for checking values are valid and for what type of field to display)
そして最後にScreenテーブル:
ScreenID
ScreenTitle
Screen Menus
etc...
次に、ユーザーの画面選択に応じて、画面とフィールドテーブルからデータをプルし、画面を動的に構築する「画面構築エンジン」を作成します。
SELECT ScreenTitle, ScreenMenus, ..., FieldID, FieldName,
FieldDisplayName, FieldLocations, FieldSize, FieldType
FROM Screen s INNER JOIN Field f ON s.ScreenID = f.ScreenID
これにより、エンジンが画面を構築するためのデータが得られます。画面は空白のキャンバスとして開始され、フィールドはありません。画面は、クエリによって返されるフィールドのタイプ/サイズと場所を使用して構築されます。次に、選択したアイテムに基づいて値テーブルからデータを抽出し、可視フィールドに挿入します。
SELECT ValueID, ItemID, FieldID, Value
FROM Field f INNER JOIN Value v ON f.FieldID = v.ValueID
WHERE ItemID = <user item ID entered>
これにより値が返され、エンジンは各値を画面の適切なフィールドに挿入します。
これは、実装するとうまくいき、テーブルに行を追加するだけで、アプリケーションとデータベース側に文字通り新しい「フィールド」を追加できるようになります。基本的に各フィールドはフィールドテーブルの行であり、行はフィールドが何であるかを定義します。ある時点で、約3秒でデータを挿入できるようにフィールドとラベルが定義された3つのまったく新しい画面を追加しました。ユーザーはアプリケーションを終了する必要さえありませんでした。画面が移動するとすぐに、画面は新しいデータベースフィールドと画面データで更新されます。
このアプローチの明らかな問題は次のとおりです。
ただし、次のような利点があります。
製品
ProdId
ProdName
プロパティ
(PropId) (primary key, if required)
ProdId (composite key)
PropCode (composite key)
PropValue (composite key) (if storing a specific value, otherwise you can remove this to simply store the possible properties for any given product)
基本的に、すべてが単一の製品を指す特定のプロパティに複数の値を格納します。複合キーは一意である必要があり、PropCodeを別のテーブルにリンクするか、エントリの値を制限することにより、データの整合性を確保する必要があります。