mysql-いくつの列が多すぎますか?


111

70列を超える可能性があるテーブルを設定しています。テーブルにアクセスするたびに列のデータの一部が必要になるわけではないので、分割することを考えています。次に、これを行うと、結合を使用する必要があります。

どの時点で、列が多すぎると考えられますか?


6
常にSELECT *を使用する必要はありません。特定の状況で必要な列のみを選択するオプションが常にあります。
APC、

3
70カラム?!nullにできないものはいくつありますか?
OMGポニー

1
大きな問題は...テーブルを正規化していますか?意図的にパフォーマンスを正規化しない限り、70は異常な量です(70の固有の属性を持つものはほとんどありません)。パフォーマンスのために非正規化している場合は、ChssPly76に同意します。これにより、データベースで実現できるものは何でも使用できるようになります。
Godeke

2
@KM。それは冗談だと思いますか?私はMySQLを初めて使用し、それを取得することはできません。JOINは良いことだと思いますか、それとも回避するべきでしょうか?
エリアイリアシェンコ2015年

2
結合はSQLのコア部分であるのと同じように、結合のために結合すると、アプリケーションのパフォーマンスと保守性が低下する可能性があります。
jeteon 2016年

回答:


142

データベースでサポートされている上限を超えると、多すぎると見なされます

すべてのクエリですべての列を返す必要がないという事実は、まったく正常です。そのため、SELECTステートメントでは、必要な列に明示的に名前を付けることができます。

原則として、テーブル構造はドメインモデルを反映する必要があります。同じエンティティに属している70(100、何を持っている)属性がある場合でも、それらを複数のテーブルに分割する理由はありません。


29
@KM-それが私が「ドメインモデルの同じエンティティに属する属性」と言った理由です。テーブルの列数が多いからといって非正規化されることはありません。それは問題の列がそれを表すと言ったものです。その上、正規化は間違いなく良いことですが、すべての人生の問題の解決策ではありません。トリックの質問-SOの質問/回答の横にある投票数はselect count(*) from votes毎回計算されると思いますか、それとも非正規化されていると思いますか?それはSOデータベースを悪くし、ジェフ・アトウッドをクレイジーにしますか?
ChssPly76

@ ChssPly76、それはオブジェクトモデルではなくリレーショナルデータベースです。テーブル、行、列があり、最大のパフォーマンスが必要な場合はその制約内で機能し、パフォーマンスのためにオブジェクトを模倣します。では、人に関するすべての情報を同じ行に格納する必要がありますか?いいえ、それらを分割し、それらを別のテーブルにグループ化します(私の例を使用して、以前のコメントを作成します):「Person」、「Activities」、「HealthRecords」。パフォーマンス上の理由でSUMを保存することは、結合を回避するためにすべてのデータを70列に保持することとはまったく別の問題です。
和基。

20
「numberOfTeethPulled」はPersonレコードの一部である必要がありますか?いいえ、おそらくまったく保存しないでください。ドメインモデルでこのような詳細レベルが必要な場合は、「ToothExtractionRecord」からその情報を取得します。しかし、それはあなたの(そして、あえて言うのはむしろ不自然な)例です。これは私のポイントとは関係ありません。テーブル内の列の数が多いからといって、テーブルが非正規化されているわけではありません。いくつかの例を挙げると、不動産契約/発注書/その他の財務文書を考えてください。それらをさらに複数のテーブルに分割できますか?はい。そうする理由はありますか?あんまり。
ChssPly76 09/09/25

1
+1、それは陽気だった。別のテーブルを作成していて、それが1対1の関係になる場合は、おそらくそれをメインテーブルに含める必要があります。スペースを節約するつもりはありません。データを要求しない場合は、テーブルにまったくない場合と比べて、パフォーマンスはそれほど向上しません。機密情報は、などSSN、クレジットカード情報、...のようにそこに存在する場合、今私のために頭に浮かぶ唯一の合法的な理由は、ある
Vandel212

1
1つのテーブルに15の列があり、別のテーブルに300の列がある場合、2つのテーブルの主キーは同じです。2つのテーブルで1つの列を選択します。パフォーマンスは大幅に異なりますか?
オファーは

28

テーブルをいくつかの列に分割することにはいくつかの利点があります。これは垂直分割とも呼ばれます。ここにいくつかあります:

  1. 多くの行を持つテーブルがある場合、MySQLはテーブル内のすべてのインデックスを再構築する必要があるため、インデックスの変更には非常に長い時間がかかる可能性があります。インデックスを複数のテーブルに分割すると、処理が速くなる場合があります。

  2. クエリと列のタイプによっては、MySQLが一時テーブル(より複雑な選択クエリで使用される)をディスクに書き込んでいる可能性があります。ディスクI / Oは大きなボトルネックになる可能性があるため、これは悪いことです。これは、クエリにバイナリデータ(テキストまたはBLOB)がある場合に発生します。

  3. テーブルの幅が広いと、クエリのパフォーマンスが低下する可能性があります。

時期尚早に最適化しないでください。ただし、場合によっては、より狭いテーブルから改善を得ることができます。


5
変更されたインデックスが1つだけの場合、MySQLがテーブル内のすべてのインデックスを再構築する必要があるのはなぜですか?
Petr Peller、2011年

同じことを思っていた。MySQLがテーブル内のすべてのインデックスを再構築する理由 上記の記述は正しいですか?
maj 2017年

13

正規化のルールに違反している場合は多すぎます。データベースを正規化している場合、多くの列を取得するのはかなり困難です。データベースを設計して、問題をモデル化します。特定のdbプラットフォーム用に最適化するための人為的なルールやアイデアは避けてください。

幅の広いテーブルに次のルールを適用すると、1つのテーブルの列がはるかに少なくなる可能性があります。

  1. 繰り返し要素や要素グループはありません
  2. 連結されたキーに部分的に依存しない
  3. 非キー属性に依存しない

ここにあなたを助けるためのリンクがあります。


17
It is pretty hard to get that many columns if you are normalizing your database.見た目ほど難しくはありません。
Petr Peller、2011年

5
そんなに難しいことではありません。人々はこれらのここの部分の周りの通常の形を本当に理解していないようです。10000列にすることができ、STILLは正規化されます(最高の正規形であっても)。
Hejazzman 2013

2
@foljsそして、ここで非正規化の慣行が受け入れられます。交差点にいて、車が車に乗り込もうとしている場合、ライトが緑色に変わるのを待つのは愚かでしょう。邪魔にならないでください。赤色信号を通過することは技術的には合法ではないかもしれませんが、状況=非正規化を前提として明らかにすべきことを実行しています
user3308043 '27

3
車について話し始めたとき、あなたは私を失いました。関連性が何であるかわからない。
JohnFx

2
ただし、このシナリオで単一のデータテーブルを使用して複雑なクエリを実行する方法はできません。これを行うには、プログラミング言語やその他のさまざまなものに大きく依存する必要があります。したがって、170列のテーブルに戻ることもできます。 "JOIN"クエリと、個別のテーブルを機能させるために必要な非常に複雑なプログラミングを行うことは、時間の無駄のように思えます。私はKISS原理の大ファンだと思います。
Vlad Vladimir Hercules

0

すべての属性が同じエンティティーに属し、相互に依存していない限り、これは問題ではありません。人生を楽にするために、JSON配列が格納されたテキスト列を1つ持つことができます。明らかに、毎回すべての属性を取得することに問題がない場合。ただし、これはRDBMSに格納する目的を完全に無効にし、すべてのデータベーストランザクションを非常に複雑にします。したがって、データベース全体で従うことは推奨されないアプローチです。


0

同じテーブルに列が多すぎると、レプリケーションでも大きな問題が発生する可能性があります。マスターで発生する変更はスレーブに複製されることを知っておく必要があります。たとえば、テーブルの1つのフィールドを更新すると、行全体がwになります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.