Archive for May 13th, 2007

Alguien que es como mi madre! …

Sunday, May 13th, 2007

Como buen regalo de día de las madres…

Como confirmación de ser la gran doña del Software Libre, algún ser solitario decidió buscar en google "Alguien que es como mi madre" …

Busqueda en google

Y quien mas puede ser como tu madre que …

"Phenobarbital con soda! …"

Aqui la confirmación de la búsqueda …

Gracias Google por ese hermoso regalo de día de las madres!! …

xD

Experimento con datos: migrando a postgreSQL (tercera parte)

Sunday, May 13th, 2007

Migrar datos desde mySQL hasta postgreSQL no es tan dificil, es sumamente facil; lo engorroso es en la DDL (data de definición), los CREATE TABLE son algo distintos en postgreSQL que en mysql, pero eso es algo que podemos solventar.

Migración de CNE desde mySQL hasta postgreSQL:
conectamos a mysql:
>mysql -u root -p
ejecutamos la conversion de sintaxis a ANSI postgresql:
mysql>set sql_mode = ‘ANSI,ANSI_QUOTES,IGNORE_SPACE,NO_FIELD_OPTIONS,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_ZERO_DATE,PIPES_AS_CONCAT,REAL_AS_FLOAT,STRICT_ALL_TABLES’;
Query OK, 0 rows affected (0.00 sec)

usamos la base de datos CNE y consultamos la estructura de cada tabla:
mysql>use cne

mysql>show create table maisanta;

CREATE TABLE "maisanta" (
  "cedula" int(10) NOT NULL,
  "nacionalidad" char(1) NOT NULL,
  "nombre" varchar(128) NOT NULL,
  "cod_centro" int(10) NOT NULL,
  "direccion" text,
  "fecha_nac" date default NULL,
  "opositor" tinyint(1) unsigned NOT NULL default ‘0′,
  "telefono" varchar(50) default NULL,
  "abstencion" tinyint(1) unsigned NOT NULL default ‘0′,
  "firma_valida" tinyint(1) unsigned NOT NULL default ‘0′,
  "firma_rechazada" tinyint(1) unsigned NOT NULL default ‘0′,
  "fallecido" tinyint(1) unsigned NOT NULL default ‘0′,
  "mision_patriota" tinyint(1) unsigned NOT NULL default ‘0′,
  "mision_ribas" tinyint(1) unsigned NOT NULL default ‘0′,
  "mision_vuelvan" tinyint(1) unsigned NOT NULL default ‘0′,
  "contra_opo" tinyint(1) unsigned NOT NULL default ‘0′,
  PRIMARY KEY  ("cedula","nacionalidad"),
  KEY "idx_cedula" ("cedula")
)

debemos convertir todos los campos ANSI a campos PostgreSQL (si hubieran auto_increment, pasarlos a serial, los tinyint(1) a int2 y crear un constraint con cedula.

asi queda en postgresql:
tabla maisanta:
CREATE TABLE maisanta
(
  cedula int4 NOT NULL,
  nacionalidad char(1) NOT NULL,
  nombre varchar(128) NOT NULL,
  cod_centro int4 NOT NULL,
  direccion text,
  fecha_nac date,
  opositor int2 NOT NULL DEFAULT 0::smallint,
  telefono varchar(50),
  abstencion int2 NOT NULL DEFAULT 0::smallint,
  firma_valida int2 NOT NULL DEFAULT 0::smallint,
  firma_rechazada int2 NOT NULL DEFAULT 0::smallint,
  fallecido int2 NOT NULL DEFAULT 0::smallint,
  mision_patriota int2 NOT NULL DEFAULT 0::smallint,
  mision_ribas int2 NOT NULL DEFAULT 0::smallint,
  mision_vuelvan int2 NOT NULL DEFAULT 0::smallint,
  contra_opo int2 NOT NULL DEFAULT 0::smallint,
  CONSTRAINT maisanta_pkey PRIMARY KEY (cedula, nacionalidad)
)

la tabla electores queda asi:
CREATE TABLE "electores" (
  "nacionalidad" char(1) NOT NULL default ‘V’,
  "cedula" integer NOT NULL default ‘0′,
  "nombre" varchar(128) default ”,
  "cod_elector" varchar(50) default ‘0′,
  "fecha_nac" varchar(25) default ”,
  PRIMARY KEY  ("nacionalidad","cedula"),
  UNIQUE ("nacionalidad","cedula")
)

Ahora tenemos ambas tablas (electores y maisanta) creadas e indexadas en postgreSQL y en mySQL.

Ahora toca exportar los datos:
>mysqldump -uroot -p -c –compatible=postgresql –skip-opt -t -n cne > cnedump.sql

Hay que tomar en cuenta que ambos comandos toman tiempo (bastante tiempo); estamos hablando que maisanta cuenta con 12 millones de registros y electores del cne cuenta con 16 millones de registros.

Como verán, podemos exportar los datos en una forma casi "compatible" con postgreSQL; posteriormente respaldamos estos datos en postgreSQL:
>psql -U postgres < cnedump.sql
y posteriormente ejecutar el VACUMM ANALIZE
>vacuumdb -a -z

Tambien es posible pasar directamente un backup a postgreSQL sin necesidad de un archivo intermedio usando pipes:
>mysqldump -uroot -p -c –compatible=postgresql –skip-opt -t -n cne | psql -U postgres cne

Ahora, contaremos con dos bases de datos de grandes dimensiones para hacer los benchmarks respectivos (a priori, por el volumen de los datos, apuesto por postgreSQL, pero pueden haber sorpresas).

Notas informativas: Los originales CSV del CNE vienen de una DB posiblemente MS SQL Server u Oracle, el charset es bastante extraño y tiende a corromper algunos registros cuando lo llevas a UTF-8 tanto en mySQL como en postgreSQL.  (nota: cuando aprenderan?).

A la hora de la publicación de este artìculo todavia se estaban pasando los 16 millones de registros a postgreSQL, cuando terminen, realizaré y publicaré la cuarta parte, respuestas de consultas y operaciones con los datos.

Espero termine hoy … :P

Experimento con datos: y ahi viene Maisanta! (segunda parte)

Sunday, May 13th, 2007

En uno de esos buhoneros especializados en IT del centro de caracas encontramos la DB maisanta; ella viene de un horrible DBF que ha sido llevado a la forma separada por comas (archivo CSV) y para cargarlo simplemente ejecutamos desde consola de mysql el siguiente comando:

>mysql -u root -p

y nos conectamos a la db CNE creada en el acpitulo 1:
mysql>use cne

crear la tabla maisanta:
mysql>CREATE TABLE `maisanta` (
  `cedula` int(10) NOT NULL,
  `nacionalidad` char(1) NOT NULL,
  `nombre` varchar(128) NOT NULL,
  `cod_centro` int(10) NOT NULL,
  `direccion` text,
  `fecha_nac` date default NULL,
  `opositor` tinyint(1) unsigned NOT NULL default ‘0′,
  `telefono` varchar(50) default NULL,
  `abstencion` tinyint(1) unsigned NOT NULL default ‘0′,
  `firma_valida` tinyint(1) unsigned NOT NULL default ‘0′,
  `firma_rechazada` tinyint(1) unsigned NOT NULL default ‘0′,
  `fallecido` tinyint(1) unsigned NOT NULL default ‘0′,
  `mision_patriota` tinyint(1) unsigned NOT NULL default ‘0′,
  `mision_ribas` tinyint(1) unsigned NOT NULL default ‘0′,
  `mision_vuelvan` tinyint(1) unsigned NOT NULL default ‘0′,
  `contra_opo` tinyint(1) unsigned NOT NULL default ‘0′,
  PRIMARY KEY  (`cedula`,`nacionalidad`),
  KEY `idx_cedula` (`cedula`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=1;

y posteriormente cargamos la data:
mysql>LOAD DATA LOCAL INFILE ‘/home/webapp/repdbf.txt’
IGNORE INTO TABLE maisanta FIELDS TERMINATED BY ‘;’
        ENCLOSED BY ‘\”
LINES TERMINATED BY ‘\n’ STARTING BY ”
(cedula, nacionalidad, nombre, cod_centro, direccion, @fecha_tmp, opositor, telefono, abstencion, firma_valida, firma_rechazada, fallecido, mision_patriota, mision_ribas, mision_vuelvan, contra_opo)
SET fecha_nac = DATE_FORMAT(@fecha_tmp, ‘%Y-%m-%d’);

Observen 2 cosas; primero, tarda un buen rato (aprox. unos 10 minutos si tu mysql está bien "tuneado"), lo otro, es que la fecha esta en formato latino (dia/mes/año) y no en formato ansi (año-mes-dia) vean que puedo adicionalmente pre-procesar los campos antes de ser insertados, en este caso, convertir el campo fecha_nacimiento a una forma ANSI.
ahora, probamos que la data ha cargado correctamente:
mysql> select count(cedula) from maisanta;
+—————+
| count(cedula) |
+—————+
|      12394109 |
+—————+

1 row in set (0.00 sec)

Si me faltó algun registro; bueno, cosas de andar convirtiendo desde esa horrible cosa que es JosPro (lease: Visual Publisher para Windows y compañia).

fijense que la tabla tiene una muy buena respuesta:
mysql> select nombre, fecha_nac from maisanta where cedula = 13264658 and nacionalidad = ‘V’;
+———————————+————+
| nombre                          | fecha_nac  |
+———————————+————+
| LARA GIMENEZ JESUS IGNACIO JOSE | 1978-10-23 |
+———————————+————+

1 row in set (0.09 sec)

Lo cual prueba que la indización se ejecutó correctamente, sino; ejecuten el myisamchk en la db:
>myisamchk -f -p /var/lib/mysql/data/cne/*.MYI

y todo listo.

Ahora, pasaremos todo esto a postgreSQL.