2

私は10個のテーブル(Product_A、Product_B、Product_Cなど)を持っています。それらのテーブルのそれぞれは、親テーブルProduct内の行を指すプライマリキーを持っています。多型関連を扱う:「あまりにも多くの」LEFT JOINのようなものはありますか?

基本的に、私はビルKarwin(ここで説明し、このアンチパターンソリューション: https://fr.slideshare.net/billkarwin/practical-object-oriented-models-in-sql/34-Polymorphic_Assocations_Exclusive_Arcs_Referential)からSQLアンチパターンブックからの勧告を適用している私はこのようなものを使用し、子製品をロードするために

を:

SELECT * FROM Product 
LEFT JOIN Product_A USING (product_id) 
LEFT JOIN Product_B USING (product_id) 
LEFT JOIN Product_C USING (product_id) 
LEFT JOIN Product_D USING (product_id) 
WHERE product_id = 1337 
etc. 

子テーブル製品の種類が増えるほど、JOIN句を追加する必要があります。追加する必要があるため、クエリが非常に遅くなってしまいます。

多型関連を防止するためにLEFT JOINを使用していますが、何十というサブツリーのテーブルを操作すると、反パターン処理が解決されますか?

「product_type」を取得し、親テーブルの「product_type」列に格納されている値に応じて、適切な子テーブルで別のクエリを実行するために、親テーブルProductのクエリを使用することを検討する必要があります?

更新:このトピックについての最初の返信は、これが悪いデザインであり、子テーブルの列を組み合わせた単一のテーブルを作成する必要があることを述べています。しかし、各製品タイプには独自の属性があります。そうでないと言うと、「テレビにはピクセル数があるかもしれませんが、それはミキサーにはあまり意味がありません」 @TomH

は、これらの表の中に起こっているどのような種類のデータ

+2

なぜ複数の商品表がありますか?カラムを持つ単一のテーブルに結合して、そのタイプ/グループを識別することはできませんか? –

+1

これはクラスの論理質問ですか、10個のテーブルを使用してソリューションを適用する必要がありますか?これは良いデータベース設計のようには見えません。 – justiceorjustus

+1

私は、それぞれの製品タイプが異なる属性を持っていると推測します。テレビではピクセル数があるかもしれませんが、それはミキサーにはあまり意味がありません。 –

答えて

3

MySQLでは、結合数に厳しい制限があります。制限は61個のジョインですが、設定はできません(ソースコードを見てみると実際にはハードコードされています)。したがって、62種類以上の製品タイプがある場合、これは単一のクエリでは機能しません。

データが記述した構造体に格納されていた場合は、製品タイプごとに個別のクエリを実行するため、あまりジョインをしないでください。

最初にProductテーブルに対してクエリを実行してから、詳細が必要な場合は製品タイプ別テーブルにクエリを追加します。

たとえば、製品固有の詳細をすべて一度に収集する必要がある場合は、何らかの検索ページで?検索ページのプライマリProductテーブルの属性のみを表示するようにコードを設計できると思いますか?

ユーザーが特定の製品をクリックした場合にのみ、別のページにアクセスして詳細情報を表示します。それとも、別のページではない場合は、詳細な情報を取得するための "+"ボタンを展開し、そのたびにAJAXリクエストを実行して詳細を表示するダイナミックなHTMLのものでしょう。

+2

私はあなたから答えを得ることを望んでいました。あなたはちょうど私の日を作った。 – Vincent

+0

61 - https://dev.mysql.com/doc/refman/5.7/ja/joins-limits.html。 (私はチェックしなければならなかった - 私の[_Limits_](http://mysql.rjweb.org/doc.php/limits)には61と書かれていますか、他の場所に63がありますか? –

+0

@RickJames、間違いです。 。ここで私は研究を投稿した:https://www.quora.com/For-what-reason-is-the-maximum-number-of-tables-that-c​​an-be-referenced-in-a-single-MySQL -join-61/answer/Bill-Karwin –

0

ありがとう?それは単に製品に関するメタデータですか?そうであれば、各製品について説明する背の高い表を作成することができます。

たとえば、product_id、product_data_key、valueの3つの列を持つProduct_Detailsテーブル。 product_data_keyは、Product_A、Product_B、Product_Cの列であったものです。

product_data_keyをよりよく記述する別のテーブルを作成することもできます。これはProduct_Detailsの外部キーです。

+0

Product_A、Product_B、Product_Cなどの各列には、実際に独自の表に固有の属性を定義する列があります。これらの列をすべて親表Productに追加するのは意味がありません。それは決して関連しません。 – Vincent

+0

Gotcha。そう、ええ、背の高いテーブルがここに必要なものかもしれません。 [この記事](https://powerpivotpro.com/2011/08/less-columns-more-rows-more-speed/)をご覧ください。基本的には、余分なテーブルのすべての列を単一のテーブルのより多くの行に変換することになります。 – ebraley

2

はい、product_type(いわゆる「弁別子」)を使用すると、DBMSがより良いクエリプランを作成し、不要な結合を避けるのに役立ちます。 DBMSは、右product_typeを持って参加し、対応することは避けてくださいショートすべての「支店」にできるはずです

SELECT 
    * 
FROM 
    Product 
    LEFT JOIN Product_A 
     ON product_type = 1 -- Or whatever is the actual value in your case. 
     AND Product.product_id = Product_A.product_id 
    LEFT JOIN Product_B 
     ON product_type = 2 
     AND Product.product_id = Product_B.product_id 
    LEFT JOIN Product_C 
     ON product_type = 3 
     AND Product.product_id = Product_C.product_id 
    LEFT JOIN Product_D 
     ON product_type = 4 
     AND Product.product_id = Product_D.product_id 
WHERE 
    Product.product_id = 1337 

:あなたはこのような何かを行うことができます。それはあなたがテストするべきものだ - これは実際にproduct_typeを取得するために別のクエリを使用して、その後、対応する「特別な」クエリを選択(および他のデータベース・ラウンドトリップを発生さ)よりも優れているかどうか

。代表的なデータ量については、いつものようにテストしてください!


少なくともOracleまたはSQL Serverがそれを行うだろう - MySQLのためにチェックしてください!

0

多分デザインを変更しますか? 1つの製品は多くの属性(および同じ属性の多く)を持つことができ、それらの属性は値を持ちます。その後あなたは、属性を再利用した製品にそれらを結ぶ、とその値を格納することができます

SELECT p.Product_Id, a.Attribute_Name, pa.Value FROM Products p 
JOIN ProductsAttributes pa ON pa.Product_Id = p.ProductId 
JOIN Attributes a ON a.Attribute_Id = pa.Attribute_Id 

Products  ProductsAttributes  Attributes 
-Product_Id  -Product_Id    -Attribute_Id 
-...   -Attribute_Id   -Attribute_Name 
       -Value     -... 
       -... 

のような使い方:

は、私は3つのテーブルを示唆しています。各製品には必要な属性のみがあります。

+2

これはEntity-Attribute-Valueまたは "EAV"として知られており、ワームのもう1つの缶です。 –

+1

EAV = Bad!悪いEAV、悪い! –

+0

@BrankoDimitrijevic皆さん、皆さんの正しい言葉があります:)私はこれに名前があるのか​​分かりませんでした!これを使用すると何が問題になりますか? – justiceorjustus

関連する問題