feb
13
2018

T-SQL Tuesday #99 – Grandes Debates : Unicode

tsql2sday150x150

 Esta publicación forma parte de T-SQL Tuesday, que es una fiesta de blog mensual el segundo martes de cada mes. Todos el mundo es bienvenido y tiene la oportunidad de escribir sobre SQL Server.

El anfitrión de este mes es Aaron Bertrand (B|T) y el tema puede elegirse entre contar algo que le apasiona fuera del mundo de SQL Server, o elegir entre su índice de malos hábitos, entre los que hay uno que especialmente me afecta en mi día a día.

 
Antecedentes

Tal como lo anuncia el título de la publicación, existe un debate continuo sobre el uso de UNICODE, y como cualquier otro debate, existen dos posiciones fuertemente enfrentadas, a favor y en contra de su uso.

Trataré de ser racional y tan solo dar algunos ejemplos de por qué es una mala idea usar indiscriminadamente los tipos de datos UNICODE, por si acaso.

 
Ejemplo 1, Códigos ISO

Obviamente, todo el mundo entenderá que estos códigos caen en el lado de estar 100% seguro de que nunca requerirán UNICODE.

Podemos tener aquí monedas, países, idiomas, etc., generalmente no son muy largos, normalmente dos o tres caracteres, según el código que usemos.

Pero como siempre, hay que pensar a lo grande, imagina que creas una tabla con países del mundo, unas 200 filas, ¿cuál es el problema? Bueno, si decides convertir el código de país en la clave principal, entonces ahí tienes tu problema.

En cada tabla donde creemos una clave externa para la tabla de países, (por ejemplo [dbo].[PhoneListing] que tiene 100 millones de filas) heredará esa columna, ahora ya se ve el problema, ¿verdad? En cifras aproximadas, 2 bytes * 100M = ~190MB de espacio extra desperdiciado en una sola tabla.

Pero no solo se malgasta espacio en disco, que la gente se puede pensar que es barato, está malgastando RAM cada vez que leemos una de esas páginas en la memoria, está en su registro de transacciones cada vez que lo actualizamos, incluso en su red si sucede que tiene AG o cualquier otro tipo de sincronización!!

 
Ejemplo 2, Fechas

Sí, lo habéis leído … Veo fechas almacenadas como NVARCHAR(10) y NCHAR(10) a diario, por favor no me preguntéis por qué.


Este caso es aún peor, porque DATE usa 3 bytes donde NCHAR(10) utiliza 20 bytes, así es damas y caballeros, necesitamos más de 6 veces el espacio para almacenar los mismos datos.

¡Pero espera! ¿Cómo podemos estar seguro de que esos diez caracteres son en realidad una fecha válida? No podemos, a menos que reinventemos la rueda y validemos que esas fechas son realmente válidas y paguemos la penalización de rendimiento al tener que hacerlo.

Usando el ejemplo anterior, este caso se vuelve aún mejor cuando multiplicas por dieciocho, 18 bytes * 100M = ~ 1.6GB Wow, ahora ya es cosa seria.

 
SQL Server 2016 SP1 al rescate

Pero no todo está perdido, porque si tienes la mala suerte de heredar un sistema que se implementaó esa manera y no hay posibilidad de cambiarlo, aún puedes hacer algo para sobrellevarlo y tratar de no malgastar tanto espacio.

Dije SQL Server 2016 SP1 por una razón, no porque lo que voy a contar no existiera antes, sino que esta es la versión cuando la funcionalidad se ha vuelto disponible para todas las ediciones de SQL Server y esta es, compresión de datos.

Hece tiempo escribí un blog post en el que detallo como pude ahorra un montón de espacio usando compresión de datos a nivel de filas.

Como ya mencioné en la publicación, la compresión a nivel de filas hará que los caracteres que no sean Unicode vuelvan a ocupar un byte. Por supuesto, pagaremos la penalización en el uso de la CPU, pero a veces vale la pena. Y ahora está alcance de todos el poder usarlo.

 
Literales Unicode

Esta es mi favorita. Recuerdo ese día que un desarrollador estaba realmente molesto porque sus datos estaban “corruptos” porque los campos en su tabla estaban llenos de signos de interrogación. 🙂

Algo como esto


DECLARE @Unicode_string NVARCHAR(50) = 'какво ще бъда?'

SELECT @Unicode_string AS Unicode_string

Todavía me río de esto, porque le hicimos escribir en un post-it y pegarlo en su monitor lo siguiente:

N”

Así que, al final, incluso si hemos previsto todo correctamente, nos podríamos enfrentarte al clásico layer 8 error.

 
Conclusión

Podemos ver que hay usos más que razonables para UNICODE, por eso existen, pero a veces son simplemente un no-no.

Este post ha sido mejor que ir al psicologo, ¡qué alivio!

Solo para terminar de agradecer a Aaron por organizar el evento de este mes y vosotros por leer.

Gracias.
 

2 comments
  1. Martin Guth dice:

    Great article…I really enjoyed reading.
    People can always come up with a “storage is cheap nowadays” answer. Whether this is correct or not most do not think about RAM (buffer pool) and if things go worse all these extra space tends to add up soon. Have a look at my contribution at http://www.martinguth.de/database-administration/why-i-chose-int-rather-than-bigint-for-id-columns/ … I also wrote about saving some space regarding ID columns.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *