68 votes

Remplir les tables de la base de données avec un grand nombre de données de test

Je dois charger un tableau avec un grand nombre de données de test. Ces données seront utilisées pour tester les performances et la mise à l'échelle.

Comment puis-je créer facilement 100 000 lignes de données aléatoires ou inutiles pour ma table de base de données ?

1 votes

Disposez-vous déjà des données de test ou allez-vous devoir les générer ?

1 votes

Quelle est la structure de votre tableau ? et quelle langue utiliser ?

0 votes

Non, je n'ai pas de données de test, c'est pour les générer que je cherche une solution.

89voto

Daniel Vassallo Points 142049

Vous pouvez également utiliser un procédure stockée . Prenons l'exemple du tableau suivant :

CREATE TABLE your_table (id int NOT NULL PRIMARY KEY AUTO_INCREMENT, val int);

Vous pouvez alors ajouter une procédure stockée comme celle-ci :

DELIMITER $$
CREATE PROCEDURE prepare_data()
BEGIN
  DECLARE i INT DEFAULT 100;

  WHILE i < 100000 DO
    INSERT INTO your_table (val) VALUES (i);
    SET i = i + 1;
  END WHILE;
END$$
DELIMITER ;

Lorsque vous l'appellerez, vous aurez 100 000 enregistrements :

CALL prepare_data();

0 votes

Êtes-vous sûr que cela fonctionnerait pour MySQL ? Je n'ai jamais vu WHILE dans les requêtes MySQL.

0 votes

C'est bien mais nous avons besoin de données moyennes complètes avec plus de colonnes dans les données.

1 votes

@fritzmg C'est parce que la valeur initiale de i a été fixée à 100.

18voto

michalzuber Points 700

Pour le clonage de plusieurs lignes (duplication de données), vous pouvez utiliser

DELIMITER $$
CREATE PROCEDURE insert_test_data()
BEGIN
  DECLARE i INT DEFAULT 1;

  WHILE i < 100000 DO
    INSERT INTO `table` (`user_id`, `page_id`, `name`, `description`, `created`)
    SELECT `user_id`, `page_id`, `name`, `description`, `created`
    FROM `table`
    WHERE id = 1;
    SET i = i + 1;
  END WHILE;
END$$
DELIMITER ;
CALL insert_test_data();
DROP PROCEDURE insert_test_data;

5voto

Ici, la solution est purement mathématique et SQL :

create table t1(x int primary key auto_increment);
insert into t1 () values (),(),();

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 1265 rows affected (0.01 sec)
Records: 1265  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 2530 rows affected (0.02 sec)
Records: 2530  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 5060 rows affected (0.03 sec)
Records: 5060  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 10120 rows affected (0.05 sec)
Records: 10120  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 20240 rows affected (0.12 sec)
Records: 20240  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 40480 rows affected (0.17 sec)
Records: 40480  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 80960 rows affected (0.31 sec)
Records: 80960  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 161920 rows affected (0.57 sec)
Records: 161920  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 323840 rows affected (1.13 sec)
Records: 323840  Duplicates: 0  Warnings: 0

mysql> insert into t1 (x) select x + (select count(*) from t1) from t1;
Query OK, 647680 rows affected (2.33 sec)
Records: 647680  Duplicates: 0  Warnings: 0

0 votes

Votre tableau ne comporte-t-il qu'une seule colonne ? J'aime l'idée de dupliquer les lignes existantes, mais il se peut que votre requête doive être quelque peu modifiée pour utiliser des colonnes supplémentaires. Vous devriez également être en mesure d'insérer NULL pour couvrir les AUTO_INCREMENT colonnes.

0 votes

Je n'aime pas dupliquer les lignes - lors des requêtes pour les tests - le cas d'utilisation peut être tel que vous ne pouvez pas voir où votre requête échoue dans le résultat attendu.

4voto

gmarcotte Points 387

Si vous souhaitez avoir plus de contrôle sur les données, essayez quelque chose comme ceci (en PHP) :

<?php
$conn = mysql_connect(...);
$num = 100000;

$sql = 'INSERT INTO `table` (`col1`, `col2`, ...) VALUES ';
for ($i = 0; $i < $num; $i++) {
  mysql_query($sql . generate_test_values($i));
}
?>

où la fonction generate_test_values renverrait une chaîne formatée comme "('val1', 'val2', ...)". Si cela prend beaucoup de temps, vous pouvez les grouper afin de ne pas faire autant d'appels à la base de données, par exemple :

for ($i = 0; $i < $num; $i += 10) {
  $values = array();
  for ($j = 0; $j < 10; $j++) {
    $values[] = generate_test_data($i + $j);
  }
  mysql_query($sql . join(", ", $values));
}

n'exécuterait que 10000 requêtes, chacune ajoutant 10 lignes.

0 votes

Retardez un peu les boucles ; pour éviter les erreurs MySQL Server has gone away, si vous les obtenez.

0 votes

Notez que cette réponse est assez ancienne. mysql_connect() est obsolète et n'est plus disponible en PHP 7.

1voto

Essayer filldb

Vous pouvez soit publier votre schéma, soit utiliser le schéma existant et générer des données fictives, les exporter à partir de ce site et les importer dans votre base de données.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X