Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General »

migrar base de datos

Estas en el tema de migrar base de datos en el foro de Bases de Datos General en Foros del Web. Estimados: Necesito realizar la migración de una base de datos que tengo en mssql (a mysql aunque esto ultimo no es el inconveniente). El tema ...
  #1 (permalink)  
Antiguo 19/08/2008, 13:31
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años, 6 meses
Puntos: 2
migrar base de datos

Estimados:

Necesito realizar la migración de una base de datos que tengo en mssql (a mysql aunque esto ultimo no es el inconveniente). El tema es que tengo que pasar los datos de una manera no lineal. Algunos campos tengo que separarlos en dos o mas según un determinado patrón, por ejemplo, el campo nombre_apellido tiene una lista de nombres y apellidos separados por (,) para separar nombre de apellido y (;) para separar grupos nombre,apellido .

cada nombre se convierte en dos campos, campo nombre y campo apellido, se le asigna un id y se vincula con el registro original.

Como esto tengo que hacer varias cosas mas. Hay alguna forma sencilla de resolver esto con algun soft?. Yo hice un script php que lo resuelve, pero no creo que sea lo adecuado.

voy campo por campo, tomo todos los nombres y los armo en un array
recorro el array si no existe la persona inserto el valor en la tabla nueva, tomo el id y lo guardo en la tabla union (idPersona, idRegistroOriginal)

Que me recomiendan? ya sea soft o logica para resolverlo

saludos
  #2 (permalink)  
Antiguo 19/08/2008, 19:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: migrar base de datos

Buena suerte al intentarlo...
¿Cómo harías si te toca separar el nombre, por ejemplo de Verónica Gabriela de Torres y De la Puerta?
No es un nombre ficticio.. era el nombre de una alumna mía hace años y ese era su nombre completo... Como tal figuraba en documentos, certificados, pasaportes y planillas de inscripción (puntualmente el apellido del padre era De Torres y el de la madre De la Puerta).

Lo que quiero decir es que si la tabla en cuestión tiene solamente un nombre y un apellido, la cosa es fácil. Pero si te vas a encontrar con nombres dobles o triples (como admite la ley argentina, por ejemplo) y apellidos simples, dobles y/o compuestos (también admisibles en muchos países)... El algoritmo se vuelve imposible, y el que planteas tu, directamente obsoleto.

Por eso siempre se recomienda que NUNCA se use un sólo campo para nombre y apellido. Es más fácil unir que separar.

Sintetizando: Analiza la composición del campo en cuestión. Si te encuentras que hay campos con tres strings (que pueden implicar tanto nombres dobles como apellidos dobles), la única solución simple va a ser separarlos temporalmente para editarlos manualmente.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 20/08/2008, 05:36
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años, 6 meses
Puntos: 2
Respuesta: migrar base de datos

Por suerte, por no decir, para menos desgracia, los autores estan separados dentro del campo.
en el caso de tu alumna, que sería un caso excepcional supongo que estaría escrito del siguiente modo:

de Torres y De la Puerta, Verónica Gabriela ; Perez, Jose Ernesto
Eso no sería problema, el tema es con que lo hago?, que es lo mas conveniente?

saludos
  #4 (permalink)  
Antiguo 20/08/2008, 07:12
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: migrar base de datos

No me has entendido:
El problema no es cómo compones los campos, el problema a que te enfrentas es cómo hacer para que un programa reconozca que un determinado string es un nombre y otro es un apellido, porque obviamente el modo de hacerlo deberá ser automático para que la migración sea eficiente.

Piensa bien el ejemplo que te di: Contiene en total 8 strings de los cuales 6 son apellido...
A eso sumale el problema de cómo vas a diferenciar aquellos apellidos que son iguales a nombres, que los hay.

En eso se centra el inconveniente. Si estás seguro que los registros de ese campo solamente tienen dos strings por registro, no hay problema, pero si tienen más...
No creas que esto está traído de los pelos. La propuesta que te haces no serviría para separar un registro con mi propio nombre completo.

Respecto a cómo lo haces:

1. No hay aplicaciones comerciales u OpenSource que puedan hacer esa tarea eficientemente, por lo que deberás programarla

2. Debes hacer una interfase de programación, o una consulta con la cual separes en dos el contenido del campo (el uso combinado de LEFT(), RIGHT(), MID(), SUBSTR() y/o LOCATE() permitiría esa tarea), pero no te servirá bajo ningún contexto para separar un nombre compuesto por más de dos cadenas, sin analizar si el grupo mayor es de apellidos o nombres.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 20/08/2008 a las 07:28
  #5 (permalink)  
Antiguo 20/08/2008, 07:27
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años, 6 meses
Puntos: 2
Respuesta: migrar base de datos

Gracias por la respuesta.

Yo ya programé el script, y logro separar personas y luego apellidos de nombres, lo que me da la pauta de persona es la separación por punto y coma que existe en todos los casos.

quiero hacerlo con el gestor de db, pero en programación hice algo asi y separo todo bien, el tema es la performance y que aveces se cuelga:

para cada campo persona del registro
{
array personas[idRegistro][]= separar cadena en su punto y coma (;)
}

para cada personas
array per= separar persona en su coma (,)
nombre = per[0]
apellidos= per[1]

guardar en tabla personas nombre,apellido
guardar en tabla union IdRegistro,idPersona
  #6 (permalink)  
Antiguo 20/08/2008, 08:49
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 8 meses
Puntos: 300
Respuesta: migrar base de datos

ACLARO que todo esto es posterior a la importación a la base de los campos como los tienes, separados ahora por punto y coma. Está en la línea de lo que te dice gnzsoloyo y tú haces con la programación. Yo te recomendaría importar y luego trabajar con la base.
Si cargas el dato con "apellidos, nombre" en un campo llamado autor de una tabla llamada autores, luego en MySQL podrás añadir los datos a unos campos que crearás llamados apellidos y nombre. Con una sintaxis parecida a esta puedes mostrarlos
SELECT LEFT(autor, LOCATE (',', autor)-1) AS apellidos FROM autores
SELECT SUBSTRING (autor, LOCATE (',', autor)+1) AS nombre FROM autores

y para añadir los datos a esos campos nombre y apellidos:
1) para el campo nombre:
UPDATE autores SET nombre = LEFT(autor, LOCATE (',', autor)-1)
2) para el campo apellidos
UPDATE autores SET apellidos = SUBSTRING (autor, LOCATE (',', autor)+1)

y en caso de que haya espacios antes o después de la coma, puedes eliminarlos con TRIM (aunque esto no lo he probado):
1) para el campo nombre:
UPDATE autores SET nombre = TRIM(LEFT(autor, LOCATE (',', autor)-1))
2) para el campo apellidos
UPDATE autores SET apellidos = TRIM(SUBSTRING (autor, LOCATE (',', autor)+1))

Pero antes haz una prueba con los select para que veas que todo está bien.
Luego compruebas que todo está bien y tras eso borras el campo autor.
En esencia es lo que te recomendaba gnzsoloyo, pero usando la coma que los separa y el orden apellidos-nombre como clave de separación una vez importado en MySQL.

Última edición por jurena; 20/08/2008 a las 09:37
  #7 (permalink)  
Antiguo 20/08/2008, 12:17
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: migrar base de datos

Lamento no haber tomado nota del separador que mencionaste en el primer post. Caso contrario no hubiese insistido tanto con el tema.
El problema que planteabas es algo que aparece frecuentemente en foros de bases de datos, precisamente porque por inexperiencia o por dejadez de algunos encargados del modelo de datos no se percatan del problema a largo plazo que ocasionan las bases diseñadas rudimentariamente, en especial en datos como nombres y apellidos, ciudades y provincias, calles y numeraciones, etc.
En la mayoría de los casos ni tan siquiera se han molestado en poner un separador como la coma o el punto y coma para dividir el contenido, y de allí mi insistencia con el problema.
Me alegra que quien haya hecho este modelo haya tenido en cuenta eso.

La propuesta de Jurena es una de las formas en que puedes hacer el proceso. Habría que ver si las funciones que propone pueden ser ejecutadas en un sólo SELECT, como por ejemplo:
Código:
SELECT 
      TRIM(LEFT(autor, LOCATE (',', autor)-1)) Nombre, 
      TRIM(SUBSTRING (autor, LOCATE (',', autor)+1)) Apellido
FROM autores;
De esa forma podrías hacer un INSERT INTO ... SELECT ... FROM directo...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 20/08/2008, 12:34
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años, 6 meses
Puntos: 2
Respuesta: migrar base de datos

Gracias a Ambos, de todas formas, antes de separar apellidos de nombres, tengo que separar autores entre si, como hago esto en conjunción con lo que me mostraron previamente?

registro id1 autor: jose,perez;Roberto, juarez; pepe, Quiroga
registro id2 autor: ana,perez;laura, juarez; Equistafia, Quiroga

segun entiendo, teniendo un autor solamente en un registro puedo separarlos con dicho script, pero aca tengo que hacer un desgloce mayor
  #9 (permalink)  
Antiguo 20/08/2008, 14:33
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 8 meses
Puntos: 300
Respuesta: migrar base de datos

Morón,
en primer lugar, te he propuesto una sintaxis para un orden apellido,nombre, cuando en realidad tienes un orden nombre,apellido, y pensando en que en cada campo había datos de un solo autor. Pero eso ahora no importa, pues creo que tu problema podría ser mayor.
¿cómo separas los campos de la base cuando exportas, pues si usas como separador el punto y coma o la coma, tendrás problemas, ya que me parece que esa separación de nombres mediante punto y coma se produce dentro de un campo.
A ver si he entendido: aquí el problema son, según me parece ahora, las relaciones entre dos tablas, pues sugieres la existencia de una tabla con la lista de autores, es decir, de nombres y apellidos (no estoy seguro de que exista y tal vez tienes que crearla), y que tendrá un id; y por otra parte otra tabla en la que se han almacenado, no los id de esa tabla con la lista de autores, sino los nombres en una cadena separada por puntos y coma, cuando lo lógico sería que existiese una tercera tabla con los id del id de esa tabla y el id de la tabla autores como FK. No sé si me explico. ¿Es ese el problema?, porque este tipo de almacenamiento con separación de punto y coma dentro de un campo, y con uso de cadenas de texto (los nombres) en lugar de números, no es muy adecuado.
Explícanos un poco más la estructura de lo que tienes y lo que quieres obtener...

EDITO para tratar de aclararte un poco más lo que te puse antes.
tabla1 (la que tienes y quieres exportar a MySQL o importar desde MySQL), id, campo1, nombre_apellido, campo2, etc.

Tú dices que tu objetivo es obtener una tabla llamada union con los datos de esos nombres, sin repetir. Eso puedes hacerlo de muchas maneras, una de ellas la que dices del array. También podrías exportar a texto y luego cambiar los puntos y coma en el tratamiento de texto por salto de párrafo; posteriormente importas desde la tabla de MySQL. No deben preocuparte las repeticiones, pues luego desde la tabla puedes eliminarlas haciendo una tercera tabla e insertando una selección agrupada por nombre_apellido. Todavía no sería el momento de separar nombres y apellidos. Esto nos daría la tabla donde los autores estarían con su id como clave primaria. Te quedarán los campos idunion, nombre_apellido. Si fuera sólo eso, sería fácil.

Pero me parece que te falta una tabla3, la tabla intermedia entre esta última y la primera, es decir, la tabla de conexión entre tabla1 y esta tabla union, la de la lista. Sería tal vez una tabla con los campos idtabla3, refidtabla1, nombre_apellido que contendría un registro de cada nombre (aquí sí podrá aparecer el mismo nombre_apellidos en varios registros y no tendríamos que eliminar los nombre_apellidos repetidos). Si fuera así, habría que hacer un INNER JOIN entre las tablas union y tabla3 para asignar el id de la tabla union como refidtabla1 (al final, estarían relacionadas las tablas por campos numéricos y no por cadenas de texto), pero todo eso habría que hacerlo más tarde. Y además, en ese caso, la solución del array que tú propones sería mejor, pues te permitiría añadir el id de la tabla1 junto a cada nombre en esa tabla3, algo que en el tratamiento de texto tendrías que hacer de manera manual o con un macro.

En cualquier caso, yo haría todo el trabajo después de haber exportado los campos tal y como los tienes a MySQL. Luego desde MySQL trabajaría para exportar a texto o trabajar con PHP mediante arrays, etc. Finalmente, una vez hecho todo y tras las comprobaciones necesarias, eliminaría los campos que ya no me sirvieran y usaría las sintaxis propuestas para separar nombres y apellidos en la tabla union. Esta es mi opinión, la de un no profesional.
Pero lo más importante es saber qué vas a hacer con esos datos. Como no sabemos cuál es la estructura de esa tabla, con qué intención se hizo, cómo se utilizaba, resulta difícil ver qué hacer. Lo que sabemos es cómo están almacenados los datos. Me explico:
si en la tabla uno tienes los nombres de productos comprados por esas personas, necesitarás tres tablas como te he dicho:
una con el producto y sus datos, otra con la lista de compradores y otra con los datos de cada compra...

Última edición por jurena; 21/08/2008 a las 02:46
  #10 (permalink)  
Antiguo 21/08/2008, 06:18
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años, 6 meses
Puntos: 2
Respuesta: migrar base de datos

Claro.

La tabla que me dieron corresponde a publicaciones, cada publicación tiene N autores y un autor puede tener N publicaciones. Razon por la cual, como bien decis, necesito migrar de este formato:

idPublicacion, titulo, autoresSeparadosPorPuntoYComa

a este otro:


publicaciones (idPublicacion,titulo)
Autores(idAutor,Apellido,Nombre)
tablaJoin(idPublicacion,idAutor)
  #11 (permalink)  
Antiguo 21/08/2008, 07:04
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 9 meses
Puntos: 13
Respuesta: migrar base de datos

Buenas,

Veo que la cosa se está alargando, asi que con vuestro permiso, voy a entrar en el hilo.
Por desgracia me ha tocado hacer más de una migración de BD, a ver si puedo ayudar en algo.

El como pasar los datos de una BD a otra es una decisión propia, teniendo entre otras opciones: linkar las BDs, hacerlo con cualquier lenguaje de programación...

Ahora el mayor problema con el que te vas a encontrar es con inconsistencia en la informacion, por ejemplo:
BD original -
Publicación (1, 'titulo1', 'Pepito gracia'; 'Joselito Garcia');
Publicación (2, 'titulo2', 'Pepito garcia'; 'Joselito García');
Parece que son el mismo, pero los apellidos no son los mismos en las 2 publicaciones, aunque el usuario queria que si lo fueran, asi que te quedan 2 autores distintos.
Dejando de lado los "gazapos" ortograficos, identificar una persona solo por su nombre y apellidos también puede llevar a "unir" N autores en 1 solo autor.

Como te veo en muy buenas manos con gnzsoloyo y jurena os dejo tranquilos, si necesitais algo avisar.

Salu2
  #12 (permalink)  
Antiguo 21/08/2008, 07:45
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años, 6 meses
Puntos: 2
Respuesta: migrar base de datos

Gracias por el aporte, tengo en cuenta esas cosas, pero no tengo opción. Aunque se que también podemos hablar de que un tipo puede tener identico nombre que otro, pero será cuestión de que luego se acomode manualmente, seria lo menos grave.

En el script que comenté oportunamente, voy revisando si el autor ya está en la tabla autores, de ser asi no creo uno nuevo, sino que tomo su id y lo cargo en la tabla join junto con el idPublicacion.

También se que Gomez, Raul puede estar escrito en varios registros de forma diferente (Gomez, Raul | Gomez, Raul J. |Gomez R), pero no es algo con lo que voy a luchar en esta instancia.
  #13 (permalink)  
Antiguo 21/08/2008, 12:00
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 8 meses
Puntos: 300
Respuesta: migrar base de datos

Yo, a pesar de lo que dice mi amigo Seyko (por cierto, estaremos todos encantados de que sigas entrando en este hilo y aportando), no puedo decirte nada sobre las conexiones entre distintas bases, etc. Yo, como te he dicho, me sitúo en el momento en que tienes exportados los datos a una tabla MysQL. Yo la he llamado titulos, y trabajo con la tabla MySQL directamente.

1) Esta consulta de inserción carga en la tabla autores (que he creado previamente con los campos idautor (int, autoincrementable) y autor (varchar)) los distintos autores que aparecen en registros de titulos que tengan un solo autor
INSERT INTO autores (autor) SELECT distinct autores FROM titulos WHERE autores NOT LIKE '%;%';

2) Esto carga en una tabla autortitulo (que he creado antes al efecto) en los campos refidtitulo y refidautor los datos de idtitulo y autores, procedentes de la tabla titulos (la de partida), pero solo aquellos en que hay un único autor:
INSERT INTO autortitulo (refidtitulo, refidautor) SELECT idtitulo, autores FROM titulos WHERE autores NOT LIKE '%;%';

3)
a) SELECT idtitulo, autores FROM titulos WHERE autores LIKE '%;%';
Esto te cargará el idtitulo y los autores separados por punto y coma. Esta consulta te servirá para cargar en el array que dices o para trabajar con ella en el tratamiento de texto.
b) tras trabajar con ellos, sea mediante arrays con PHP que generarán los datos que luego harás que se inserten en la tabla autores, o haciéndolo manualmente en un archivo de texto, importarás: I) desde la tabla de autortítulo, para la que utilizarás los dos datos, y
II) desde la tabla de autores, para la que no necesitarás el idtitulo.

4) Aquí te tocaría eliminar los repetidos (si no lo has hecho ya mediante programación) en la tabla autores, duplicados que puedes localizar con la consulta: SELECT *, count(*) as total FROM autor GROUP BY autor HAVING total > 1; eliminas todos los repetidos menos uno.

Ya tienes los datos. Ahora se trata de establecer las relaciones entre las tablas. Nos falta el número de refidautor en la tabla autortitulo, que ahora es una cadena. Aquí subsiste el peligro de que dos personas se llamen igual, es decir, que tengan los mismos nombre y apellido (ya eres consciente). Te tocaría revisar antes esos nombres...

Añades un campo a la tabla autortitulo llamado idautor, que será numérico, por ej. int(11)
y con esta consulta pones el idautor de autores al campo idautor de autortitulo:
UPDATE autortitulo at, autores a SET at.idautor = a.idautor WHERE a.autor = at.refidautor

5) Ahora, si todo está bien, puedes eliminar los campos refidautor de autor titulo
ALTER TABLE autortitulo DROP COLUMN refidautor

Y autores de la tabla titulos
ALTER TABLE titulos DROP COLUMN autores

6) creo en la tabla autores dos campos de texto, nombre y apellidos,
ALTER TABLE `autores` ADD `nombre` VARCHAR( 50 ) NOT NULL AFTER `autor` ,
ADD `apellidos` VARCHAR( 100 ) NOT NULL AFTER `nombre` ;

y luego pongo nombres y apellidos
mediante las sintaxis
UPDATE autores SET nombre = TRIM(LEFT(autor, LOCATE(',', autor)-1)), apellidos = TRIM(SUBSTRING(autor, LOCATE(',', autor)+1))

7) borro el campo autor de la tabla autores
ALTER TABLE autor DROP COLUMN autores



8) ahora puedo añadir los índices correspondientes a los PK (si no lo he hecho antes), es decir a los campos idautor y refidtitulo de la tabla autortitulo, y luego hacer un repair de las tablas y empezar a trabajar con inner join... etc.

Lo he ido probando y a mí me ha funcionado, aunque debes ir con mucho cuidado y revisando todo. Haz si quieres alguna prueba antes con pocos registros...

Tal vez no te sirva de nada, pero tal vez también te ofrezca alguna idea.

Última edición por jurena; 24/08/2008 a las 11:19
  #14 (permalink)  
Antiguo 21/08/2008, 13:19
Avatar de moron  
Fecha de Ingreso: mayo-2004
Mensajes: 972
Antigüedad: 20 años, 6 meses
Puntos: 2
Respuesta: migrar base de datos

Hermano, realmente te has tomado un lindo trabajo.
Lo voy a ir probando tranquilo y luego te comento.

desde ya muchicimas gracias.
  #15 (permalink)  
Antiguo 21/08/2008, 14:14
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 8 meses
Puntos: 300
Respuesta: migrar base de datos

De acuerdo, pero vigila también poner un tamaño amplio a los campos de autores en las distintas tablas pues si hay varios lo necesitarás. Y si los dejas pequeños, no sólo te cortará el nombre, sino que al hacer la actualización que te pone los id no podrá hacerlo pues un nombre y apellido cortados no pueden relacionarse con uno completo.

Un aviso: esto es con tablas MyIsam

Suerte

Última edición por jurena; 21/08/2008 a las 15:54
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 22:58.