1699列のテーブルがあり、さらに列を挿入しようとすると、
エラーコード:1117。列が多すぎます
この表では、1000行しかありません。私にとって最も重要なことは、列の数です。テーブルに制限はありますか? 2000列を作成します。それは可能ですか?
なぜ2000列は言うまでもなく、20列さえあるテーブルを作成する必要があるのでしょうか???
許可された非正規化データにより、JOINを実行して多くのデータ列を取得する必要がなくなる場合があります。ただし、10を超える列がある場合は、停止して、データの取得中に内部で何が起こるかを考える必要があります。
2000列のテーブルがSELECT * FROM ... WHEREを受ける場合、処理中に大きな一時テーブルを生成し、不要な列をフェッチし、通信パケット( max_allowed_packet )がプッシュされる多くのシナリオを作成しますすべてのクエリの瀬戸際に。
開発者としての私は、1995年にDB2がメインのRDBMSだった会社で働いていました。同社には、270列、数十のインデックスを持つ単一のテーブルがあり、データの取得でパフォーマンスの問題がありました。彼らはIBMに連絡し、コンサルタントにこの1つのモノリシックテーブルを含むシステムのアーキテクチャを調べてもらいました。 「今後2年間でこのテーブルを正規化しないと、DB2はStage2処理を実行するクエリ(インデックス付けされていない列でのソートが必要なクエリ)で失敗します。」これは、数兆ドル規模の企業に270列のテーブルを正規化するように言われました。さらに2000列のテーブルです。
MySQLに関しては、DB2 Stage2処理に相当するオプションを設定することにより、このような悪い設計を補う必要があります。この場合、これらのオプションは
RAMがTBの場合、数百、さらに数百の列の存在を補うためにこれらの設定を調整することは、うまく機能します。
InnoDBを使用する場合、この問題は幾何学的に増大します MVCC(Multiversion Concurrency Control) トランザクションの分離を通じて各SELECT、UPDATE、DELETEで大量の列を保護しようとします。
[〜#〜]結論[〜#〜]
悪いデザインを補うことができる代用品やバンドエイドはありません。将来の正気のために、今日そのテーブルを正規化してください!!!
データモデルが適切に正規化されたテーブルに2000列を正当に含めることができる場所を想像するのに苦労しています。
私の推測では、ある種の「空白を埋める」非正規化スキーマを実行していると思います。実際には、さまざまな種類のデータをすべて1つのテーブルに格納し、データを別々のテーブルに分割してリレーションを作成するのではありません。 、特定の行に格納されているデータの「タイプ」を記録するさまざまなフィールドがあり、フィールドの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>
各センサーの詳細が必要な場合は、さらに参加します。
2000センサーの測定システムです
正規化について叫んでいるすべてのコメントを無視してください-あなたが求めているのは(理想的な世界では)賢明なデータベース設計であり、完全に十分に正規化されている可能性があります。 。
MySQL ハードリミット には到達していませんが、リンクに記載されている他の要因の1つが原因で、それ以上高くできない可能性があります
他の人が示唆しているように、id, sensor_id, sensor_value
を使用して子テーブルを作成することでこの制限を回避できます。より簡単には、最初のテーブルに収まらない列だけを含む2番目のテーブルを作成します(同じPKを使用します)。 )
MySQL 5.0列数制限 (強調を追加):
テーブルごとに4096列のハード制限がありますが、特定のテーブルの有効な最大値はこれよりも少ない場合があります。正確な制限は、いくつかの相互作用する要因によって異なります。
すべてのテーブル(ストレージエンジンに関係なく)の最大行サイズは65,535バイトです。ストレージエンジンはこの制限に追加の制約を課し、有効な最大行を減らします。サイズ。
すべての列の合計の長さがこのサイズを超えることはできないため、最大行サイズは列の数(場合によってはサイズ)を制限します。
...
個々のストレージエンジンによって、テーブルの列数を制限する追加の制限が課される場合があります。例:
- InnoDBは最大1000列を許可します。
最初にさらに燃えるように、次に実際の解決策...
私はほとんどあなたにすでに投げられた炎に同意します。
Key-Valueの正規化に同意しません。クエリはひどいものになります。パフォーマンスはさらに悪化します。
差し迫った問題(列数の制限)を回避する1つの「簡単な」方法は、データを「垂直分割」することです。たとえば、それぞれ400列の5つのテーブルがあるとします。 AUTO_INCREMENTである場合を除いて、それらはすべて同じ主キーを持ちます。
おそらく、最も重要な数十のフィールドを決定し、それらを「メイン」テーブルに入れる方が良いでしょう。次に、センサーをいくつかの論理的な方法でグループ化し、いくつかの並列テーブルに配置します。適切なグループ化により、常にすべてのテーブルを結合する必要がない場合があります。
値のインデックスを作成していますか?それらを検索する必要がありますか?おそらくあなたはdatetimeで検索しますか?
多数の列にインデックスを付ける必要がある場合-パント。
いくつかのインデックスを作成する必要がある場合は、それらをメインテーブルに入れます。
これが実際の解決策です(該当する場合)...
インデックス化された膨大な数のセンサーが必要ない場合は、列を作成しないでください。はい、あなたは私を聞いた。代わりに、それらをJSONに収集し、JSONを圧縮して、BLOBフィールドに格納します。スペースを大幅に節約できます。列制限の問題ではなく、テーブルは1つしかありません。 etc.アプリケーションは解凍され、JSONを構造として使用します。何だと思う?アプリのように、センサーを配列やマルチレベルのものなどにグループ化して、構造を持つことができます。もう1つの「機能」-オープンエンドです。さらにセンサーを追加する場合、テーブルを変更する必要はありません。そのように柔軟であればJSON。
(圧縮はオプションです。データセットが巨大な場合は、ディスクスペースを節約できるため、全体的なパフォーマンスが向上します。)
これは、ビッグデータの世界で考えられるシナリオであり、従来のselect *タイプのクエリを実行していない可能性があります。私たちはこれを顧客レベルの予測モデリングの世界で扱います。ここでは、何千ものディメンション(すべて0または1の値を持つ)にわたって顧客をモデル化します。このストレージ方法により、同じ行にリスク要因があり、同じ行に結果フラグがある場合でも、下流のモデル構築アクティビティなどが簡単になります。これは、親の子構造を持つストレージの観点から正規化できますが、ダウンストリームの予測モデルは、それをフラットスキーマに戻す必要があります。私たちは、列のストレージを行うredshiftを使用しているため、データをロードすると、1000以上の列は実際には列の形式で保存されます...
このデザインには時間と場所があります。もちろんです。正規化はすべての問題の解決策ではありません。