Archive for 14 febrero 2017

Motivos para seleccionar PostgreSQL en lugar de MySQL

febrero 14, 2017

MySQL es un RDBMS muy popular y como seres humanos tendemos a aplicar la política del menor esfuerzo, así que cuando se requiere desarrollar una aplicación en donde es necesario utilizar una base de datos, la mayoría piensa inmediatamente en MySQL.

Yo siempre he preferido PostgreSQL sobre MySQL, a continuación expongo algunos de los motivos

La configuración por defecto de PostgreSQL respeta todas las restricciones y validaciones que se indican en el diseño de la base de datos, MySQL no, uno debe configurar el servidor en modo “Strict SQL”, de lo contrario, se insertarán valores “ajustados”.

Por ejemplo, no importa si una tabla se creó con un campo numérico con una restricción de NOT NULL, la configuración por defecto de MySQL permitirá insertar registros en esa tabla aún cuando no se especifique un valor para ese campo, almacenando un cero como valor. Aún seleccionando el modo “Strict SQL”, MySQL no soporta check constraints.

El único de los nueve motores de almacenamiento de MySQL que soporta integridad referencial y transacciones es InnoDB (MyISAM no soporta integridad referencial ni transacciones), PostgreSQL sólo trae un motor de almacenamiento y soporta integridad referencial y transacciones.

PostgreSQL cumple con ACID (Atomicity, Consistency, Isolation, Durability) al 100%, MySQL no, el mismo manual de MySQL no indica “full ACID complaint” sólo dice “follows ACID”

PostgreSQL soporta más tipos de datos y estructuras que MySQL

El tamaño máximo por renglón en una tabla de PostgreSQL es de 1.6TB mientras que en MySQL es de 65,535 bytes

Algunas cosas que MySQL no soporta y PostgreSQL si:

  • Full Outer Joins

  • Window Functions

  • CTE (Common Table Expressions) para SQL recursivo

  • Table functions

  • JSON (JavaScript Object Notation)

Para extender el servidor, MySQL cuanta con un plugin para C/C++, PostgreSQL soporta C/C++, Java, .Net, Perl, Python, Ruby, Tcl, ODBC y otros más

PostgreSQL es mejor que MySQL en cuanto a consistencia de datos, estabilidad, mantenimiento y recuperación de datos.

Algunas lecturas recomendadas:

http://www.slideshare.net/anandology/ten-reasons-to-prefer-postgresql-to-mysql

https://www.compose.io/articles/what-postgresql-has-over-other-open-source-sql-databases/

Anuncios

Procesamiento de archivos con Ruby

febrero 1, 2017

En este post voy a mostrar un ejemplo de procesamiento de archivos con Ruby haciendo referencia a un caso real que se me presentó.

Se tiene un archivo csv llamado datos_clientes.csv y un archivo txt llamado solo_correos.txt; el archivo csv contiene una lista de clientes con datos como nombre, correo electrónico, teléfono, etc. y el archivo txt sólo contiene direcciones de correo electrónico.

El contenido del archivo datos_clientes.csv puede ser algo como esto:

NAME,E-MAIL
SALOMON RINCON TORRES,rtmex@yahoo.com
TOP SYSTEMS S.A DE C.V.,ventas@topsystems.com.mx
SALOMON RINCON TORRES,salomonrincon@softwarelibrepuebla.org
JOHN DOE,ejemplo@gmail.com

y el contenido del archivo solo_correos.txt podría parecerse a esto:

ventas@topsystems.com.mx
ejemplo@gmail.com
rtmex@yahoo.com

Imaginemos que ambos registros tienen cientos o miles de líneas

El objetivo es leer cada uno de los correos del archivo solo_correos.txt y buscarlo en el archivo datos_clientes.csv, si se encuentra, guardar el correo y el nombre del cliente al que pertenece dicho correo en un nuevo archivo csv (en este caso el archivo se llamará resultado.csv).

Aquí el código

require 'csv'

# Declara el encabezado para el archivo que se creará
encabezado = ['correo', 'nombre']
correo = nil
nombre = nil
num_linea = 0

CSV.open('resultado.csv', 'w', write_headers: true, headers: encabezado) do |archivo_nuevo|
    # Abre el archivo que contiene cada una de las líneas que se van a buscar en otro archivo
    File.open("solo_correos.txt") do |archivo|
         archivo.each do |linea|
             num_linea += 1
             puts "Linea #{num_linea} del archivo solo_correoa.txt = "+linea.strip
             # Abre un archivo delimitado por comas
             # En la segunda columna de este archivo, se busca la línea que se leyó del primer archivo
             CSV.foreach('datos_clientes.csv', headers: true) do |linea2|
                 if linea2[1].strip == linea.strip
                    puts "El correo "+linea.strip+" pertenece a "+linea2[0].strip
                    correo = linea.strip
                    nombre = linea2[0].strip
                    archivo_nuevo << [correo, nombre]
                    break
                 end
             end
         end
    end
end

El programa va mostrando el número de línea y su contenido conforme va procesando el archivo solo_correos.txt. Cada vez que en el archivo datos_clientes.csv encuentra el correo que leyó del archivo solo_correos.txt, muestra a que cliente pertenece dicho correo.

Lo que iría mostrando el programa mientras va procesando el archivo solo_correos.txt sería algo como esto:

Linea 3 del archivo solo_correos.txt = rtmex@yahoo.com
El correo rtmex@yahoo.com pertenece a SALOMON RINCON TORRES

Cuando el programa termina, tenemos un archivo csv llamado resultado.csv con 2 columnas, la primera contiene el correo electrónico y la segunda el nombre del cliente al que pertenece dicho correo.