1699列のテーブルがあり、さらに列を挿入しようとすると、
エラーコード:1117。列が多すぎます
このテーブルには、1000行しかありません。私にとって最も重要なことは、列の数です。テーブルに制限はありますか?2000列を作成します。それは可能ですか?
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 Processingに匹敵するオプションを設定することにより、このような悪い設計を補う必要があります。この場合、これらのオプションは
TBのRAMがあれば、これらの設定を数十、何百、何百という列の存在を補うためにうまく機能します。
InnoDBを使用する場合、トランザクションの分離を通じて各SELECT、UPDATE、およびDELETEで大量の列を保護しようとするMVCC(Multiversion Concurrency Control)を処理する必要があるため、この問題は幾何学的に増大します。
結論
悪いデザインを補うことができる代替物やバンドエイドはありません。将来の正気のために、今日そのテーブルを正規化してください!!!
データモデルが適切に正規化されたテーブルに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>
そして、各センサーの詳細が必要な場合はさらに参加します。
2000個のセンサーを備えた測定システムです
正規化について叫ぶコメントをすべて無視します-あなたが求めているのは、賢明なデータベース設計(理想的な世界)であり、完全に正規化されている可能性があります、それは非常に珍しいことです。 。
MySQLのハード制限に達していませんが、リンクで言及されている他の要因の1つは、おそらくあなたが高くなるのを妨げていることです。
他の人が示唆しているように、この制限を回避するには、で子テーブルをid, sensor_id, sensor_value
作成するか、より簡単に、最初のテーブルに収まらない列だけを含む2番目のテーブルを作成します(同じPKを使用します)
MySQL 5.0の列数制限(強調を追加):
テーブルごとに4096列のハード制限がありますが、有効な最大値は特定のテーブルではより少ない場合があります。正確な制限は、相互作用するいくつかの要因に依存します。
すべてのテーブル(ストレージエンジンに関係なく)の最大行サイズは65,535バイトです。ストレージエンジンは、この制限に追加の制約を課し、有効な最大行サイズを縮小する場合があります。
すべての列の合計の長さがこのサイズを超えることはできないため、最大行サイズは列の数(および場合によってはサイズ)を制限します。
...
個々のストレージエンジンは、テーブルの列数を制限する追加の制限を課す場合があります。例:
- InnoDBは最大1000列を許可します。
最初にもう少し燃え上がり、次に本当の解決策...
私はすでにあなたに投げつけられた炎に同意します。
キー値の正規化に同意しません。クエリは恐ろしくなります。パフォーマンスはさらに悪化します。
差し迫った問題(列の数の制限)を回避するための1つの「簡単な」方法は、データを「垂直方向に分割」することです。たとえば、それぞれ400列の5つのテーブルがあるとします。AUTO_INCREMENTである場合を除き、これらはすべて同じ主キーを持ちます。
おそらく、最も重要な12個のフィールドを決定し、それらを「メイン」テーブルに入れる方が良いでしょう。次に、センサーを論理的な方法でグループ化し、複数の並列テーブルに配置します。適切にグループ化すると、すべてのテーブルを常に結合する必要がなくなる場合があります。
値のいずれかにインデックスを付けていますか?それらを検索する必要がありますか?おそらくdatetimeで検索しますか?
多数の列にインデックスを付ける必要がある場合-パント。
いくつかのインデックスが必要な場合は、それらを「メインテーブル」に入れます。
実際のソリューションは次のとおりです(該当する場合)...
膨大な数のセンサーのインデックスが必要ない場合は、列を作成しないでください!はい、あなたは私を聞いた。代わりに、それらをJSONに収集し、JSONを圧縮して、BLOBフィールドに保存します。大量のスペースを節約できます。列の制限の問題ではなく、テーブルは1つしかありません。など。アプリケーションは圧縮を解除し、JSONを構造体として使用します。何だと思う?構造を持つことができます。アプリが望むように、センサーを配列、マルチレベルのものなどにグループ化できます。もう1つの「機能」-それは無制限です。さらにセンサーを追加する場合、テーブルを変更する必要はありません。そのように柔軟な場合はJSON。
(圧縮はオプションです。データセットが非常に大きい場合、ディスク容量が増えるため、全体的なパフォーマンスが向上します。)
JSON
「列が多すぎる」ことを避けます。選択した列にインデックスを付けると、パフォーマンスが向上します。
これは、従来のselect *タイプのクエリを実行していない可能性があるビッグデータの世界で考えられるシナリオと考えています。これは、数千の次元(すべてが0または1の値を持つ)にわたって顧客をモデル化する顧客レベルの予測モデリングの世界でこれに対処します。この保存方法により、同じ行にリスク要因があり、同じ行に結果フラグがある場合、ダウンストリームモデルの作成アクティビティなどが簡単になります。これは、親の子構造を持つストレージの観点から正規化できますが、下流の予測モデルは、それをフラットスキーマに変換する必要があります。カラムナーストレージを行うredshiftを使用しているため、データをロードするときに1000以上のカラムが実際にカラムナー形式で格納されます...
この設計には時間と場所があります。絶対に。正規化はすべての問題の解決策ではありません。