¿Cuál es la mejor manera de INSERTAR un gran conjunto de datos en una base de datos MySQL (o cualquier base de datos en general)?

9

Como parte de un proyecto PHP, tengo que insertar una fila en una base de datos MySQL. Obviamente estoy acostumbrado a hacer esto, pero esto requería insertarlo en 90 columnas en una consulta. La consulta resultante se ve horrible y monolítica (especialmente insertando mis variables PHP como los valores):

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

y me preocupa no hacer esto de la manera correcta. También me tomó mucho tiempo (aburrido) escribir todo y probar escribir el código de prueba será igualmente tedioso, me temo.

¿Cómo hacen los profesionales para escribir y probar rápidamente estas consultas? ¿Hay alguna manera de acelerar el proceso?

Joe
fuente
2
Me preocupa más que la tabla tenga 90 columnas que la cantidad trivial de tiempo dedicado a escribir nombres de columnas. (Por cierto, arrastro y suelto todas las columnas a la vez en SQL Server, ¿no hay lugar para hacer lo mismo en mySQL o PHP? Me gustaría ver si puede encontrar que hace la vida más fácil ya que no hay errores tipográficos)
HLGEM
1
Sé que 90 columnas son muchas, pero cada columna se relaciona con un solo campo para un documento pdf que necesito completar y no veo el punto de dividirlo, ni cómo lo haría. Gracias por la información sobre SQL Server. No estoy seguro de qué quieres decir con arrastrar y soltar las columnas, pero echaré un vistazo.
Joe
1
Escriba una instrucción select que enumere todas las columnas en una tabla dada y vaya desde allí.
JeffO
Jeff O: También lo he usado, puede ser una técnica muy poderosa si se hace bien. ¡Debe publicar eso como respuesta si puede dar un ejemplo de código!
FrustratedWithFormsDesigner

Respuestas:

7

Joe, tu último comentario explicó mucho. Creo que el verdadero problema es el diseño de datos. Es posible que se necesiten nuevas columnas cuando cambie el formato del documento y, en mi experiencia, los formatos de los documentos tienden a cambiar con frecuencia. En lugar de una tabla de 90 columnas, con una sola fila por informe, almacenaría los datos del informe en una tabla con cuatro columnas: report_id, format_id, field_name, field_value. Cada informe estaría representado por 90 filas, una para cada valor de campo en el informe. Esto debería simplificar su código considerablemente.

Kevin Cline
fuente
Gracias por su respuesta. Todos los campos (aparte del índice) son VARCHARS, por lo que eso funcionaría para mí (y podría convertir otros valores de todos modos). Sin embargo, podría estar desperdiciando mucho espacio porque tendría que tener el tamaño de la columna field_value establecido en el valor más grande (aproximadamente 256 caracteres de largo), mientras que algunos campos solo requieren una longitud de 3. Sin duda, sería más fácil de usar y puedo entender cómo sería más una prueba futura como usted describió.
Joe
44
FWIW, la mayoría de los sistemas de bases de datos solo usan tanto espacio como sea necesario para almacenar datos. Entonces, si almacena solo 3 caracteres en un campo VARCHAR (256), solo tomará 3 bytes, no 256. No sé mucho sobre los componentes internos de MySQL, pero me sorprendería si rellenaran sus campos al máximo tamaño declarado
TMN
@ TMN ¡Eso es lo que significa VAR en VARCHAR! Longitud variable Char. Esta es una función (o la definición) del tipo de datos, no del sistema de base de datos. Además, no porque a VARCHAR es Longitud variable, la base de datos necesita saber la longitud de cada valor, por lo que almacena la longitud como metadatos. ¡Eso significa almacenamiento en el techo! Entonces, un VARCHAR (1) en realidad usa 3 bytes de datos debido a la sobrecarga, ¡3 veces más que un Char (1)!
Morons
2
-1, no estoy de acuerdo con esta respuesta, en este caso es mejor con 90 columnas. Si la entidad tiene 90 puntos de datos, que así sea, mantenga sus datos racionales.
Morons
@ TMN solo para aclarar mi punto, dijo "Entonces, si almacena solo 3 caracteres en un campo VARCHAR (256), solo tomará 3 bytes" La verdad es que tomará 5 bytes no 3.
Morons
7

En general, la forma más rápida de cargar un gran conjunto de datos en una base de datos SQL es usar la interfaz nativa de carga masiva. Que yo sepa, cada dbms SQL tiene al menos uno.

Documentos de MySQL: uso del cargador masivo

Si tengo que convertir un archivo delimitado por tabulaciones o comas en instrucciones SQL INSERT, utilizo awk para leer el archivo de entrada y escribir el archivo de salida. No hay nada realmente especial en awk; Resulta que es el lenguaje de procesamiento de texto que mejor conozco. Puede obtener los mismos resultados escribiendo código en Perl, Python, Ruby, Rexx, Lisp, etc.

Mike Sherrill 'Cat Recall'
fuente
2
La carga masiva es el camino a seguir si necesita insertar una gran cantidad de filas, pero en este caso solo está insertando una sola fila con muchas columnas. La carga masiva no ayudará, y probablemente requerirá escribir más código que el enfoque directo.
TMN
-1, esta respuesta pierde completamente el punto de la pregunta
Doc Brown
2

Si puede obtener fácilmente los nombres de las columnas en una hoja de cálculo de Excel, podría escribir macros de Excel para generar código para varias consultas y declaraciones DML, luego simplemente pegue los valores en otra columna y su declaración de inserción / actualización se creará automáticamente. Escribir manualmente es una forma muy lenta de hacerlo, así que mira si puedes encontrar trucos usando tus herramientas existentes. Muchos editores de texto orientados al desarrollador también tienen la capacidad de grabar y almacenar macros para hacer que los trabajos repetitivos como este sean mucho más rápidos y fáciles.

FrustratedWithFormsDesigner
fuente
2

Si tiene un archivo csv, puede usar LOAD DATA INFILE ... para importar los datos.

Si tiene que usar consultas 'INSERTAR', hacer inserciones masivas acelerará el proceso. En lugar de ejecutar una consulta 'INSERTAR' para cada fila, agrupe las filas, diga 100 y ejecute la consulta. Algo como esto:

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

Una manera eficiente de escribir datos de consulta de varias columnas en MySQL DB es convertir estos datos en formato JSON o YAML e insertarlos como una sola unidad. Cambia "escribir una inserción para una tabla con 90 columnas" en "escribir una inserción en una tabla con una columna".

En este enfoque, no todo se debe dividir en sus componentes básicos, y el dato único se almacena solo en 1 columna.

Noviff
fuente
@gnat: ofrece una solución alternativa. Cambia "escribir una inserción para una tabla con 90 columnas" en "escribir una inserción en una tabla con una columna". Dado el problema como se describe, es una solución válida. No todo debe desglosarse en sus componentes base. La única otra respuesta similar, sugirió noSQL completo, eliminando la base de datos SQL por completo, lo cual es excesivo. Esta respuesta dice que puede usar un enfoque mixto. Haga solo 1 columna para este único dato. Considere que la alternativa podría ser tener una columna binaria y almacenar todo el pdf.
jmoreno
@gnat: le daré a Noviff la oportunidad de expresarlo con sus propias palabras ...
jmoreno
@ gnat and jmoreno - gracias por tus comentarios. Me gusta la aclaración de mi respuesta por parte del mosquito, y edité la respuesta según su aclaración.
Noviff
0

Con MySQL puede usar una sintaxis alternativa para las insertdeclaraciones:

insert into table
        set column1 = value1
          , column2 = value2
          , column3 = value3
Kaspars Foigts
fuente
1
¿Es esto realmente más rápido?
Pacerier
@Pacerier No, esto no es más rápido. Solo otra sintaxis.
Kaspars Foigts
0

Su escenario se ve muy bien para una solución NoSQL, ya que la lista de atributos puede cambiar en cualquier momento que cambie el formato. ¿Ha evaluado otras opciones además de MySQL? Cava alrededor de DynamoDB / MongoDB / Cassandra, eso podría ser una mejor opción.

Subu Sankara Subramanian
fuente
-1

Hay una forma más eficiente de insertar datos en la base de datos usando php y mysql. Podemos usar LOAD COMMAND para insertar los datos. Inserta datos notablemente rápido.

Para esto, cree un archivo plano (por ejemplo, utilicé el archivo .csv) con sus datos utilizando la fputcsv()función. Luego inserte los datos usando el comando LOAD. Sintaxis algo similar a la siguiente:

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

Intenta lo siguiente. Trabajó para mi.

Los nombres de los formularios deben ser iguales a los nombres de las columnas de la base de datos.

Obtenga los valores de la siguiente manera:

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

Primero deberá insertar una ID antes del bucle foreach. puedes obtener la siguiente identificación haciendo:

SELECT MAX(id) FROM .....

agregue 1 al id e insértelo.

Ángel
fuente