J'ai une table répartie sur deux serveurs exécutant MySql 4. Je dois les fusionner en un seul serveur pour notre environnement de test.
Ces tables ont littéralement des millions d'enregistrements chacune, et la raison pour laquelle elles se trouvent sur deux serveurs est à cause de leur taille énorme. Toute modification et pagination des tables nous donnera un énorme coup de performance.
Parce qu'ils sont dans un environnement de production, il m'est impossible de les modifier de quelque façon que ce soit sur leurs serveurs existants.
Le problème est que la clé primaire est un champ d'incrémentation automatique unique, donc il y a des intersections.
J'ai essayé de comprendre comment utiliser la commande mysqldump pour ignorer certains champs, mais les touches --disable-modifient simplement la table, au lieu de se débarrasser complètement des clés.
À ce stade, il semble que je vais devoir modifier la structure de la base de données pour utiliser une somme de contrôle ou un hachage pour la clé primaire en tant que combinaison des deux champs uniques qui devraient en fait être uniques ... Je ne veux vraiment pas fais ça.
Aidez-moi!
si vous ne vous souciez pas de la valeur de la colonne auto_increment, chargez simplement le premier fichier, renommez la table, puis recréez la table et chargez le deuxième fichier. enfin, utilisez
INSERT newly_created_table_name (all, columns, except, the, auto_increment, column)
SELECT all, columns, except, the, auto_increment, column
FROM renamed_table_name
Pour résoudre ce problème, j'ai recherché cette question, trouvé la réponse de @ pumpkinthehead et réalisé que tout ce que nous devons faire est de trouver + remplacer la clé primaire de chaque ligne par NULL afin que mysql utilise à la place la valeur auto_increment par défaut.
(your complete mysqldump command) | sed -e "s/([0-9]*,/(NULL,/gi" > my_dump_with_no_primary_keys.sql
Sortie d'origine:
INSERT INTO `core_config_data` VALUES
(2735,'default',0,'productupdates/configuration/sender_email_identity','general'),
(2736,'default',0,'productupdates/configuration/unsubscribe','1'),
Sortie transformée:
INSERT INTO `core_config_data` VALUES
(NULL,'default',0,'productupdates/configuration/sender_email_identity','general'),
(NULL,'default',0,'productupdates/configuration/unsubscribe','1'),
Remarque: il s'agit toujours d'un hack; Par exemple, il échouera si votre colonne d'incrémentation automatique n'est pas la première colonne, mais résout mon problème 99% du temps.
Vous pouvez créer une vue de la table sans la colonne de clé primaire, puis exécuter mysqldump sur cette vue.
Donc, si votre table "utilisateurs" a les colonnes: id, nom, email
> CREATE VIEW myView AS
SELECT name, email FROM users
Edit: ah je vois, je ne sais pas s'il y a un autre moyen alors.
C'est une douleur totale. Je contourne ce problème en exécutant quelque chose comme
sed -e "s/([0-9]*,/(/gi" export.sql > expor2.sql
sur la décharge pour se débarrasser des clés primaires, puis
sed -e "s/VALUES/(col1,col2,...etc.) VALUES/gi" LinxImport2.sql > LinxImport3.sql
pour toutes les colonnes à l'exception de la clé primaire. Bien sûr, vous devrez faire attention à ce que ([0-9]*,
ne remplace rien de ce que vous voulez réellement.
J'espère que cela aide quelqu'un.
SELECT null as fake_pk, `col_2`, `col_3`, `col_4` INTO OUTFILE 'your_file'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM your_table;
LOAD DATA INFILE 'your_file' INTO TABLE your_table
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';
Pour plus de fantaisie, vous pouvez définir un déclencheur avant l'insertion sur votre table de réception qui définit la nouvelle clé primaire pour la ligne de portée avant l'insertion, ce qui utilise des vidages réguliers et efface toujours votre paquet. Non testé, mais plutôt confiant.
Utilisez une clé primaire temporaire factice:
Utilisez mysqldump
normalement --opts -c
. Par exemple, votre clé primaire est 'id'. Modifiez les fichiers de sortie et ajoutez une ligne "dummy_id" à la structure de votre table avec le même type que 'id' (mais pas la clé primaire bien sûr). Modifiez ensuite l'instruction INSERT
et remplacez 'id' par 'dummy_id'. Une fois importé, déposez la colonne 'dummy_id'.
jimyi était sur la bonne voie.
C'est l'une des raisons pour lesquelles les clés à incrémentation automatique sont un PITA. Une solution consiste à ne pas supprimer les données mais à y ajouter.
CREATE VIEW myView AS
SELECT id*10+$x, name, email FROM users
(où $ x est un chiffre unique identifiant de manière unique la base de données d'origine) soit en créant la vue sur la base de données source (ce que vous suggérez peut-être pas possible) ou utilisez une routine d'extraction comme celle décrite par Autocracy ou chargez les données dans des tables intermédiaires sur le boîte de test.
Alternativement, ne créez pas la table sur le système de test - placez plutôt des tables séparées pour les données src puis créez une vue qui les récupère toutes les deux:
CREATE VIEW users AS
(SELECT * FROM users_on_a) UNION (SELECT * FROM users_on_b)
C.
J'aime la route des tables temporaires.
create temporary table my_table_copy
select * from my_table;
alter table my_table_copy drop id;
// Use your favorite dumping method for the temporary table
Comme les autres, ce n'est pas une solution universelle (surtout compte tenu des millions de lignes de OP), mais même à 10 ^ 6 lignes, l'exécution prend plusieurs secondes mais fonctionne.
La solution que j'ai utilisée consiste à simplement effectuer une exportation SQL régulière des données que j'exporte, puis à supprimer la clé primaire des instructions d'insertion à l'aide d'un éditeur RegEx find & replace. Personnellement, j'utilise Sublime Text, mais je suis sûr que TextMate, Notepad ++ etc. peuvent faire de même.
Ensuite, je lance simplement la requête dans quelle base de données les données doivent être insérées en copiant coller la requête dans la fenêtre de requête de HeidiSQL ou PHPMyAdmin. S'il y a BEAUCOUP de données, j'enregistre la requête d'insertion dans un fichier SQL et j'utilise plutôt l'importation de fichiers. Le copier-coller avec d'énormes quantités de texte fait souvent geler Chrome.
Cela peut sembler beaucoup de travail, mais j'utilise rarement plus de quelques minutes entre l'exportation et l'importation. Probablement beaucoup moins que ce que j'utiliserais sur la solution acceptée. J'ai utilisé cette méthode de solution sur plusieurs centaines de milliers de lignes sans problème, mais je pense que cela deviendrait problématique lorsque vous atteignez les millions.