it-swarm.asia

Kode Kesalahan 1117 Terlalu banyak kolom; Batas kolom pada tabel MySQL

Saya memiliki tabel dengan 1699 kolom dan ketika saya mencoba memasukkan lebih banyak kolom,

Kode Kesalahan: 1117. Terlalu banyak kolom

Dalam tabel ini saya hanya memiliki 1000 baris. Bagi saya yang terpenting adalah jumlah kolom. Apakah ada batasan di atas meja? Saya ingin membuat 2000 kolom. Apakah itu mungkin?

38
OHLÁLÁ

Mengapa Anda perlu membuat tabel dengan genap 20 kolom, apalagi 2000 ???

Memang, data yang dinormalisasi dapat mencegah keharusan melakukan GABUNG untuk mengambil banyak kolom data. Namun, jika Anda memiliki lebih dari 10 kolom, Anda harus berhenti dan memikirkan apa yang akan terjadi di bawah tenda selama pengambilan data.

Jika tabel kolom 2000 mengalami SELECT * FROM ... WHERE, Anda akan menghasilkan tabel temp besar selama pemrosesan, mengambil kolom yang tidak perlu, dan membuat banyak skenario di mana paket komunikasi ( max_allowed_packet ) akan didorong ke tepi di setiap permintaan.

Pada hari-hari awal saya sebagai pengembang, saya bekerja di sebuah perusahaan pada tahun 1995 di mana DB2 adalah RDBMS utama. Perusahaan memiliki satu tabel yang memiliki 270 kolom, lusinan indeks, dan memiliki masalah kinerja mengambil data. Mereka menghubungi IBM dan meminta konsultan memeriksa arsitektur sistem mereka, termasuk tabel monolitik yang satu ini. Perusahaan diberi tahu "Jika Anda tidak menormalkan tabel ini dalam 2 tahun ke depan, DB2 akan gagal pada kueri yang melakukan Pemrosesan Stage2 (setiap kueri yang membutuhkan pengurutan pada kolom yang tidak diindeks)." Ini diceritakan kepada perusahaan multi-triliun dolar, untuk menormalkan tabel 270 kolom. Terlebih lagi tabel kolom 2000.

Dalam hal mysql, Anda harus mengimbangi desain yang buruk dengan menetapkan opsi yang sebanding dengan DB2 Stage2 Processing. Dalam hal ini, opsi tersebut adalah

Tweeking pengaturan ini untuk menebus kehadiran lusinan, apalagi ratusan, kolom bekerja dengan baik jika Anda memiliki TB RAM.

Masalah ini berlipat ganda secara geometris jika Anda menggunakan InnoDB karena Anda harus berurusan dengan MVCC (Multiversion Concurrency Control) mencoba melindungi ton kolom dengan setiap SELECT, UPDATE dan DELETE melalui isolasi transaksi.

[~ # ~] kesimpulan [~ # ~]

Tidak ada pengganti atau bantuan-band yang dapat menggantikan desain yang buruk. Tolong, demi kewarasan Anda di masa depan, normalkan meja itu hari ini !!!

37
RolandoMySQLDBA

Saya mengalami kesulitan membayangkan apa pun di mana model data dapat secara sah memuat 2000 kolom dalam tabel yang dinormalisasi dengan benar.

Dugaan saya adalah bahwa Anda mungkin melakukan semacam skema "isi kosong" skema dinormalisasi, di mana Anda sebenarnya menyimpan semua jenis data yang berbeda dalam satu tabel, dan bukannya memecah data ke dalam tabel terpisah dan membuat hubungan , Anda memiliki berbagai bidang yang merekam "tipe" data apa yang disimpan dalam baris tertentu, dan 90% bidang Anda NULL. Meskipun begitu, meskipun, ingin mencapai 2000 kolom ... ya.

Solusi untuk masalah Anda adalah memikirkan kembali model data Anda. Jika Anda menyimpan banyak data kunci/nilai yang terkait dengan catatan yang diberikan, mengapa tidak memodelkannya seperti itu? Sesuatu seperti:

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>
);

Kemudian untuk mendapatkan semua entri sensor yang terkait dengan catatan "master" yang diberikan, Anda bisa saja SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>. Jika Anda perlu mendapatkan data untuk catatan di tabel master bersama dengan semua data sensor untuk catatan itu, Anda bisa menggunakan gabungan:

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>

Dan kemudian bergabung lebih jauh jika Anda membutuhkan detail dari masing-masing sensor.

25
womble

Ini adalah sistem pengukuran dengan 2000 sensor

Abaikan semua komentar yang berteriak tentang normalisasi - apa yang Anda minta bisa menjadi desain database yang masuk akal (di dunia yang ideal) dan dinormalisasi dengan sangat baik, itu hanya sangat tidak biasa, dan seperti yang ditunjukkan di tempat lain, RDBMS biasanya tidak dirancang untuk banyak kolom ini. .

Meskipun Anda tidak memukul MySQL batas keras , salah satu faktor lain yang disebutkan dalam tautan mungkin mencegah Anda naik lebih tinggi

Seperti yang disarankan orang lain, Anda dapat mengatasi keterbatasan ini dengan memiliki meja anak dengan id, sensor_id, sensor_value, atau lebih sederhana, Anda bisa membuat tabel kedua untuk berisi hanya kolom yang tidak cocok di yang pertama (dan menggunakan PK yang sama)

Batas Jumlah Kolom MySQL 5. (penekanan ditambahkan):

Ada batas keras 4096 kolom per tabel , tetapi maksimum efektif mungkin kurang untuk tabel yang diberikan. Batas yang tepat tergantung pada beberapa faktor yang saling berinteraksi.

  • Setiap tabel (terlepas dari mesin penyimpanan) memiliki ukuran baris maksimum 65.535 byte. Mesin penyimpanan dapat menempatkan kendala tambahan pada batas ini, mengurangi baris maksimum efektif ukuran.

    Ukuran baris maksimum membatasi jumlah (dan kemungkinan ukuran) kolom karena panjang total semua kolom tidak dapat melebihi ukuran ini.

...

Mesin penyimpanan individual dapat memberlakukan batasan tambahan yang membatasi jumlah kolom tabel. Contoh:

  • InnoDB memungkinkan hingga 1000 kolom.
15
lg_

Pertama beberapa lebih menyala, lalu solusi nyata ...

Saya sebagian besar setuju dengan api yang sudah dilemparkan pada Anda.

Saya tidak setuju dengan normalisasi nilai kunci. Pertanyaan akhirnya menjadi mengerikan; kinerja lebih buruk.

Salah satu cara 'sederhana' untuk menghindari masalah langsung (pembatasan jumlah kolom) adalah dengan 'mempartisi data' secara vertikal. Memiliki, katakanlah, 5 tabel dengan masing-masing 400 kolom. Mereka semua akan memiliki kunci utama yang sama, kecuali satu mungkin memiliki itu menjadi AUTO_INCREMENT.

Mungkin lebih baik untuk memutuskan selusin bidang yang paling penting, menempatkan mereka di tabel 'utama'. Kemudian kelompokkan sensor dengan cara yang logis dan masukkan ke dalam beberapa tabel paralel. Dengan pengelompokan yang tepat, Anda mungkin tidak harus BERGABUNG semua tabel sepanjang waktu.

Apakah Anda mengindeks salah satu nilai? Apakah Anda perlu mencarinya? Mungkin Anda mencari di datetime?

Jika Anda perlu mengindeks banyak kolom - punt.

Jika Anda perlu mengindeks beberapa - letakkan di tabel utama.

Inilah solusi nyata (jika itu berlaku) ...

Jika Anda tidak membutuhkan banyak sensor yang diindeks, maka jangan membuat kolom! Ya, kamu mendengarku. Alih-alih, kumpulkan mereka ke dalam JSON, kompres JSON, simpan di bidang BLOB. Anda akan menghemat banyak ruang; Anda hanya akan memiliki satu tabel, tanpa masalah batas kolom; dll. Aplikasi Anda akan terkompresi, dan kemudian menggunakan JSON sebagai struktur. Tebak apa? Anda dapat memiliki struktur - Anda dapat mengelompokkan sensor menjadi array, hal-hal bertingkat, dll, seperti yang diinginkan aplikasi Anda. 'Fitur' lain - itu terbuka. Jika Anda menambahkan lebih banyak sensor, Anda tidak perlu mengubah tabel. JSON jika fleksibel seperti itu.

(Kompresi adalah opsional; jika dataset Anda besar, itu akan membantu dengan ruang disk, maka kinerja keseluruhan.)

7
Rick James

Saya melihat ini sebagai skenario yang mungkin terjadi di dunia data besar, di mana Anda mungkin tidak melakukan tipe query * pilih tradisional. Kami berurusan dengan ini dalam dunia pemodelan prediktif pada tingkat pelanggan di mana kami memodelkan pelanggan di ribuan dimensi (semuanya memiliki nilai 0 atau 1). Cara penyimpanan ini membuat kegiatan pembangunan model hilir dll lebih mudah ketika Anda memiliki faktor risiko di baris yang sama dan bendera hasil di baris yang sama juga .. Ini dapat dinormalisasi dari titik berdiri penyimpanan dengan struktur anak induk, tetapi model prediksi hilir perlu mengubahnya kembali menjadi skema datar. Kami menggunakan redshift yang melakukan penyimpanan kolom, jadi 1000+ kolom Anda saat Anda memuat data, sebenarnya disimpan dalam format kolom ...

Ada waktu dan tempat untuk desain ini. Benar. Normalisasi bukanlah solusi untuk setiap masalah.

4
BigDataGuy