Büyük bir veri kümesini MySQL veritabanına (veya genel olarak herhangi bir veritabanına) eklemenin en iyi yolu nedir?


9

Bir PHP projesinin bir parçası olarak, bir MySQL veritabanına bir satır eklemek zorunda. Açıkçası bunu yapmaya alışkınım, ancak bu bir sorguda 90 sütuna eklenmesini gerektiriyordu. Ortaya çıkan sorgu korkunç ve yekpare görünüyor (özellikle PHP değişkenlerimi değerler olarak ekleyerek):

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

ve bunu doğru şekilde yapmayacağımdan endişeliyim. Ayrıca her şeyi yazmak ve test kodunu yazmak da korkutucu derecede sıkıcı olacak kadar uzun (sıkıcı) bir zaman aldı.

Profesyoneller bu sorguları hızlı bir şekilde yazmaya ve test etmeye nasıl gidiyor? Süreci hızlandırabilmemin bir yolu var mı?


2
Tablo sütun adları yazarak harcanan önemsiz miktardan 90 sütun var daha endişe duyuyorum. (? BTW sürükle ve SQL Server bir kerede tüm sütunları damla, sana hiçbir yazım hatası olmadığından gibi hayatı kolaylaştırır olduğunu bulabilirsiniz görmek için bakmak istiyorum orada mySQL veya PHP içinde aynı şeyi aplace değildir.)
HLGEM

1
Ben 90 sütun çok şey biliyorum, ama her sütun doldurmak için gereken bir pdf belgesi için tek bir alan ile ilgilidir ve onu parçalama noktasını ya da nasıl yapacağımı görmüyorum. SQL Server hakkında bilgi için teşekkürler. Sütunları sürükleyip bırakarak ne demek istediğinden tam olarak emin değilim.
Joe

1
Belirli bir tablodaki tüm sütunları listeleyen bir select deyimi yazın ve oradan gidin.
JeffO

Jeff O: Bunu da kullandım, doğru yapılırsa çok güçlü bir teknik olabilir. Bir kod örneği verebilirseniz, bunu bir cevap olarak göndermelisiniz!
SinirliWithFormsDesigner

Yanıtlar:


7

Joe, son yorumun çok açıkladı. Bence asıl sorun veri tasarımı. Belge biçimi değiştiğinde yeni sütunlara ihtiyaç duyulabilir ve deneyimimde belge biçimleri sık sık değişme eğilimindedir. Rapor başına tek bir satır içeren 90 sütunlu bir tablo yerine, rapor verilerini dört sütunlu bir tabloda depolardım: rapor_kimliği, biçim_kimliği, alan_adı, alan_değeri. Her rapor, rapordaki her alan değeri için bir tane olmak üzere 90 satırla temsil edilir. Bu, kodunuzu önemli ölçüde basitleştirmelidir.


Cevabın için teşekkürler. Tüm alanlar (dizin dışında) VARCHARS, bu yüzden benim için işe yarayacak (ve yine de diğer değerleri dönüştürebilirsiniz). Ben alan çok değer israf olabilir çünkü field_value sütun boyutu en büyük değere (yaklaşık 256 karakter uzunluğunda) ayarlanmış olması gerekirken, bazı alanlar sadece 3 uzunluğunda bir süre gerektirir. ve sizin de tarif ettiğiniz gibi geleceğe daha fazla kanıt olacağını anlayabiliyorum.
Joe

4
FWIW, çoğu veritabanı sistemi sadece veri depolamak için gereken alanı kullanır. Yani bir VARCHAR (256) alanında sadece 3 karakter depolarsanız, 256 değil 3 bayt alır. MySQL dahili hakkında çok şey bilmiyorum, ancak alanlarını sonuna kadar doldururlarsa şaşırırdım beyan edilen boyut.
TMN

@TMN VARCHAR'daki VAR bunun anlamıdır! Değişken Uzunluk Karakter. Bu, DB sisteminin değil Veri türünün bir işlevidir (veya tanımı). Ayrıca, bir VARCHAR Değişken Uzunluk olduğu için, DB'nin her değer için uzunluğu bilmesi gerektiğinden, uzunluğu meta veri olarak depolar. Bu, havai depolama anlamına gelir! Yani bir VARCHAR (1) genel olarak 3 bayt veri kullanır, Char (1) kadar 3 kat daha fazla!
Morons

2
-1, bu yanıta katılmıyorum, bu durumda 90 sütunla daha iyi durumdasınız. Varlığın 90 veri noktası varsa, öyle olsun, verilerinizi rasyonel tutun.
Moronlar

@TMN sadece benim açımdan netleştirmek için, "Yani bir VARCHAR (256) alanında sadece 3 karakter saklarsan, sadece 3 bayt alacak" Gerçek şu ki 3 değil 5 bayt alacak.
Morons

7

Genel olarak, büyük bir veri kümesini SQL veritabanına yüklemenin en hızlı yolu yerel toplu yükleme arabirimini kullanmaktır. Bildiğim kadarıyla, her SQL dbms en az bir tane var.

MySQL belgeleri: Toplu Yükleyiciyi Kullanma

Ben ise var SQL INSERT deyimleri içine sekme veya virgülle ayrılmış dosyayı açmak için, ben giriş dosyasını okumak ve çıkış dosyası yazmak için awk kullanın. Awk hakkında gerçekten özel bir şey yok; en iyi bildiğim metin işleme dili. Aynı sonuçları Perl, Python, Ruby, Rexx, Lisp ve benzerlerine kod yazarak da alabilirsiniz.


2
Çok sayıda satır eklemeniz gerekiyorsa toplu yükleme gerçekten de yoludur, ancak bu durumda çok sayıda sütun içeren tek bir satır ekler. Toplu yükleme yardımcı olmaz ve muhtemelen doğrudan yaklaşımdan daha fazla kod yazmayı gerektirir.
TMN

-1, bu yanıt sorunun tamamen eksik
Doc Brown

2

Sütun adlarını kolayca bir Excel e-tablosuna alabiliyorsanız, çeşitli sorgular ve DML ifadeleri için kod üretmek üzere Excel makroları yazabilir, ardından değerleri başka bir sütuna yapıştırabilir ve ekleme / güncelleme ifadeniz sizin için otomatik olarak oluşturulur. Manuel olarak yazmak bunu yapmanın çok yavaş bir yoludur, bu nedenle mevcut araçlarınızı kullanarak hileler bulabileceğinize bakın. Birçok geliştirici odaklı metin editörleri, bu gibi tekrarlayan işleri daha hızlı ve daha kolay hale getirmek için makroları kaydetme ve saklama yeteneğine de sahiptir.


2

Bir csv dosyanız varsa , verileri içe aktarmak için LOAD DATA INFILE ... öğesini kullanabilirsiniz.

'INSERT' sorgularını kullanmanız gerekiyorsa, toplu ekleme yapmak işlemi hızlandıracaktır. Her satır için bir 'INSERT' sorgusu çalıştırmak yerine, satırları gruplandırın, 100 deyin ve sorguyu çalıştırın. Bunun gibi bir şey:

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

2

Çok sütunlu sorgu verilerini MySQL DB'ye yazmanın etkili bir yolu, bu verileri JSON veya YAML biçimine dönüştürmek ve tek bir birim olarak eklemektir. "90 sütunlu bir tablo için bir insert yaz" ı "bir sütunlu bir tabloya bir insert yaz" olarak değiştirir.

Bu yaklaşımda, her şeyin temel bileşenlerine bölünmesi gerekmez ve tek veri sadece 1 sütunda saklanır.


@gnat: alternatif bir çözüm sunar. "90 sütunlu bir tablo için bir insert yaz" ı "bir sütunlu bir tabloya bir insert yaz" olarak değiştirir. Açıklandığı gibi sorun göz önüne alındığında, geçerli bir çözümdür. Her şeyin temel bileşenlerine bölünmesi gerekmez. Diğer tek benzer cevap, NoSQL'e tam olarak ulaşılmasını ve SQL veritabanının tamamen ortadan kaldırılmasını önerdi. Bu cevap, karışık bir yaklaşım kullanabileceğinizi söylüyor. Bu tek veri için sadece 1 sütun oluşturun. Alternatifin bir ikili sütuna sahip olabileceğini ve tüm pdf'yi depolayabileceğini düşünün.
jmoreno

@gnat: Noviff'e kendi sözleriyle ifade etme şansı vereceğim ...
jmoreno

@ gnat ve jmoreno - yorumlarınız için teşekkür ederiz. Gnat'ın cevabımı açıklamasını seviyorum ve cevabını açıklamasına dayanarak düzenledim.
Noviff

0

MySQL ile insertifadeler için alternatif sözdizimi kullanabilirsiniz :

insert into table
        set column1 = value1
          , column2 = value2
          , column3 = value3

1
Bu gerçekten daha mı hızlı?
Pacerier

@Pacerier Hayır, bu daha hızlı değil. Sadece başka bir sözdizimi.
Kaspars Foigts

0

Öznitelik listesi biçim değiştiğinde değişebileceğinden, senaryonuz bir NoSQL çözümü için çok uygun görünüyor. MySQL dışında başka seçenekleri de değerlendirdiniz mi? DynamoDB / MongoDB / Cassandra'yı araştırın - bu daha uygun olabilir.


-1

Php ve mysql kullanarak veritabanına veri eklemek için daha etkili bir yolu var. Veri eklemek için LOAD COMMAND'ı kullanabiliriz. Verileri oldukça hızlı ekler.

Bunun için fputcsv()işlev kullanarak verilerinizle düz bir dosya (örneğin .csv dosyası kullandım) oluşturun . Ardından LOAD komutunu kullanarak veri ekleyin. Sözdizimi aşağıdakine benzer bazı şeyler:

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;

-1

Takip etmeyi dene. Benim için çalıştı.

Form adları veritabanı sütun adlarına eşit olmalıdır

Değerleri aşağıdaki gibi alın:

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

Önce foreach döngüsünden önce bir kimlik girmeniz gerekir. yaparak bir sonraki kimliği alabilirsiniz:

SELECT MAX(id) FROM .....

kimliğe 1 ekleyin ve ekleyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.