web-dev-qa-db-ja.com

複数のテーブルを結合して集約するか、属性を組み合わせて単一のテーブルを作成します

次のER図があります。

enter image description here

前述のように、単一のテーブルARTDATAを使用するか、リレーションで相互にリンクした13の異なるテーブルを使用するかを選択できます。

問題は、アートごとにすべての属性を表示する必要があることです。つまり、アートごとに、TYPE、AUTHOR、TIMEFRAME、FORM、LOCATION AND SCHOOLをフェッチする必要があります。そのためには、これらすべてのテーブルを結合する必要があり、時間がかかる場合があります。ただし、常に単一テーブルのARTDATAの代替案を使用して、すべてを1つの場所で取得できます。

私のデータセットが大きく(50000以上のエントリ)、将来成長することを考えると、どのソリューションが最適ですか?

13個のテーブルを使用する場合、すべてのテーブルをマージするのに最適なクエリは何ですか?私の哀れな試みを以下に記します。

select 
t1.ID,
t1.TITLE,
t1.DATE,
t1.TECHNIQUE,
t1.URL,
t3.AUTHOR,
t3.BORN_DIED,
t5.FORM,
t7.LOCATION,
t9.SCHOOL,
t11.TIMEFRAME,
t13.TYPE

from
ART t1 inner join 

ART_AUTHOR t2 on t1.id=t2.art_id inner join 
AUTHOR t3 on t3.id=t2.author_id inner join

ART_FORM t4 on t1.id=t4.art_id inner join 
FORM t5 on t4.form_id=t5.id inner join 

ART_LOCATION t6 on t1.id=t6.art_id inner join 
LOCATION t7 on t6.location_id=t7.id inner join 

ART_SCHOOL t8 on t1.id=t8.art_id inner join 
SCHOOL t9 on t8.school_id=t9.id inner join 

ART_TIMEFRAME t10 on t1.id=t10.art_id inner join 
TIMEFRAME t11 on t10.timeframe_id=t11.id inner join 

ART_TYPE t12 on t1.id=t12.art_id inner join 
TYPE t13 on t12.type_id=t13.id; 

あなたは要点を手に入れます、それは野蛮です。

更新:

テーブルを更新し、上記のクエリを使用してARTDATAというビューを作成しました。これが更新ERです。

UPDATED ER

1
Mercurial

1つのテーブルを6つの他のテーブルにリンクする6つの多対多のテーブルがありますか?

それらのいずれかが1対多の場合は、リンクテーブルをトスします。

正規化は良好です。過正規化は悪いです。

LOCATIONだけが含まれているのに、なぜテーブルLOCATIONがあるのですか?

多対多のテーブルはやや非効率的です。 (部分的なソリューションについては、これを参照してください: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table )。

反対に、5万行は「小さな」テーブルです。サイズは50MBで、サーバーに簡単に収まるはずです。

正規化は次の場合に役立ちます。

  • 単一の場所で変更できるように名前を分離する(これは必要ですか?)、または
  • スペースを節約するため(以下を参照)、または
  • 複数の属性を一緒に収集する(例:AUTHOR

スペースの節約の必要性に反対したと私は思います。

AUTHORの場合、複数の列が存在するため、AUTHORテーブルがあることは、そのために意味があります。

1
Rick James

複数の値が必要な場合(1つのARTに複数の著者がいるなど)、このようなリンクが必要です。それが必要ない場合は、ARTテーブルにすべてのIDを含めてください。

単一の値で十分なすべての属性IDをARTに移動し、外部リンクテーブルを介したより複雑な種類のリンクを使用して複数値のIDのみを残すことをお勧めします。

1