エラーコード1117列が多すぎます。テーブルのMySQL列制限


37

1699列のテーブルがあり、さらに列を挿入しようとすると、

エラーコード:1117。列が多すぎます

このテーブルには、1000行しかありません。私にとって最も重要なことは、列の数です。テーブルに制限はありますか?2000列を作成します。それは可能ですか?


21
良い主よ、一体何のために。これは、非常に貧弱なデータベース設計のような匂いがします。または、ジョブに間違ったツールを使用している可能性があります。おそらく、あなたは見てする必要があるデータベースの正規化
Zoredache

12
モニターを90度回転させます。さらに深刻なのは、MySQL(または他のほとんどすべてのRDBMS)が多くの列向けに設計されていないことです。

11
そして、なぜ2000個のセンサーが2000個のカラムにつながるのですか?データベースを再設計します。別のセンサーテーブルなどを作成しますが、各センサーを新しい列として追加しないでください。それは信じられないほど間違ったことです。

6
最大テーブル数...おっと!おそらく、いくつかのテーブルのみが必要になります。2000列ではなく2000テーブルを作成することさえ考えないでください!

2
データベースの正規化についてお読みください。

回答:


35

2000はもちろん、20列のテーブルを作成する必要があるのはなぜですか?

付与された非正規化データにより、JOINを実行してデータの多くの列を取得する必要がなくなります。ただし、10を超える列がある場合は、停止して、データ取得中に内部で何が起こるかを考える必要があります。

2000列のテーブルがSELECT * FROM ... WHEREを受ける場合、処理中に大きな一時テーブルを生成し、不要な列をフェッチし、すべてのクエリで通信パケット(max_allowed_pa​​cket)が瀬戸際にプッシュされる多くのシナリオを作成します。

開発者としての初期の頃、私は1995年にDB2が主要なRDBMSであった会社で働いていました。同社には、270列、数十のインデックスがあり、データの取得にパフォーマンスの問題がある単一のテーブルがありました。彼らはIBMに連絡し、コンサルタントにこの1つのモノリシックテーブルを含むシステムのアーキテクチャを調べてもらいました。会社は、「今後2年間でこのテーブルを正規化しないと、DB2はStage2処理を実行するクエリ(インデックスのない列での並べ替えを必要とするクエリ)で失敗します」と言われました。これは、270桁のテーブルを正規化するために、数兆ドルの会社に伝えられました。2000列のテーブルがどれだけ大きいか。

mysqlに関しては、DB2 Stage2 Processingに匹敵するオプションを設定することにより、このような悪い設計を補う必要があります。この場合、これらのオプションは

TBのRAMがあれば、これらの設定を数十、何百、何百という列の存在を補うためにうまく機能します。

InnoDBを使用する場合、トランザクションの分離を通じて各SELECT、UPDATE、およびDELETEで大量の列を保護しようとするMVCC(Multiversion Concurrency Control)を処理する必要があるため、この問題は幾何学的に増大します。

結論

悪いデザインを補うことができる代替物やバンドエイドはありません。将来の正気のために、今日そのテーブルを正規化してください!!!


1
これを言われたとき、会社がどうするか想像できました。svnフックを追加するか、「DBベストプラクティスガイドライン」を作成して、開発者にSQLの非インデックス列をソートしないように依頼します。代わりに、独自の大規模なデータソートアルゴリズムを実装して、アプリケーション内でソートを行います。
Gqqnbig

25

データモデルが適切に正規化されたテーブルに2000列を合法的に含むことができるものを想像するのは困難です。

私の推測では、おそらく何らかのデータを別々のテーブルに分割してリレーションを作成する代わりに、ある種の「空白を埋める」非正規化スキーマを実行していると思われます。 、特定の行に格納されているデータの「タイプ」を記録するさまざまなフィールドがあり、フィールドの90%がNULLです。しかし、それでも、2000カラムに到達したいのです...

問題の解決策は、データモデルを再考することです。特定のレコードに関連付けられた大量のキー/値データを保存している場合、そのようにモデル化してみませんか?何かのようなもの:

CREATE TABLE master (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields that really do relate to the
    master records on a 1-to-1 basis>
);

CREATE TABLE sensor_readings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    master_id INT NOT NULL,   -- The id of the record in the
                              -- master table this field belongs to
    sensor_id INT NOT NULL,
    value VARCHAR(255)
);

CREATE TABLE sensors (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields relating to sensors>
);

次に、特定の「マスター」レコードに関連付けられているすべてのセンサーエントリを取得するには、を実行しますSELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>。あなたがレコードのデータを取得する必要がある場合はmasterそのレコードのためのセンサデータのすべてと一緒にテーブル、あなたが参加使用することができます。

SELECT master.*,sensor_readings.sensor_id,sensor_readings.value
FROM master INNER JOIN sensor_readings on master.id=sensor_readings.master_id
WHERE master.id=<some ID>

そして、各センサーの詳細が必要な場合はさらに参加します。


18

2000個のセンサーを備えた測定システムです

正規化について叫ぶコメントをすべて無視します-あなたが求めているのは、賢明なデータベース設計(理想的な世界)であり、完全に正規化されている可能性があります、それは非常に珍しいことです。 。

MySQLのハード制限に達していませんが、リンクで言及されている他の要因の1つは、おそらくあなたが高くなるのを妨げていることです。

他の人が示唆しているように、この制限を回避するには、で子テーブルをid, sensor_id, sensor_value作成するか、より簡単に、最初のテーブルに収まらない列だけを含む2番目のテーブルを作成します(同じPKを使用します)


1
これは本当です。データと対応するSQLを細心の注意を払って処理するとき、あなたの答えはさらに際立ちます!!!
RolandoMySQLDBA

3
子テーブルを使用することは「回避策」ではありません。センサーごとに1つの列を持つことは、単に悪い(間違った)デザインです。これは、人事システムの従業員ごとに1列、または自動車モデルを管理するDBのすべての自動車メーカーごとに1列を持つようなものです。
a_horse_with_no_name

11
@a_horse-あなたは、私が有効だとは思わないという仮定をしている。センサーの数が基本的に固定され、すべてが同時に読み取られ、すべてのデータが毎回返される可能性は十分にあります。この場合、センサーごとに1つの列が「間違っている」わけではなく、データベースの制限を考えると単に非実用的です。質問者は別の方法で証明されるまで馬鹿ではないと思いますが、iUngiはSFの群衆からの非常に役に立たない応答に直面して尊厳をもって応答しました。
ジャックダグラス

2
@Jack Douglas:あなたの仮定がすべて真実であったとしても(非常に疑わしい)、各センサー値を独自の列に格納すると、長期的には問題が発生します。「昨日から今日までのセンサー10〜50および25〜100の平均値はどれくらいですか」などのクエリはどうでしょうか。または「先週の月曜日に、どのセンサーが最高の読み取り値を示しましたか?」2000列を使用して、このクエリを作成してみてください。正規化されたテーブルを使用すると、2000カラムのソリューションが現在解決するよりも長い目で見ればより多くの問題を解決できます。
a_horse_with_no_name

2
確かに、センサーが関連する値を保存している場合-私はそれらが関連していないと仮定しています(たとえば、それらはすべて異なる場所で基本的に同じものではなく、異なる種類のものを測定しています)。あなたはそれを疑うかもしれませんが、OPだけが確実に知っています-そしてそれは医学または科学の分野で不可能ではありません。
ジャックダグラス

15

MySQL 5.0の列数制限(強調を追加):

テーブルごとに4096列のハード制限がありますが、有効な最大値は特定のテーブルではより少ない場合があります。正確な制限は、相互作用するいくつかの要因に依存します。

  • すべてのテーブル(ストレージエンジンに関係なく)の最大行サイズは65,535バイトです。ストレージエンジンは、この制限に追加の制約を課し、有効な最大行サイズを縮小する場合があります。

    すべての列の合計の長さがこのサイズを超えることはできないため、最大行サイズは列の数(および場合によってはサイズ)を制限します。

...

個々のストレージエンジンは、テーブルの列数を制限する追加の制限を課す場合があります。例:

  • InnoDBは最大1000列を許可します。

7

最初にもう少し燃え上がり、次に本当の解決策...

私はすでにあなたに投げつけられた炎に同意します。

キー値の正規化に同意しません。クエリは恐ろしくなります。パフォーマンスはさらに悪化します。

差し迫った問題(列の数の制限)を回避するための1つの「簡単な」方法は、データを「垂直方向に分割」することです。たとえば、それぞれ400列の5つのテーブルがあるとします。AUTO_INCREMENTである場合を除き、これらはすべて同じ主キーを持ちます。

おそらく、最も重要な12個のフィールドを決定し、それらを「メイン」テーブルに入れる方が良いでしょう。次に、センサーを論理的な方法でグループ化し、複数の並列テーブルに配置します。適切にグループ化すると、すべてのテーブルを常に結合する必要がなくなる場合があります。

値のいずれかにインデックスを付けていますか?それらを検索する必要がありますか?おそらくdatetimeで検索しますか?

多数の列にインデックスを付ける必要がある場合-パント。

いくつかのインデックスが必要な場合は、それらを「メインテーブル」に入れます。

実際のソリューションは次のとおりです(該当する場合)...

膨大な数のセンサーのインデックスが必要ない場合は、列を作成しないでください!はい、あなたは私を聞いた。代わりに、それらをJSONに収集し、JSONを圧縮して、BLOBフィールドに保存します。大量のスペースを節約できます。列の制限の問題ではなく、テーブルは1つしかありません。など。アプリケーションは圧縮を解除し、JSONを構造体として使用します。何だと思う?構造を持つことができます。アプリが望むように、センサーを配列、マルチレベルのものなどにグループ化できます。もう1つの「機能」-それは無制限です。さらにセンサーを追加する場合、テーブルを変更する必要はありません。そのように柔軟な場合はJSON。

(圧縮はオプションです。データセットが非常に大きい場合、ディスク容量が増えるため、全体的なパフォーマンスが向上します。)


これが実際のベストアンサーです。多分彼はそれほど多くのコラムを持たないで研究するべきだとコメントすることは問題ありませんが、受け入れられた答えが「それをしないでください」であるということは質問に答えません。この人がそれほど多くの列を必要としない場合でも、このQを見つける他の誰かがその多くを必要とし、本当の答えを必要とする可能性があります。
BoB3K

@ BoB3K-述べられている問題に関する利用可能な情報を考えると、私の大きな段落は何をすべきかを述べています。 JSON「列が多すぎる」ことを避けます。選択した列にインデックスを付けると、パフォーマンスが向上します。
リックジェームズ

3

これは、従来のselect *タイプのクエリを実行していない可能性があるビッグデータの世界で考えられるシナリオと考えています。これは、数千の次元(すべてが0または1の値を持つ)にわたって顧客をモデル化する顧客レベルの予測モデリングの世界でこれに対処します。この保存方法により、同じ行にリスク要因があり、同じ行に結果フラグがある場合、ダウンストリームモデルの作成アクティビティなどが簡単になります。これは、親の子構造を持つストレージの観点から正規化できますが、下流の予測モデルは、それをフラットスキーマに変換する必要があります。カラムナーストレージを行うredshiftを使用しているため、データをロードするときに1000以上のカラムが実際にカラムナー形式で格納されます...

この設計には時間と場所があります。絶対に。正規化はすべての問題の解決策ではありません。


コメントありがとうございます。画像で分析を行いたい場合、16x16ピクセルの小さなカラー画像でも、0〜255の16 * 16 * 3整数が必要です(RGBカラーを使用して16x16ピクセルの1つで色を表す3つの数字)。これはデータ用の768列であり、キーを追加する必要があります。
VictorZurkowski
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.