Qual é a melhor maneira de INSERIR um grande conjunto de dados em um banco de dados MySQL (ou qualquer banco de dados em geral)

9

Como parte de um projeto PHP, tenho que inserir uma linha no banco de dados MySQL. Obviamente, estou acostumado a fazer isso, mas isso exigia a inserção em 90 colunas em uma consulta. A consulta resultante parece horrível e monolítica (especialmente inserindo minhas variáveis ​​PHP como os valores):

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

e estou preocupado que não vou fazer isso da maneira certa. Também me levou um longo tempo (chato) apenas para digitar tudo e testar a escrita do código de teste será igualmente entediante.

Como os profissionais escrevem e testam essas consultas rapidamente? Existe uma maneira de acelerar o processo?

Joe
fonte
2
Estou mais preocupado que a tabela tenha 90 colunas do que a quantidade trivial de tempo gasto digitando os nomes das colunas. (BTW, arrasto e solto todas as colunas de uma só vez no SQL Server, não há como fazer o mesmo no mySQL ou PHP? Gostaria de ver se você pode achar que isso facilita a vida, pois não há erros de digitação.)
HLGEM
11
Eu sei que 90 colunas são muitas, mas cada coluna se refere a um único campo para um documento PDF que eu preciso preencher e não vejo sentido em dividi-lo, ou como eu faria isso. Obrigado pelas informações sobre o SQL Server. Não sei bem o que você quer dizer com arrastar e soltar as colunas, mas vou dar uma olhada.
Joe
11
Escreva uma instrução select que lista todas as colunas em uma determinada tabela e vá a partir daí.
JeffO
Jeff O: Eu também usei isso, pode ser uma técnica muito poderosa se bem feita. Você deve postar isso como resposta, se puder dar um exemplo de código!
FrustratedWithFormsDesigner

Respostas:

7

Joe, seu último comentário explicou muito. Eu acho que o verdadeiro problema é o design de dados. Novas colunas podem ser necessárias quando o formato do documento é alterado e, na minha experiência, os formatos de documento tendem a mudar com frequência. Em vez de uma tabela de 90 colunas, com uma única linha por relatório, eu armazenaria os dados do relatório em uma tabela com quatro colunas: report_id, format_id, field_name, field_value. Cada relatório seria representado por 90 linhas, uma para cada valor de campo no relatório. Isso deve simplificar consideravelmente seu código.

Kevin Cline
fonte
Obrigado pela sua resposta. Todos os campos (exceto o índice) são VARCHARS, portanto, isso funcionaria para mim (e eu poderia converter outros valores de qualquer maneira). Talvez eu esteja perdendo muito espaço, porque teria que ter o tamanho da coluna field_value definido como o maior valor (cerca de 256 caracteres), enquanto alguns campos exigem apenas um comprimento de 3. Seria certamente mais fácil usar e eu posso entender como seria mais uma prova do futuro, como você descreveu.
Joe
4
FWIW, a maioria dos sistemas de banco de dados usa apenas o espaço necessário para armazenar dados. Portanto, se você armazenar apenas 3 caracteres em um campo VARCHAR (256), serão necessários apenas 3 bytes, e não 256. Não sei muito sobre os MySQL internos, mas ficaria surpreso se eles preenchessem seus campos ao máximo. tamanho declarado.
TMN
@TMN É isso que significa o VAR no VARCHAR! Caractere de comprimento variável. Esta é uma função (ou a definição) do tipo de dados e não do sistema DB. Também não é porque um VARCHAR é Comprimento variável, o banco de dados precisa saber o comprimento de cada valor, para que ele armazene o comprimento como metadados. Isso significa armazenamento aéreo! Portanto, um VARCHAR (1) realmente usa 3 bytes de dados por causa da sobrecarga, 3x mais que um Char (1)!
Idiotas
2
-1, não concordo com esta resposta. Nesse caso, é melhor você ter 90 colunas. Se a entidade tiver 90 pontos de dados, mantenha-os racionais.
Idiotas
@TMN só para esclarecer o meu ponto, disse: "Então, se você armazenar apenas 3 caracteres em um campo VARCHAR (256), levará apenas 3 bytes" A verdade é que vai demorar até 5 não bytes 3.
Morons
7

Em geral, a maneira mais rápida de carregar um grande conjunto de dados em um banco de dados SQL é usar a interface de carregamento em massa nativa. Até onde eu sei, todos os dbms SQL têm pelo menos um.

Documentos do MySQL: Usando o carregador em massa

Se eu tiver que transformar um arquivo delimitado por tabulação ou vírgula em instruções SQL INSERT, utilizarei o awk para ler o arquivo de entrada e gravar o arquivo de saída. Não há nada realmente especial no awk; por acaso é a linguagem de processamento de texto que eu conheço melhor. Você pode obter os mesmos resultados escrevendo código em Perl, Python, Ruby, Rexx, Lisp e assim por diante.

Mike Sherrill 'Recolha de Gatos'
fonte
2
O carregamento em massa é realmente o caminho a percorrer, se você precisar inserir um grande número de linhas, mas, neste caso, ele está apenas inserindo uma única linha com muitas colunas. O carregamento em massa não ajudará e provavelmente exigirá a criação de mais código do que a abordagem direta.
TMN
-1, esta resposta está completamente ausente do ponto em questão
Doc Brown
2

Se você pode facilmente inserir os nomes das colunas em uma planilha do Excel, você pode escrever macros do Excel para produzir código para várias consultas e instruções DML, basta colar valores em outra coluna e sua instrução de inserção / atualização é criada automaticamente para você. Digitar manualmente é uma maneira muito lenta de fazê-lo; portanto, veja se consegue encontrar truques usando as ferramentas existentes. Muitos editores de texto orientados ao desenvolvedor também têm a capacidade de gravar e armazenar macros para fazer trabalhos repetitivos como esse muito mais rápido e fácil.

FrustratedWithFormsDesigner
fonte
2

Se você possui um arquivo csv, pode usar o LOAD DATA INFILE ... para importar os dados.

Se você precisar usar consultas 'INSERT', fazer inserções em massa acelerará o processo. Em vez de executar uma consulta 'INSERT' para cada linha, agrupe as linhas, diga 100 e execute a consulta. Algo assim:

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
fonte
2

Uma maneira eficiente de gravar dados de consulta com várias colunas no MySQL DB é convertê-los no formato JSON ou YAML e inseri-los como uma única unidade. Ele muda "escreve uma inserção em uma tabela com 90 colunas" em "escreve uma inserção em uma tabela com uma coluna".

Nessa abordagem, nem tudo precisa ser dividido em seus componentes básicos, e o dado único é armazenado em apenas uma coluna.

Noviff
fonte
@gnat: oferece uma solução alternativa. Ele muda "escreve uma inserção em uma tabela com 90 colunas" em "escreve uma inserção em uma tabela com uma coluna". Dado o problema descrito, é uma solução válida. Nem tudo precisa ser dividido em seus componentes básicos. A única outra resposta semelhante, sugeriu o preenchimento completo do NoSQL, eliminando completamente o banco de dados SQL, que é um exagero. Esta resposta diz que você pode usar uma abordagem mista. Faça apenas 1 coluna para esse dado único. Considere que a alternativa pode ser ter uma coluna binária e armazenar o pdf inteiro.
jmoreno
@gnat: Eu darei ao Noviff a chance de colocá-lo em suas próprias palavras ...
jmoreno
@ gnat e jmoreno - obrigado por seus comentários. Gosto do esclarecimento de gnat sobre minha resposta e editei a resposta com base em seus esclarecimentos.
Noviff 22/01
0

Com o MySQL você pode usar sintaxe alternativa para insertinstruções:

insert into table
        set column1 = value1
          , column2 = value2
          , column3 = value3
Kaspars Foigts
fonte
11
Isso é realmente mais rápido?
Pacerier
@ Pacerier Não, isso não é mais rápido. Apenas outra sintaxe.
Kaspars Foigts
0

Seu cenário parece ser muito bom para uma solução NoSQL, pois a lista de atributos pode mudar a qualquer momento que o formato for alterado. Você já avaliou outras opções além do MySQL? Pesquise o DynamoDB / MongoDB / Cassandra - isso pode ser melhor.

Subu Sankara Subramanian
fonte
-1

Existe uma maneira mais eficiente de inserir dados no banco de dados usando php e mysql. Podemos usar LOAD COMMAND para inserir os dados. Ele insere dados notavelmente rápidos.

Para isso, crie um arquivo simples (por exemplo, usei o arquivo .csv) com seus dados usando a fputcsv()função Em seguida, insira os dados usando o comando LOAD. Sintaxe alguns que semelhante como abaixo:

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
fonte
-1

Tente o seguinte. Trabalhou para mim.

Os nomes dos formulários devem ser iguais aos nomes das colunas do banco de dados

Obtenha os valores abaixo:

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

Você primeiro precisará inserir um ID antes do loop foreach. você pode obter o próximo ID fazendo:

SELECT MAX(id) FROM .....

adicione 1 ao id e insira-o.

Anjo
fonte