viernes, enero 30, 2009

Groovy - Referencia #10

Heredocs

Otra de las características poderosas que nos ofrece Groovy son los Heredocs. Con ellos hacer cadenas de dos o más línea, sin necesidad de utilizar caracteres de escape, de hecho podríamos verlo como el <pre> de HTML donde se respeta los caracteres a como sean puestos, espacios, tabs, etc.

Para usarlos simplemente indicamos tres comas dobles o simples, seguidas y tres mas para cerrar la cadena.

Veamos un ejemplo:


void heredocs () {

println("\nHeredocs")
(1..3).each { print "*** " }
println("")

String s = """ This a is very big and
multi line string
"You don't need escape characters", really cool
"""

print s
} // heredocs


Heredocs
*** *** ***

This a is very big and
multi line string
"You don't need escape characters", really cool

Como se puede apreciar, inclusive los tabs que se utilizan para la indentación son incluidos.

Groovy - Referencia #9

Cadenas en comillas simples o dobles

De forma similar a Php, Groovy permite utilizar comillas dobles o comillas simples para definir cadenas, veamos algunos ejemplos:


void embeddedQuotes () {

println("\nEmbedded quotes")
(1..3).each { print "*** " }
println("")

def string1 = 'My name is "Jon"'
def string2 = "My name is 'Jon'"
def string3 = "My name is \"Jon\""

print string1 + " " + string2 + " " + string3
} // embeddedQuotes.


salida
Embedded quotes
*** *** ***
My name is "Jon" My name is 'Jon' My name is "Jon"

Groovy - Referencia #8

Condiciones de verdad / Eval Truth

Parecido a como funciona en JavaScript, Php e inclusive C++, las instrucciones condicionales no solo funcionan con valores booleanos, que es el caso de Java, existen varios otras equivalencias:

null -> false
no null -> true


cadena nula o vacía ->false
cadena no nula o vacía -> true

valor numérico 0 ->false
valor numérico no 0, como -1,1, etc -> true

coleccion vacía o nula ->false
coleccion no vacía o nula -> true

Ejemplo:
void evalTruth () {

println("\nCondicional statements - truth")
(1..3).each { print "*** " }
println("")

if (1) {

println "the value 1 (not zero) is true"
}

if (!null) {

println "the not null value is true"
}

if ("Jsanca") {

println "the not empty string is true"
}
} // evalTruth.

Resultado:

Condicional statements - truth
*** *** ***
the value 1 (not zero) is true
the not null value is true
the not empty string is true

Groovy - Referencia #7

Groovy - Auto Boxing

El auto boxing en Java no es realmente soportado de forma nativa, el auto boxing introducido en Java 5 en realidad es un workaround que utiliza un precompilador para hacer el casteo a objetos por nosotros, por ejemplo si hacemos la siguiente sentencia:


List&t;Integer> list = new ArrayList &t;Integer> ();

list.add (1);
int i = list.get(0);

Eso esto traducido por el precompilador de Java 5 como:

list.add(new Integer(1));
int i = (Integer)list.get(0);

En Groovy, todo objeto nativo es realmente un objeto y se trata como tal, veamos un ejemplo:

void autoboxing () {

println("\nFull object primitives - autoboxing")
(1..3).each { print "*** " }
println("")

def i = 2 // define an integer
println i.class
println i.abs()
def d = 2.2
println d.class
} // autoboxing

Salida:
Full object primitives - autoboxing
*** *** ***
class java.lang.Integer
2
class java.math.BigDecimal


Párrafo aparte, si alguno se pregunta porque en Java no todo es un objeto y hay una clara diferencia entre objetos primitivos y Objetos, inclusive en el pase por parametros, como se a comentado en post pasados. Contrario a Groovy o el mismo .Net, los ingenieros de Sun alegan que en el momento de hacer el lenguaje la decisión sonaba coherente por un asunto de perfomance, pues lo objetos se comportan de una forma mas pesada que un simple dato primitivo, cosa que creo ya no aplica y por eso lenguajes mas modernos, que sin lugar a duda se basan en Java así como Java se baso en C++, evitan ese error de diseño.

Groovy - Referencia #6

Safe dereferencing

Esta es una de las características que veo como mis favoritas en Groovy y valga mencionar, es muy poderosa.
El Safe Dereferencing, proporciona una sintaxis muy reducida para acceder a objetos compuestos (Composite).

Para contextualizar, si en Java tenemos un Objeto, Persona y dentro de este tenemos una composición Address y dentro de esta State:

clas State {

String name = "NY"
String detail = "NewYork"
}

class Address {

State state = null
String street
....
}

class Persona {

// ...
Address address = null
}

Si deseamos obtener el atributo "name" del objeto State, deberíamos hacer algo como así, para evitarnos NullPointerException's

String stateName = null;
if (null != persona) {

if (null != persona.getAddress()) {

if (null != persona.getAddress().getState()) {

stateName = persona.getAddress().getState().getName();


En Groovy solo debemos hacer:

stateName = persona?,address?.state?.name

En caso que algunos de los objetos sea nulo, stateName, se le asignará null.


Un ejemplo:

void safeDereferencing () {

println("\nSafe Dereferencing")
(1..3).each { print "*** " }
println("")

def name = "Jon";
println name.size()

name = null
// name.size() dispararía un NullPointerException
// pero si uso dereference =>

// si es nulo name, devuelve null, si no devuelve el tamaño del String.
println name?.size()
} // safeDereferencing.

Salida
Safe Dereferencing
*** *** ***
3
null

Groovy - Referencia #5

Manejo de excepciones

En Java existen dos tipos de excepciones, Exception y RuntimeException, la diferencia fundamental entre ambas, es que la primera necesita ser cachada y declarada en los métodos, la segunda no, lo cual a veces hace que nuestro métodos tengas muchas excepciones declaradas después del throws, sin embargo en Groovy todas las excepciones se manejan como Runtime, inclusive las que no lo son en Java, por ejemplo cualquier excepción IOException, no debe ser cachada ni declarada y así el resto. Muy parecido a como funcionan en .Net.

Vamos algunos ejemplos para apreciar las diferencias:

void openFileInGroovyStyle () {

println("\nException handling")
(1..3).each { print "*** " }
println("")

// No necesita ni hacer the throws en el método, o el try/catch
def reader = new FileReader ("file.txt");
}

En Java:
void openFileInJavaStyle () throws IOException {

new FileReader ("file.txt");
}

o también:

void openFileInJavaStyle () {

try {
new FileReader ("file.txt");
} catch (IOException e) {

// ...
}
}

Pienso que a veces es importante la posibilidad de exponer ciertas excepciones, sin embargo me gusta que las excepciones Java sean Runtime en Groovy, aunque me gustaría que se pudieran declarar de forma optativa algunas en la firma del método.
Una nota al pie, he encontrado algunos problemas con las excepciones, pues algunas no son cachadas en el "catch", fue reportado como un error en el Jira de Groovy, así que proba antes de solar a producción.

Groovy - Referencia #4

Duck Typing

Una característica muy propia de un lenguaje dinámico es el "duck typing", Groovy nos da soporte intentando adivinar el tipo que instanciamos.
A continuación un ejemplo:

void duckTyping () {

def duckString
String otherString
println("\nDuck Typing")
(1..3).each { print "*** " }
println("")
duckString = "Hello"
otherString = "Hello"

println (duckString.class); // duckString.getClass()
println (duckString.class == otherString.class);
// duckString.class.equal(otherString.class)
} // duckTyping.


La salida de este ejemplo es:
Duck Typing
*** *** ***
class java.lang.String
true

Aprecie que la clase de la variable "duckString" es interpretada por Groovy como un String y cuando lo comparamos con una variable tipada, vemos que es del mismo tipo (java.lang.String).

Vale la pena indicar, que el "duck typing", es opcional, es decir puede indicar o no el tipo, particularmente cuando utilizamos IDEs, el indicar el tipo proporciona mas facilidad a la hora de usar el intelligence.

Groovy - Referencia #3

Instrucción opcional "return"

String optionalReturnStatement () {

println("\nOptional return")
(1..3).each { print "*** " }
println("")
def message = "Hello All"

message += "!";
} // optionalReturnStatement.

Si esta función es invocada como

println optionalReturnStatement()

Retornará el valor de "message"

Como ves, el ultimo parametro utilizada es el que se retorna en Groovy, exactamente igual que en lenguajes como Perl.

Groovy - Referencia #2

El operador ;

Este operador, es opcional, solo se ocupa para dividir dos o mas sentencias en una línea.

class GroovyExample {

def myMessage = "";

void semiColons () {

println("\nSemi colons")
(1..3).each { print "*** " }
println("")
this.myMessage = "Hello" // no needs ; 1) optional ;
this.myMessage += "guys"; this.myMessage += "!"; // use el ; para separar sentencias

println this.myMessage // Los parentesis son opcionales para el println
} // semiColons.

}

La primera línea nos muestra la versión reducida para Groovy del System.out.println
La siguiente línea es un rango que imprime de 1 a 3 la cadena "***", su explicación sera tomada en cuenta mas adelante
Las siguientes lineas muestran como vamos concatenando mensajes a la cadena, observe el uso del ";" para dividir la cadena.


Salida

Semi colons
*** *** ***
Hello guys!

jueves, enero 29, 2009

Groovy - Referencia #1


Como anda todo Bloggers,

Introducción
A continuación inicio un nuevo esfuerzo en el blog, esta vez le toca el turno a Groovy.
El presente y los siguientes artículos no pretenden ser una guía detallada, todo lo contrario, este y el resto, pretenden ser una guía de referencia para programadores principalmente en Java, que deseen una rápida introducción al lenguaje.

Que es Groovy?
Groovy es un lenguaje del tipo Scripting y de naturaleza dinámico, que corre en la Maquina Virtual de Java, esta característica proporciona según los creadores le permite hasta un 99.9% de compatibilidad con las clases Java existentes.
En cuando a las características de dinamismo y scripting, podemos decir que Groovy es dinámico, el mismo cuenta con una implementación de ClassLoader que carga un script y lo compila a bytecode como una clase dentro del VM, lo que nos permite hacer cambios en caliente en el código y ver los resultados de forma inmediata, sin necesidad de compilar y deployar de nuevo, evitando bajadas y resubidas del servidor, etc, justo como lo hace Php.

La naturaleza Scripting permite picar código a una velocidad algo mayor que hacerlo en Java, con resultados equivalentes, su sintaxis como veremos es mas permisiva, dinámica y ágil, además la mayoría de los framework's Groovy se basan en el principio de "convención contra configuración", lo que ahorra tiempo en configuración.
Solo para poner un pequeño ejemplo acerca de la compatibilidad Java; si tomas una clase tuya, con extensión ".java" y la renombras a ".groovy", funciona como una clase Java, pero proporcionándole las características dinamicas de Groovy. Las características Scripting de Groovy son opcionales y se pueden ir integrando progresivamente en una clase Java existente. Algunas de las nuevas prestaciones que podemos recalcar en groovy son: duck typing, el tipado de los objetos es opcional (justo como ActionScript), sobrecarga de operadores, closures; tanto una cantidad de closures ya listos, como la posibilidad de definir nuevos, soporte nativo para XML, entre otros.

Como podrás ver Groovy nos reduce mucho el tiempo de trabajo al crear clases Java de forma dinámica, sin embargo debo recalcar que esta ganancia en el tiempo de desarrollo se ve afectada en dos sentidos, el primero de ellos es la velocidad, como al inicio se realizaban comparaciones entre Java y C++, la diferencia entre Groovy y Java yace en la misma naturaleza. También encontramos otro problema a la trabajar con un IDE, pues la agilidad de los mismos para inferir el "intelligence" no es la misma que Java o algún otro lenguaje tipado.

Otras alternativas a Groovy?

Existen otras alternativas, tales como; Ruby/JRuby, Phyton/Jython e inclusive recientemente Php, sin embargo Ruby no correo directamente en la maquina virtual de Java, si no que lo hace a través de un interprete JRuby, de forma idéntica Jython, lo que nos permite tomar scripts de estos lenguajes y meterlos como una clase en la VM para ser reutilizados, sin embargo el mayor problema con este enfoque es el siguiente:

Imaginese que estamos utilizando la versión 1.1 de Ruby y sale la versión 1.5, para utilizar las nuevas características que pudiera incluir la versión 1.5, tenemos que esperar a que el interprete (JRuby) puede incorporar estas nuevas características, cosas que no pasa con Groovy, pues el lenguaje corre y se fusiona directamente con Java y su VM

+ Info en:
http://groovy.codehaus.org/

lunes, enero 26, 2009

Pobreza democrática, globalización de las consecuencias

Un 2009 que nos abre las puertas con un crisis económica que golpea al globo entero, records en el precio del crudo, productos de consumo entre otro factores. Reflexiono y pienso, 12000000 millones de dolares para salvar un país, definitivamente la riqueza se encuentra mal distribuida y la pobreza se ha democratizado a lo largo del mundo, especialmente en países Africanos y algunos Asiáticos como ciertos sectores de China, sin olvidar nuestra América Latina, piensalo, si ese dinero fuera repartido por iguales, no solo la pobreza seria cosa del pasado, si no también todos seriamos multimillonarios.

Esta crisis tiene su raíz supuestamente en la crisis inmobiliaria que afecto a U.S.A, donde los bancos hace mas de dos años vienen prestando dinero, sin evaluar la capacidad de pago de los beneficiarios, algo solo creíble, solo porque paso. Algunas compañias que se declaran en quiebra cabe recalcar, ya venían sufriendo un déficit negativo y con esta crisis resulto ser el golpe de gracia, Circus City, la industria automovilistica, etc, tenian historiales de bajos rendimientos, mucho tiempo atrás.

Me resulta curioso que algunas personas, cargan un banner cuya inscripción dice algo como: "La crisis es de ellos, que la paguen ellos", pero la globalización de las consecuencias pone mas que evidente, que la riqueza solo recae en unos pocos y una vez mas, la pobreza y sus consecuencias se ven reflejados en todo el mundo, inclusive las supuestas potencias no escapan a las consecuencias de haber abierto la caja de pandora.

Quiero concluir dejando esta reflexión, si hoy una crisis de un país poderoso en un mundo GLOBALIZADO, es capaz de propagarse de forma casi instantánea por todo el mundo, que pasaría si una potencia crea una guerra o le declara la guerra a otra potencia, acaso vamos a tener que sufrir los embates de las decisiones de otros por mas nefastas que estas nos parezcan, siempre vamos ser la presa esperando ser degollada por el tigre sediento de mas, o vamos a estar esperando dar pena o lastima, para que otros se apiaden de nosotros!

Crisis, en el sabio Chino, es una palabra ambivalente, la cual significa: oportunidad o peligro, depende de nosotros que sentido le demos a esta.

Chau!

viernes, enero 23, 2009

China - Tori Amos

Esta canción simplemente me fascina, es como para ponerse melancólico y por que no, una mariqueada; no solo por tonada de la canción, si no también por la letra, les recomiendo esta versión en vivo, o bien ver el vídeo!

Amos muy ingeniosamente trata de una metáfora entre el país de China y la porcelana (ambas cosas en ingles son lo mismo, es decir que se utiliza tanto China, para referirse al país como para la porcelana, proveniente de este lejano lugar), la relación la hace con la pareja, melancólicamente ella habla de como una relación se aleja poco a poco, para ir quedado en el recuerdo
"I can feel the distance getting close"

En mi humilde opinión, una obra maestra, un gran arte musical, Tori de lo mejor.

"China"

All the way to New York
I can feel the distance getting close
You're right next to me
But I need an airplane
I can feel the distance as you breathe
Sometimes I think you want me to touch you
How can I when you build the great wall around you
In your eyes I saw the future
Together you just look away in the distance

China decorates our table
Funny how the cracks don't seem to show
Pour the wine dear
You say we'll take a holiday
But we never can agree on where to go

Sometimes I think you want me to touch you
How can I when you build the great wall around you
In your eyes I saw the future
Together you just look away in the distance

China all the way to New York
Maybe you got lost in Mexico
You're right next to me
I think that you can hear me
Funny how the distance
Learns to grow

Sometimes I think you want me to touch you
How can I when you build the great wall around you
In your eyes I saw the future
Together you just look away in the distance

I can feel the distance
I can feel the distance
I can feel the distance getting close

Tori Amos - China

Recuento de los daños - 2008 / 2000 y nueve nuevas esperanzas por venir

Bonjour,

Queda atrás un año mas, en este ir y venir, el 2009 ha iniciado ya y la verdad lo veo con mucha esperanza y optimismo y espero que todo pinte mejor que hasta ahora para todos; en mi caso personal, realmente no me puedo quejar del todo, tengo buena salud, trabajo, he estado leyendo y aprendiendo mucho, gente con quien compartir y querer, la gente que quiero esta bien (excepto un par de amigos que nunca faltan en mi suplicas) y mi economía al salir de deudas se vuelve cada vez más estable, lo que me quita gran peso de encima, el 2009 me liberó de dos largas deudas de encima (para meterme en otra seguro, pero esa es la vida del obrero), sin embargo tengo algunas espinillas en la espalda, a causa de algunas situaciones en mi laburo, ya te comentó:

El año pasado mi manager, me dijo que tenía que tomar vacaciones urgentes porque tenia un sobre exceso de días libres, alrededor de 20 días; como plan para tomarlas, decidí ausentarme los lunes y a final de año tome algunos días, que en realidad era mi plan original, ahora llego este año con la hermosa noticia que estoy en números rojos, para mi sorpresa en vez de tener 9 días libres debo un día, INCREIBLE; pues o mi manager cometió un error o HR cometió un error y mi manager no corroboro, o algo por el estilo, el asunto es que tome mis vacaciones de una forma absurda, en realidad hubiera preferido tomar vacaciones en algún momento de mayor estabilidad económica, para viajar o hacer algo mas productivo que solo quedarme en casa.

Mi segundo punto es el ventiunico aumento anual, el pasado 15 de enero del actual año, cumplí un año mas laburando en la compañía, por lo que, como es común hacen el aumento respectivo, yo entiendo que estamos en periodo de crisis y todo, pero la gente que cumplió el año en diciembre si le hicieron el famoso aumento, sin embargo tuvieron la grandiosa idea que a partir del 1 de Enero, 2009, el proceso de aumentos, seria mas burocrático, por lo que si tengo suerte, iré viendo algo mas de dinero por ahí de Mayo :(

Para cerrar con broche de oro, el equipo donde trabajo paro el desarrollo y hemos estado 4 meses haciendo bugfixing todo este tiempo, no todo ha sido malo, sin embargo ese dinámica de trabajo, tiende a ser tediosa, cansada y aburrida a la larga.

Añadido a esto, debo recalcar que tengo un gran equipo, 2 + 3 personas que estimo mucho y realmente hacen muy divertido y ameno el trabajo, realmente representa para mi un punto alto en el laburo diario, así como otros socios en la compañía con los cuales tengo proyectos paralelos.

También he estado dando capacitación a diferentes grupos en mi compañía, asunto que me gusta bastante y por que no, quizá en un futuro lo tome mas en serio, quizá opte por una licenciatura en docencia o algo por el estilo.

Como metas para este año, pues aprender todo lo que pueda de informática, tengo una pila de libros por leer y re-leer, volver a la UNED y avanzar en mi carrera, tomar clases de batería (drums) y quizás tomar algunos cursos de cocina o fotografía, ahí todo lo que sea aprender es bueno.

También me gustaría ponerme mas en forma y retomar el ritmo en el atletismo, por supuesto seguir manteniendo una buena relación con las personas allegadas que quiero y estimo.

Un año termina y otro llega, tener el optimismo a full y seguir en pie de lucha es mi consigna, la mejor de las suertes y mis mejores deseos a todos lo que leen mi blog, pronto publicare algunos hilos acerca de Groovy y algunos otros temas relacionados con la programación orientada a objetos, quizá también incluya algo de lo aprendido del libro de MySQL que esto tratando de leer ultimamente.

2009 un gran año!!!

A très bientôt, mes meilleurs voeux,
J

jueves, enero 22, 2009

Wikipedia data base schema


Algo interesante como caso de estudio, especialmente para los que estén cursando bases de datos, el esquema de la Wikipedia esta disponible para hechar un ojo.
A simple vista, me gusta mucho la simplicidad y lo bien documentada que se encuentra, vale la pena dedicarle un tiempo.



http://www.wikipedia.org/

martes, enero 20, 2009

La herejia de los generics

Como parte de las novedades incluidas en Java 5, contamos con los generic, genéricos emplantillados, que permiten realizar el tipado de métodos, colecciones, etc.
Sin embargo, me parece ridículo que algo tan básico como el polimorfismo, no este soportado en esta pobre implementación, veamos un ejemplo para entender mi argumento de mejor manera:

Consideremos las clases:

public class SuperClass {

}

public class SubClass extends SuperClass {

}

Y consideremos las clase generic, MyList que extiende de ArrayList, convenientemente emplantillada para limitar el acceso a solo objetos que extiendan de SuperClass:

public class MyList<t extends SuperClass> extends ArrayList<t> {


private static final long serialVersionUID = -2733586086914849461L;

public MyList() {
}

public MyList(int initialCapacity) {
super(initialCapacity);
}

public MyList(Collection c) {
super(c);
}

}

Hasta aquí, todo de maravilla, ahora intentemos utilizar esta nueva clase:

private static void getList () {

MyList<subclass> list1 = new MyList<subclass> (); // valido
MyList<superclass> list2 = new MyList<superclass> (); // valido
MyList<superclass> list3 = new MyList<subclass> (); // invalido
}

Como ven cuando el tipo y la instancia de la colección, son del mismo tipo de objeto, los genéricos funcionan, sin embargo cuando se intenta hacer que las instancias de la implementación de la colección sean genéricos, nos damos cuenta que no lo soportan, lo cual limita mucho el poder de los genéricos en Java.

No todo en el lado de la luz, es hermoso....

Beardyman - DJ human beatboxing

Entre las cosas geniales y rajadas, que he logrado ver ultimamente, se encuentra este DJ, Beardyman, graba y mezcla su voz, o mas bien, su beatboxing, en vivo.
La combinación y mezcla progresiva de los sonidos emitidos por su boca, sin simplemente increibles, algunos videos:


Massive Attack - Teardrop

Live Looping [Part One]

Live Looping [Part Two]

Enjoy!

martes, enero 06, 2009

Corriendo hilos en paralelo

Este corte de código, muestra como crear y disparar un grupo de hilos, en paralelo.
Usa la conveniente sintaxis de "String...", para recibir de 0 a N parametros, implementa, mediante clases anonimas los objetos Runnable y utiliza el método join, para bloquear el hilo actual, hasta que el hilo invocado termine su ejecución, así se asegura que todos los hilos terminen su ejecución antes de salir del método runInParallel.

public static void main(String[] args) {

runInParallelExample();
}

public static void runInParallelExample () {

runInParallel(true,
new Runnable () {
@Override
public void run() {

System.out.println("Happy");
}
},
new Runnable () {
@Override
public void run() {

System.out.println("New");
}
},
new Runnable () {
@Override
public void run() {

System.out.println("Year");
}
},
new Runnable () {
@Override
public void run() {

System.out.println("All");
}
}
);
}

/**
* Ejecuta todos los hilos en paralelo
*
* @param wait
* true si desea que el metodo espere hasta que se ejecuten todos los hilos
* @param runnables
* Conjunto de objetos runnables
*/
public static void runInParallel(boolean wait, Runnable... runnables) {

List threads = null;
Thread thread = null;

try {

// Creo los objetos
threads = new ArrayList();

// Creo la lista con los hilos y los ejecuto
for (Runnable r : runnables) {

thread = new Thread(r);
threads.add(thread);
thread.start();
}

// If desea que el metodo espere
if (wait) {
for (Thread t : threads) {
t.join();
}
}
} catch (Exception e) {

/** Catch or throws the error */
}
} // runInParallel.

lunes, enero 05, 2009

Normalizar o no normalizar, he ahí el dilema

Vía debugmodeon llego a un articulo que habla acerca de si se debe normalizar o no, aquí mis impresiones al respecto.

Creo que la normalización le proporciona elegancia y cohesión a nuestras entidades.
Resguarda la integridad de las entidades y proporciona seguridad a la hora de actualizar o eliminar entidades.

Pero que pasa con el bendito asunto de los joins, si una tabla la descompongo en 5 y luego tengo que hacer 3 consultas con 3 joins cada una, en vez de solo una pinche consulta, algo se nos esta complicando, no?
Una solución comúnmente adoptada por los DBA's es crear vistas que una virtualmente esas entidades, para realizar las consultas, pero lo malo es que estas vistas decrementan el desempeño del servidor, pues son mas pesadas tanto en memoria como en disco y su gestión puede ser un poco dolor de cabeza. (que pasa si agrego o elimino campos o entidades?)

En la minería de datos o en entornos distribuidos donde tengo una tabla en una base de datos y alguna tabla relacionada en otra base de datos distinta en un diferente servidor, resulta inútil o tan siquiera posible realizar la normalización.

Parece que en grandes cantidades de datos o en altísima recurrencia, desnormalizar un poco, puede ser útil.

A mi me parece que la normalización va de la mano con el sentido común, quiero decir, no todas las bases de datos tienen que ir hasta la ultima norma, a veces con cumplir 1 o 2, pueden obtenerse beneficios de ambos enfoques.

Saludos y por cierto feliz año 2009