Apa cara terbaik untuk menyisipkan dataset besar ke dalam basis data MySQL (atau basis data apa pun secara umum)

9

Sebagai bagian dari proyek PHP, saya harus memasukkan baris ke dalam database MySQL. Saya jelas terbiasa melakukan ini, tetapi ini diperlukan memasukkan ke dalam 90 kolom dalam satu permintaan. Kueri yang dihasilkan terlihat mengerikan dan monolitik (terutama menyisipkan variabel PHP saya sebagai nilainya):

INSERT INTO mytable (column1, colum2, ..., column90) 
VALUES
('value1', 'value2', ..., 'value90')

dan saya khawatir saya tidak melakukan hal ini dengan cara yang benar. Saya juga butuh waktu yang lama (membosankan) untuk mengetik semuanya dan menguji penulisan kode tes akan sama membosankannya, saya khawatir.

Bagaimana cara profesional menulis dan menguji pertanyaan ini dengan cepat? Apakah ada cara saya bisa mempercepat proses?

Joe
sumber
2
Saya lebih khawatir bahwa tabel tersebut memiliki 90 kolom dari jumlah waktu sepele yang digunakan untuk mengetik nama kolom. (BTW saya seret dan jatuhkan semua kolom sekaligus dalam SQL Server, apakah tidak ada tempat untuk melakukan hal yang sama di mySQL atau PHP? Saya akan melihat apakah Anda dapat menemukan bahwa ini membuat hidup lebih mudah karena tidak ada kesalahan ketik.)
HLGEM
1
Saya tahu 90 kolom banyak, tetapi setiap kolom berhubungan dengan satu bidang untuk dokumen pdf yang perlu saya isi dan saya tidak melihat gunanya memecahnya, atau bagaimana saya akan melakukannya. Terima kasih atas info tentang SQL Server. Saya tidak yakin apa yang Anda maksud dengan menyeret dan menjatuhkan kolom, tetapi saya akan memeriksanya.
Joe
1
Tulis pernyataan pilih yang mencantumkan semua kolom dalam tabel yang diberikan dan pergi dari sana.
JeffO
Jeff O: Saya sudah menggunakannya juga, itu bisa menjadi teknik yang sangat kuat jika dilakukan dengan benar. Anda harus memposting itu sebagai jawaban jika Anda dapat memberikan contoh kode!
FrustratedWithFormsDesigner

Jawaban:

7

Joe, komentar terakhirmu banyak menjelaskan. Saya pikir masalah sebenarnya adalah desain data. Kolom baru mungkin diperlukan ketika format dokumen berubah, dan dalam pengalaman saya format dokumen cenderung berubah sering. Alih-alih tabel 90 kolom, dengan satu baris per laporan, saya akan menyimpan data laporan dalam tabel dengan empat kolom: report_id, format_id, field_name, field_value. Setiap laporan akan diwakili oleh 90 baris, satu untuk setiap nilai bidang dalam laporan. Ini harus menyederhanakan kode Anda.

kevin cline
sumber
Terima kasih untuk balasan Anda. Semua bidang (terlepas dari indeks) adalah VARCHARS, sehingga itu akan bekerja untuk saya (dan saya bisa mengonversi nilai-nilai lain pula). Saya mungkin menghabiskan banyak ruang karena saya harus memiliki ukuran kolom field_value diatur ke nilai terbesar (sekitar 256 karakter) sedangkan beberapa bidang hanya membutuhkan panjang 3. Itu pasti akan lebih mudah untuk digunakan dan saya bisa mengerti bagaimana ini akan menjadi lebih banyak bukti di masa depan seperti yang Anda gambarkan.
Joe
4
FWIW, kebanyakan sistem basis data hanya menggunakan ruang sebanyak yang diperlukan untuk menyimpan data. Jadi jika Anda menyimpan hanya 3 karakter dalam bidang VARCHAR (256), itu hanya akan membutuhkan 3 byte, bukan 256. Saya tidak tahu banyak tentang internal MySQL, tapi saya akan terkejut jika mereka mengisi bidang mereka hingga penuh ukuran yang dinyatakan.
TMN
@ TMN Itulah yang dimaksud dengan VAR di VARCHAR! Panjang Variabel Char. Ini adalah fungsi (atau definisi) dari tipe data bukan sistem DB. Juga bukan itu karena VARCHAR adalah Panjang Variabel, DB perlu mengetahui panjang untuk setiap nilai, sehingga ia menyimpan panjang sebagai metadata. Itu berarti penyimpanan overhead! Jadi VARCHAR (1) benar-benar menggunakan 3 byte data karena overhead, 3x sebanyak Char (1)!
Morons
2
-1, saya tidak setuju dengan jawaban ini, Dalam hal ini Anda lebih baik dengan 90 kolom. Jika entitas memiliki 90 titik data, maka jadilah itu, jaga agar data Anda tetap rasional.
Moron
@TMN hanya untuk memperjelas poin saya, mengatakan "Jadi, jika Anda menyimpan hanya 3 karakter dalam bidang VARCHAR (256), itu hanya akan memakan waktu 3 byte" Sebenarnya, ini akan memakan waktu 5 byte bukan 3.
Morons
7

Secara umum, cara tercepat untuk memuat dataset besar ke dalam database SQL adalah dengan menggunakan antarmuka pemuatan massal asli. Sejauh yang saya tahu, setiap SQL dbms memiliki setidaknya satu.

Dokumen MySQL: Menggunakan Bulk Loader

Jika saya harus mengubah file tab- atau dibatasi koma menjadi pernyataan SQL INSERT, saya menggunakan awk untuk membaca file input dan menulis file output. Tidak ada yang spesial tentang awk; kebetulan itu adalah bahasa pemrosesan teks yang saya tahu paling baik. Anda bisa mendapatkan hasil yang sama dengan menulis kode dalam Perl, Python, Ruby, Rexx, Lisp, dan sebagainya.

Mike Sherrill 'Cat Recall'
sumber
2
Pemuatan massal memang cara yang harus dilakukan jika Anda harus memasukkan banyak baris, tetapi dalam hal ini ia hanya memasukkan satu baris dengan banyak kolom. Pemuatan massal tidak akan membantu, dan mungkin akan membutuhkan penulisan lebih banyak kode daripada pendekatan langsung.
TMN
-1, jawaban ini benar-benar tidak ada gunanya pertanyaan
Doc Brown
2

Jika Anda dapat dengan mudah memasukkan nama kolom ke dalam spreadsheet Excel, Anda bisa menulis makro Excel untuk menghasilkan kode untuk berbagai pertanyaan dan pernyataan DML, lalu cukup tempelkan nilai ke dalam kolom lain dan pernyataan insert / update Anda dibuat secara otomatis untuk Anda. Mengetik secara manual adalah cara yang sangat lambat untuk melakukannya, jadi lihat apakah Anda dapat menemukan trik menggunakan alat yang ada. Banyak editor teks yang berorientasi pengembang juga memiliki kemampuan untuk merekam dan menyimpan makro untuk membuat pekerjaan berulang seperti ini jauh lebih cepat dan lebih mudah.

FrustratedWithFormsDesigner
sumber
2

Jika Anda memiliki file csv, Anda dapat menggunakan LOAD DATA INFILE ... untuk mengimpor data.

Jika Anda harus menggunakan kueri 'INSERT', melakukan insert massal akan mempercepat prosesnya. Alih-alih menjalankan kueri 'INSERT' untuk setiap baris, kelompokkan baris, ucapkan 100 dan jalankan kueri. Sesuatu seperti ini:

INSERT INTO theTable (col1, col2, col3,....., col89, col90) 
VALUES
(val11, val12, val13, ........, val189, val190),
(val21, val22, val23, ........, val289, val290),
.......
......
(val101, val102, val103, ........, va1089, val1090);
Srisa
sumber
2

Cara efisien untuk menulis data kueri multi-kolom ke dalam MySQL DB adalah mengubah data ini ke dalam format JSON atau YAML dan menyisipkannya sebagai satu unit. Itu mengubah "tulis sebuah sisipan untuk tabel dengan 90 kolom" menjadi "tuliskan sisipan ke dalam tabel dengan satu kolom".

Dalam pendekatan ini, tidak semua yang perlu dipecah menjadi komponen dasar itu, dan datum tunggal disimpan hanya ke dalam 1 kolom.

Noviff
sumber
@gnat: ia menawarkan solusi alternatif. Itu mengubah "tulis sebuah sisipan untuk tabel dengan 90 kolom" menjadi "tuliskan sisipan ke dalam tabel dengan satu kolom". Mengingat masalah seperti yang dijelaskan, itu adalah solusi yang valid. Tidak semuanya perlu dipecah menjadi komponen dasar itu. Satu-satunya jawaban serupa lainnya, menyarankan untuk menggunakan NoSQL penuh, menghilangkan database SQL sepenuhnya, yang berlebihan. Jawaban ini mengatakan bahwa Anda dapat menggunakan pendekatan campuran. Buat hanya 1 kolom untuk datum tunggal ini. Pertimbangkan bahwa alternatifnya mungkin memiliki kolom biner dan menyimpan seluruh pdf.
jmoreno
@gnat: Saya akan memberi Noviff kesempatan untuk mengatakannya sendiri ...
jmoreno
@ nyamuk dan jmoreno - terima kasih atas komentar Anda. Saya suka klarifikasi nyamuk atas jawaban saya, dan saya mengedit jawaban berdasarkan klarifikasi nya.
Noviff
0

Dengan MySQL Anda dapat menggunakan sintaks alternatif untuk insertpernyataan:

insert into table
        set column1 = value1
          , column2 = value2
          , column3 = value3
Kaspars Foigts
sumber
1
Apakah ini sebenarnya lebih cepat?
Pacerier
@Pacerier Tidak, ini tidak lebih cepat. Hanya sintaks yang lain.
Kaspars Foigts
0

Skenario Anda terlihat sangat cocok untuk solusi NoSQL, karena daftar atribut dapat berubah kapan saja formatnya berubah. Sudahkah Anda mengevaluasi opsi selain MySQL? Gali di sekitar DynamoDB / MongoDB / Cassandra - yang mungkin lebih cocok.

Subu Sankara Subramanian
sumber
-1

Ada cara yang lebih efisien untuk memasukkan data ke dalam basis data menggunakan php dan mysql. Kita dapat menggunakan LOAD COMMAND untuk memasukkan data. Ini menyisipkan data yang sangat cepat.

Untuk ini buat file flat (misalnya saya menggunakan file .csv) dengan data Anda menggunakan fputcsv()fungsi. Kemudian masukkan data menggunakan perintah LOAD. Sintaks beberapa yang mirip seperti di bawah ini:

LOAD DATA LOCAL INFILE "C:/downloads/local/my_data_file.csv"
INTO TABLE  my_data
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES;
Subodh
sumber
-1

Coba yang berikut ini. Bekerja untukku.

Nama formulir harus sama dengan nama kolom basis data

Dapatkan nilainya seperti di bawah ini:

foreach ($_GET as $formName => $value) {
    $sql = mysql_query("UPDATE table_name SET $formName = '$value' WHERE ID= $id");
}

Pertama-tama Anda harus memasukkan ID sebelum loop foreach. Anda bisa mendapatkan id berikutnya dengan melakukan:

SELECT MAX(id) FROM .....

tambahkan 1 ke id dan masukkan.

malaikat
sumber