2009-06-19 18 views
33

Tengo una tabla distribuida en dos servidores que ejecutan MySql 4. Necesito fusionarlos en un solo servidor para nuestro entorno de prueba.mysqldump tabla sin volcar la clave principal

Estas tablas literalmente tienen millones de registros cada una, y la razón por la que están en dos servidores es por lo grandes que son. Cualquier alteración y paginación de las tablas nos dará un golpe de rendimiento demasiado grande.

Debido a que se encuentran en un entorno de producción, es imposible para mí modificarlos de ninguna manera en sus servidores existentes.

El problema es que la clave principal es un campo único de incremento automático, por lo que hay intersecciones.

He estado tratando de encontrar la manera de usar el comando mysqldump para ignorar ciertos campos, pero las teclas --disable simplemente modifican la tabla, en lugar de deshacerse completamente de las claves.

En este punto, parece que voy a necesitar modificar la estructura de la base de datos para utilizar una suma de comprobación o hash para la clave principal como una combinación de los dos campos únicos que realmente deberían ser únicos ... Realmente no me gusta no quiero hacer esto

¡Ayuda!

Respuesta

24

si no le importa cuál será el valor de la columna auto_increment, simplemente cargue el primer archivo, cambie el nombre de la tabla, vuelva a crear la tabla y cargue el segundo archivo. Finalmente, el uso

INSERT newly_created_table_name (all, columns, except, the, auto_increment, column) 
     SELECT all, columns, except, the, auto_increment, column 
     FROM renamed_table_name 
+0

parece prometedor, comenzaré a probar esto. –

+0

Tengo un campo de clave externa que hace referencia a claves principales. ¿Mantiene esta solución ese tipo de integridad referencial? No parece que lo haga. – aamiri

+1

No, no lo hará. Cambia la clave principal. – longneck

10

Puede crear una vista de la tabla sin la columna de clave principal, luego ejecute mysqldump en esa vista.

Así que si sus "usuarios" tabla tiene las columnas: ID, nombre, correo electrónico

> CREATE VIEW myView AS 
    SELECT name, email FROM users 

Editar: ah que veo, no estoy seguro de si hay alguna otra manera a continuación.

+0

No en mysql 4 :(. Lo sé, triste :(. –

+0

Según el tamaño de la tabla, puede crear una copia temporal (sin PK) en lugar de crear una vista. – balpha

+0

Las tablas están en el rango de millones de registros. –

3
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'; 

Para fanciness añadido, se puede establecer un antes de insertar gatillo en su mesa receptora que establece la nueva clave principal para la fila alcance antes de que ocurra la inserción, utilizando para ello los vertederos regulares y todavía limpiando tu pk. No probado, pero con mucha confianza al respecto.

2

Utilice una clave primaria temporal ficticia:

Uso mysqldump normalmente --opts -c. Por ejemplo, tu clave principal es 'id'. Edite los archivos de salida y agregue una fila "dummy_id" a la estructura de su tabla con el mismo tipo que 'id' (pero no clave primaria, por supuesto). Luego modifique la instrucción INSERT y reemplace 'id' por 'dummy_id'. Una vez importado, suelte la columna 'dummy_id'.

0

jimyi estaba en el camino correcto.

Esta es una de las razones por las cuales las claves de autoincrement son un PITA. Una solución no es eliminar datos sino agregarlos.

CREATE VIEW myView AS 
SELECT id*10+$x, name, email FROM users 

(donde $ x es un solo dígito identifica de forma unívoca la base de datos original) o bien la creación de la vista en la base de datos fuente (que se insinúan no puede ser posible) o utilizar una rutina de extracto como el descrito por autocracia o la carga los datos en tablas de etapas en el cuadro de prueba.

Por otra parte, no crean la tabla en el sistema de prueba - en su lugar poner en tablas separadas para los datos src continuación, crear una visión que obtiene de los dos:

CREATE VIEW users AS 
(SELECT * FROM users_on_a) UNION (SELECT * FROM users_on_b) 

C.

+0

No entiendo cómo ayuda la creación de una vista, ya que mysqldump no muestra la vista DATA, solo la declaración CREATE VIEW, por lo que no está más adelante. Si solo está utilizando la vista para crear una tabla temporal, la vista es redundante. Si va a usar select ... en el archivo de salida, entonces una vez más, la vista es redundante. ¿Qué me estoy perdiendo? –

6
  1. clonar Su mesa
  2. gota la columna en la tabla clon
  3. vuelca la tabla clon sin la estructura (pero con la opción -c para obtener inserciones completas)
  4. Importe donde desee
3

Esto es un dolor total. Me sale este problema mediante la ejecución de algo así como

sed -e "s/([0-9]*,/(/gi" export.sql > expor2.sql 

en el vertedero para deshacerse de las claves primarias y luego

sed -e "s/VALUES/(col1,col2,...etc.) VALUES/gi" LinxImport2.sql > LinxImport3.sql 

para todas las columnas excepto para la clave principal. Por supuesto, tendrá que tener cuidado de que ([0-9]*, no reemplace nada de lo que realmente desea.

Espero que ayude a alguien.

+0

Tuve que quitar la bandera 'i' de la expresión regular, pero de lo contrario, ¡esto funcionó como un amuleto! ¡Gracias! – joshwhatk

+0

no necesita la segunda instrucción cuando usa 'mysqldump --complete-insert ...'. – Blauhirn

0

La solución que he estado utilizando es hacer una exportación de SQL regular de los datos que estoy exportando, y luego eliminar la clave primaria de las instrucciones de inserción usando un editor de reemplazo de encontrar RegEx &. Personalmente utilizo Sublime Text, pero estoy seguro de que TextMate, Notepad ++, etc. pueden hacer lo mismo.

A continuación, ejecuto la consulta en la base de datos en la que deben insertarse los datos copiando y pegando la consulta en la ventana de consulta de HeidiSQL o PHPMyAdmin. Si hay un LOTE de datos, guardo la consulta de inserción en un archivo SQL y uso la importación de archivos en su lugar. Copiar & pegar con grandes cantidades de texto a menudo hace que Chrome se congele.

Esto puede parecer mucho trabajo, pero rara vez uso más de un par de minutos entre la exportación y la importación. Probablemente mucho menos de lo que usaría en la solución aceptada. He usado este método de solución en varios cientos de miles de filas sin problemas, pero creo que sería problemático cuando alcanzas los millones.

10

Para resolver este problema, busqué esta pregunta, encontré la respuesta de @ pumpkinthehead, y me di cuenta de que todo lo que tenemos que hacer es encontrar + reemplazar la clave primaria en cada fila con NULL para que mysql use el valor predeterminado auto_increment en lugar.

(your complete mysqldump command) | sed -e "s/([0-9]*,/(NULL,/gi" > my_dump_with_no_primary_keys.sql

de salida original:

INSERT INTO `core_config_data` VALUES 
    (2735,'default',0,'productupdates/configuration/sender_email_identity','general'), 
    (2736,'default',0,'productupdates/configuration/unsubscribe','1'), 

de partida transformados:

INSERT INTO `core_config_data` VALUES 
    (NULL,'default',0,'productupdates/configuration/sender_email_identity','general'), 
    (NULL,'default',0,'productupdates/configuration/unsubscribe','1'), 

Nota: Esto sigue siendo un truco; Por ejemplo, fallará si su columna de autoincremento no es la primera columna, pero resuelve mi problema el 99% del tiempo.

Cuestiones relacionadas