Quelle est la meilleure façon d'insérer un grand ensemble de données dans une base de données MySQL (ou n'importe quelle base de données en général)


9

Dans le cadre d'un projet PHP, je dois insérer une ligne dans une base de données MySQL. Je suis évidemment habitué à faire cela, mais cela nécessitait l'insertion dans 90 colonnes dans une requête. La requête résultante a l'air horrible et monolithique (en particulier en insérant mes variables PHP comme valeurs):

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

et je crains de ne pas m'y prendre correctement. Il m'a également fallu beaucoup de temps (ennuyeux) pour tout taper et tester l'écriture du code de test sera également fastidieux, je le crains.

Comment les professionnels rédigent-ils et testent-ils rapidement ces requêtes? Existe-t-il un moyen d'accélérer le processus?


2
Je suis plus préoccupé par le fait que le tableau comporte 90 colonnes que le temps insignifiant passé à taper les noms des colonnes. (Drag and drop BTW I toutes les colonnes à la fois dans SQL Server, est - il pas aplace faire la même chose dans mySQL ou PHP je regarde pour voir si vous pouvez constater que cela rend la vie plus facile car il n'y a pas de fautes de frappe?.)
HLGEM

1
Je sais que 90 colonnes, c'est beaucoup, mais chaque colonne se rapporte à un seul champ pour un document pdf que je dois remplir et je ne vois pas l'intérêt de le décomposer, ni comment je le ferais. Merci pour les informations sur SQL Server. Je ne sais pas trop ce que vous voulez dire par glisser-déposer des colonnes mais je vais y jeter un œil.
Joe

1
Écrivez une instruction select qui répertorie toutes les colonnes d'une table donnée et continuez à partir de là.
JeffO

Jeff O: Je l'ai utilisé aussi, cela peut être une technique très puissante si elle est bien faite. Vous devriez poster cela comme réponse si vous pouvez donner un exemple de code!
FrustratedWithFormsDesigner

Réponses:


7

Joe, votre dernier commentaire a beaucoup expliqué. Je pense que le vrai problème est la conception des données. De nouvelles colonnes peuvent être nécessaires lorsque le format du document change, et d'après mon expérience, les formats de document ont tendance à changer fréquemment. Au lieu d'une table à 90 colonnes, avec une seule ligne par rapport, je stocke les données du rapport dans une table à quatre colonnes: report_id, format_id, field_name, field_value. Chaque rapport serait représenté par 90 lignes, une pour chaque valeur de champ dans le rapport. Cela devrait considérablement simplifier votre code.


Merci pour votre réponse. Tous les champs (à l'exception de l'index) sont des VARCHARS, donc cela fonctionnerait pour moi (et je pourrais quand même convertir d'autres valeurs). Je gaspille peut-être beaucoup d'espace, car je devrais avoir la taille de la colonne field_value définie sur la plus grande valeur (environ 256 caractères), tandis que certains champs ne nécessitent qu'une longueur de 3. Il serait certainement plus facile à utiliser et je peux comprendre comment ce serait plus à l'épreuve du temps comme vous l'avez décrit.
Joe

4
FWIW, la plupart des systèmes de bases de données n'utilisent que l'espace requis pour stocker les données. Donc, si vous ne stockez que 3 caractères dans un champ VARCHAR (256), cela ne prendra que 3 octets, pas 256. Je ne sais pas grand-chose sur les internes de MySQL, mais je serais surpris s'ils remplissaient leurs champs au maximum taille déclarée.
TMN

@TMN C'est ce que signifie le VAR dans VARCHAR! Longueur variable Car. Il s'agit d'une fonction (ou de la définition) du type de données et non du système de base de données. Ce n'est pas non plus parce qu'un VARCHAR est de longueur variable, la base de données doit connaître la longueur de chaque valeur, donc elle stocke la longueur en tant que métadonnées. Cela signifie un stockage aérien! Donc, un VARCHAR (1) utilise en fait 3 octets de données à cause de la surcharge, 3x autant qu'un Char (1)!
Morons

2
-1, je ne suis pas d'accord avec cette réponse, dans ce cas, vous êtes mieux avec 90 colonnes. Si l'entité a 90 points de données, qu'il en soit ainsi, gardez vos données rationnelles.
Morons

@TMN juste pour clarifier mon propos, a déclaré: "Donc, si vous ne stockez que 3 caractères dans un champ VARCHAR (256), cela ne prendra que 3 octets" La vérité est que cela prendra 5 octets et non 3.
Morons

7

En général, le moyen le plus rapide pour charger un grand ensemble de données dans une base de données SQL consiste à utiliser l'interface de chargement en masse native. Pour autant que je sache, chaque dbms SQL en a au moins un.

Documents MySQL: utilisation du chargeur en bloc

Si je dois transformer un fichier délimité par des tabulations ou des virgules en instructions SQL INSERT, j'utilise awk pour lire le fichier d'entrée et écrire le fichier de sortie. Awk n'a rien de vraiment spécial; il se trouve que c'est le langage de traitement de texte que je connais le mieux. Vous pouvez obtenir les mêmes résultats en écrivant du code en Perl, Python, Ruby, Rexx, Lisp, etc.


2
Le chargement en masse est en effet la voie à suivre si vous devez insérer un grand nombre de lignes, mais dans ce cas, il insère simplement une seule ligne avec beaucoup de colonnes. Le chargement en masse n'aidera pas et nécessitera probablement d'écrire plus de code que l'approche simple.
TMN

-1, cette réponse manque complètement le point de la question
Doc Brown

2

Si vous pouvez facilement obtenir les noms de colonne dans une feuille de calcul Excel, vous pouvez écrire des macros Excel pour produire du code pour diverses requêtes et instructions DML, puis collez simplement les valeurs dans une autre colonne et votre instruction d'insertion / mise à jour est créée automatiquement pour vous. La saisie manuelle est un moyen très lent de le faire, alors voyez si vous pouvez trouver des astuces en utilisant vos outils existants. De nombreux éditeurs de texte destinés aux développeurs ont également la possibilité d'enregistrer et de stocker des macros pour rendre les travaux répétitifs comme celui-ci beaucoup plus rapides et plus faciles.


2

Si vous avez un fichier csv, vous pouvez utiliser LOAD DATA INFILE ... pour importer les données.

Si vous devez utiliser des requêtes 'INSERT', effectuer des insertions en masse accélérera le processus. Au lieu d'exécuter une requête «INSERT» pour chaque ligne, regroupez les lignes, dites 100 et exécutez la requête. Quelque chose comme ça:

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

Un moyen efficace d'écrire des données de requête multi-colonnes dans la base de données MySQL consiste à convertir ces données au format JSON ou YAML et à les insérer en une seule unité. Il change "écrire un insert pour une table avec 90 colonnes" en "écrire un insert dans une table avec une colonne".

Dans cette approche, tout ne doit pas être décomposé en ses composants de base, et la donnée unique est stockée juste dans 1 colonne.


@gnat: il propose une solution alternative. Il change "écrire un insert pour une table avec 90 colonnes" en "écrire un insert dans une table avec une colonne". Étant donné le problème décrit, c'est une solution valable. Tout n'a pas besoin d'être décomposé en ses composants de base. La seule autre réponse similaire, a suggéré d'aller complètement NoSQL, en éliminant complètement la base de données SQL, ce qui est exagéré. Cette réponse indique que vous pouvez utiliser une approche mixte. Créez une seule colonne pour cette seule donnée. Considérez que l'alternative pourrait être d'avoir une colonne binaire et de stocker le pdf entier.
jmoreno

@gnat: Je vais donner à Noviff la chance de le dire avec ses propres mots ...
jmoreno

@ gnat et jmoreno - merci pour vos commentaires. J'aime la clarification de ma réponse par moucheron, et j'ai édité la réponse en fonction de sa clarification.
novembre 2017

0

Avec MySQL, vous pouvez utiliser une syntaxe alternative pour les insertinstructions:

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

1
Est-ce vraiment plus rapide?
Pacerier

@Pacerier Non, ce n'est pas plus rapide. Juste une autre syntaxe.
Kaspars Foigts

0

Votre scénario ressemble à un très bon ajustement pour une solution NoSQL, car la liste d'attributs peut changer à chaque fois que le format change. Avez-vous évalué d'autres options que MySQL? Creusez autour de DynamoDB / MongoDB / Cassandra - cela pourrait être un meilleur ajustement.


-1

Il existe un moyen plus efficace d'insérer des données dans la base de données en utilisant php et mysql. Nous pouvons utiliser LOAD COMMAND pour insérer les données. Il insère des données remarquablement rapidement.

Pour cela, créez un fichier plat (par exemple, j'ai utilisé un fichier .csv) avec vos données en utilisant la fputcsv()fonction. Insérez ensuite les données à l'aide de la commande LOAD. Syntaxe certains ce qui ressemble à ci-dessous:

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

Essayez ce qui suit. A travaillé pour moi.

Les noms de formulaire doivent être égaux aux noms de colonne de base de données

Obtenez les valeurs comme ci-dessous:

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

Vous devrez d'abord insérer un ID avant la boucle foreach. vous pouvez obtenir le prochain identifiant en faisant:

SELECT MAX(id) FROM .....

ajoutez 1 à id et insérez-le.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.