Jaki jest najlepszy sposób na WSTAWIENIE dużego zestawu danych do bazy danych MySQL (lub dowolnej innej bazy danych ogólnie)

9

W ramach projektu PHP muszę wstawić wiersz do bazy danych MySQL. Oczywiście jestem do tego przyzwyczajony, ale wymagało to wstawienia do 90 kolumn w jednym zapytaniu. Wynikowe zapytanie wygląda okropnie i monolitycznie (zwłaszcza wstawianie moich zmiennych PHP jako wartości):

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

i martwię się, że nie zamierzam tego robić we właściwy sposób. Dużo czasu zajęło mi też (nudne) wpisanie wszystkiego i obawiam się, że pisanie kodu testowego będzie równie nudne.

Jak profesjonaliści radzą sobie z szybkim pisaniem i testowaniem tych zapytań? Czy istnieje sposób na przyspieszenie tego procesu?

Joe
źródło
2
Bardziej martwi mnie to, że tabela ma 90 kolumn niż trywialny czas spędzony na wpisywaniu nazw kolumn. (BTW przeciągam i upuszczam wszystkie kolumny naraz w SQL Server, czy nie ma miejsca, aby zrobić to samo w mySQL lub PHP? Chciałbym sprawdzić, czy można znaleźć, że ułatwia to życie, ponieważ nie ma literówek.)
HLGEM
1
Wiem, że 90 kolumn to dużo, ale każda kolumna odnosi się do pojedynczego pola dla dokumentu pdf, który muszę wypełnić i nie widzę sensu w podziale, ani w jaki sposób to zrobiłbym. Dzięki za informacje o SQL Server. Nie jestem do końca pewien, co masz na myśli mówiąc o przeciąganiu i upuszczaniu kolumn, ale przyjrzę się.
Joe
1
Napisz instrukcję select, która zawiera listę wszystkich kolumn w danej tabeli i stamtąd.
JeffO,
Jeff O: Też tego użyłem, może być bardzo potężną techniką, jeśli zrobisz to dobrze. Powinieneś opublikować to jako odpowiedź, jeśli możesz podać przykładowy kod!
FrustratedWithFormsDesigner

Odpowiedzi:

7

Joe, twój ostatni komentarz wiele wyjaśniał. Myślę, że prawdziwym problemem jest projektowanie danych. Nowe kolumny mogą być potrzebne, gdy zmienia się format dokumentu, a według mojego doświadczenia formaty dokumentów często się zmieniają. Zamiast 90-kolumnowej tabeli, z pojedynczym wierszem na raport, zapisałbym dane raportu w tabeli z czterema kolumnami: id_dokumentu, id_formatu, nazwa_pola, wartość_pola. Każdy raport będzie reprezentowany przez 90 wierszy, po jednym dla każdej wartości pola w raporcie. Powinno to znacznie uprościć kod.

Kevin Cline
źródło
Dzięki za odpowiedź. Wszystkie pola (poza indeksem) są zmiennymi VARCHARS, więc to by działało dla mnie (i i tak mogłem przekonwertować inne wartości). Być może tracę dużo miejsca, ponieważ musiałbym ustawić wielkość kolumny wartość_pola na największą wartość (około 256 znaków), podczas gdy niektóre pola wymagają jedynie długości 3. Z pewnością łatwiej byłoby użyć i rozumiem, jak to by było bardziej przyszłościowe, jak opisałeś.
Joe
4
FWIW, większość systemów baz danych wykorzystuje tylko tyle miejsca, ile jest potrzebne do przechowywania danych. Więc jeśli przechowujesz tylko 3 znaki w polu VARCHAR (256), zajmie to tylko 3 bajty, a nie 256. Nie wiem wiele o wewnętrznych elementach MySQL, ale byłbym zaskoczony, gdyby wypełnili swoje pola do końca deklarowany rozmiar.
TMN
@TMN To właśnie oznacza VAR w VARCHAR! Zmienna długość Char. Jest to funkcja (lub definicja) typu danych, a nie systemu DB. Również nie dlatego, że VARCHAR ma zmienną długość, DB musi znać długość każdej wartości, więc przechowuje długość jako metadane. Oznacza to przechowywanie nad głową! Zatem VARCHAR (1) faktycznie wykorzystuje 3 bajty danych z powodu narzutu, 3 razy więcej niż Char (1)!
Morons
2
-1, nie zgadzam się z tą odpowiedzią, w tym przypadku lepiej jest z 90 kolumnami. Jeśli jednostka ma 90 punktów danych, niech tak będzie, zachowaj racjonalność danych.
Morons
@TMN, aby wyjaśnić moją kwestię, powiedział: „Więc jeśli przechowujesz tylko 3 znaki w polu VARCHAR (256), zajmie to tylko 3 bajty” Prawda jest taka, że ​​zajmie to 5 bajtów, a nie 3.
Morons
7

Zasadniczo najszybszym sposobem na załadowanie dużego zestawu danych do bazy danych SQL jest użycie natywnego interfejsu ładowania zbiorczego. O ile mi wiadomo, każdy SQL dbms ma co najmniej jeden.

Dokumenty MySQL: Korzystanie z modułu ładującego luzem

Jeśli ja miał zamienić Tab- lub plik rozdzielany przecinkami do instrukcji SQL INSERT, używam awk odczytać pliku wejściowego i zapisać plik wyjściowy. W awk nie ma nic specjalnego; tak się składa, że ​​jest to język przetwarzania tekstu, który znam najlepiej. Możesz uzyskać te same wyniki, pisząc kod w Perl, Python, Ruby, Rexx, Lisp i tak dalej.

Mike Sherrill „Cat Recall”
źródło
2
Ładowanie zbiorcze jest rzeczywiście dobrym rozwiązaniem, jeśli chcesz wstawić dużą liczbę wierszy, ale w tym przypadku po prostu wstawia pojedynczy wiersz z dużą ilością kolumn. Ładowanie zbiorcze nie pomoże i prawdopodobnie będzie wymagało napisania większej ilości kodu niż proste podejście.
TMN
-1, ta odpowiedź jest całkowicie pozbawiona sedna pytania
Doc Brown
2

Jeśli możesz łatwo umieścić nazwy kolumn w arkuszu kalkulacyjnym Excel, możesz napisać makra Excela, aby wygenerować kod dla różnych zapytań i instrukcji DML, a następnie po prostu wkleić wartości do innej kolumny, a instrukcja wstawiania / aktualizacji zostanie utworzona automatycznie. Ręczne pisanie jest bardzo powolnym sposobem, aby to zrobić, więc sprawdź, czy możesz znaleźć sztuczki przy użyciu istniejących narzędzi. Wiele edytorów tekstu zorientowanych na programistów ma również możliwość rejestrowania i przechowywania makr, dzięki czemu powtarzalne zadania są znacznie szybsze i łatwiejsze.

FrustratedWithFormsDesigner
źródło
2

Jeśli masz plik csv, możesz użyć LOAD DATA INFILE ... do importowania danych.

Jeśli musisz użyć zapytań „INSERT”, wówczas wykonywanie masowych wstawek przyspieszy proces. Zamiast uruchamiać zapytanie „INSERT” dla każdego wiersza, zgrupuj wiersze, powiedzmy 100 i uruchom zapytanie. Coś takiego:

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
źródło
2

Skutecznym sposobem zapisania danych zapytania w wielu kolumnach w MySQL DB jest konwersja tych danych do formatu JSON lub YAML i wstawienie ich jako pojedynczej jednostki. Zmienia „napisz wstawkę do tabeli z 90 kolumnami” na „napisz wstawkę do tabeli z jedną kolumną”.

W tym podejściu nie wszystko musi zostać podzielone na podstawowe komponenty, a pojedynczy układ odniesienia jest przechowywany tylko w 1 kolumnie.

Noviff
źródło
@gnat: oferuje alternatywne rozwiązanie. Zmienia „napisz wstawkę do tabeli z 90 kolumnami” na „napisz wstawkę do tabeli z jedną kolumną”. Biorąc pod uwagę opisany problem, jest to prawidłowe rozwiązanie. Nie wszystko trzeba rozbić na podstawowe komponenty. Jedyna inna podobna odpowiedź sugerowała przejście na pełną wersję języka NoSQL, całkowicie eliminując bazę danych SQL, co jest przesadą. Ta odpowiedź mówi, że możesz zastosować podejście mieszane. Utwórz tylko 1 kolumnę dla tego pojedynczego układu odniesienia. Zastanów się, że alternatywą może być kolumna binarna i przechowywanie całego pliku pdf.
jmoreno
@gnat: Dam Noviffowi szansę, by wyraził to własnymi słowami ...
jmoreno
@ gnat i jmoreno - dziękuję za komentarze. Lubię wyjaśnienie komara mojej odpowiedzi i zredagowałem odpowiedź w oparciu o jego wyjaśnienie.
Noviff,
0

Dzięki MySQL możesz użyć alternatywnej składni insertinstrukcji:

insert into table
        set column1 = value1
          , column2 = value2
          , column3 = value3
Kaspars Foigts
źródło
1
Czy to jest rzeczywiście szybsze?
Pacerier
@Pacerier Nie, to nie jest szybsze. Po prostu kolejna składnia.
Kaspars Foigts
0

Twój scenariusz wygląda bardzo dobrze pasujący do rozwiązania NoSQL, ponieważ lista atrybutów może się zmieniać za każdym razem, gdy zmienia się format. Czy oceniłeś inne opcje niż MySQL? Kop wokół DynamoDB / MongoDB / Cassandra - to może być lepsze dopasowanie.

Subu Sankara Subramanian
źródło
-1

Istnieje bardziej wydajny sposób wstawiania danych do bazy danych przy użyciu php i mysql. Możemy użyć LOAD COMMAND do wstawienia danych. Wstawia dane niezwykle szybko.

W tym celu utwórz plik płaski (na przykład użyłem pliku .csv) z danymi za pomocą fputcsv()funkcji. Następnie wstaw dane za pomocą polecenia LOAD. Składnia niektóre podobne jak poniżej:

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
źródło
-1

Spróbuj wykonać następujące czynności. Pracował dla mnie.

Nazwy formularzy muszą być równe nazwom kolumn bazy danych

Uzyskaj wartości, jak poniżej:

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

Najpierw musisz wstawić identyfikator przed pętlą foreach. możesz uzyskać następny identyfikator, wykonując:

SELECT MAX(id) FROM .....

dodaj 1 do id i wstaw go.

Anioł
źródło