{"id":534,"date":"2018-02-13T09:01:41","date_gmt":"2018-02-13T09:01:41","guid":{"rendered":"https:\/\/sqldoubleg.live-website.com\/?p=534"},"modified":"2022-12-25T10:13:04","modified_gmt":"2022-12-25T10:13:04","slug":"t-sql-tuesday-99-great-debates-unicode","status":"publish","type":"post","link":"https:\/\/www.sqldoubleg.com\/es\/2018\/02\/13\/t-sql-tuesday-99-great-debates-unicode\/","title":{"rendered":"T-SQL Tuesday #99 &#8211; Grandes Debates : Unicode"},"content":{"rendered":"<p>En esta publicaci\u00f3n, quiero compartir mi opini\u00f3n sobre el uso de tipos de datos UNICODE de forma predeterminada para cadenas almacenadas en SQL Server&nbsp;<a href=\"https:\/\/sqlblog.org\/2018\/02\/06\/t-sql-tuesday-99\" target=\"blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2016\/07\/tsql2sday150x150.jpg\" alt=\"tsql2sday150x150\" width=\"154\" height=\"154\" style=\"float:left;margin-right:7px\" \/><\/a><\/p>\n<p>&nbsp;Esta publicaci\u00f3n forma parte de <a href=\"http:\/\/sqlblog.com\/blogs\/adam_machanic\/archive\/2017\/01\/03\/t-sql-tuesday-rules-of-engagement.aspx\" target=\"_blank\" rel=\"noopener\">T-SQL Tuesday<\/a>, 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.<\/p>\n<p>El anfitri\u00f3n de este mes es Aaron Bertrand (<a href=\"http:\/\/sqlblog.com\/blogs\/aaron_bertrand\/\" target=\"_blank\" rel=\"noopener\">B<\/a>|<a href=\"https:\/\/twitter.com\/AaronBertrand\" target=\"_blank\" rel=\"noopener\">T<\/a>) y el tema puede elegirse entre contar algo que le apasiona fuera del mundo de SQL Server, o elegir entre su \u00edndice de malos h\u00e1bitos, entre los que hay uno que especialmente me afecta en mi d\u00eda a d\u00eda.<\/p>\n<p>&nbsp;<br \/>\n<strong>Antecedentes<\/strong><\/p>\n<p>Tal como lo anuncia el t\u00edtulo de la publicaci\u00f3n, 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.<\/p>\n<p>Tratar\u00e9 de ser racional y tan solo dar algunos ejemplos de por qu\u00e9 es una mala idea usar indiscriminadamente los tipos de datos UNICODE, por si acaso.<\/p>\n<p>&nbsp;<br \/>\n<strong>Ejemplo 1, C\u00f3digos ISO<\/strong><\/p>\n<p>Obviamente, todo el mundo entender\u00e1 que estos c\u00f3digos caen en el lado de estar 100% seguro de que nunca requerir\u00e1n UNICODE.<\/p>\n<p>Podemos tener aqu\u00ed monedas, pa\u00edses, idiomas, etc., generalmente no son muy largos, normalmente dos o tres caracteres, seg\u00fan el c\u00f3digo que usemos.<\/p>\n<p>Pero como siempre, hay que pensar a lo grande, imagina que creas una tabla con pa\u00edses del mundo, unas 200 filas, \u00bfcu\u00e1l es el problema? Bueno, si decides convertir el c\u00f3digo de pa\u00eds en la clave principal, entonces ah\u00ed tienes tu problema.<\/p>\n<p>En cada tabla donde creemos una clave externa para la tabla de pa\u00edses, (por ejemplo [dbo].[PhoneListing] que tiene 100 millones de filas) heredar\u00e1 esa columna, ahora ya se ve el problema, \u00bfverdad? En cifras aproximadas, 2 bytes * 100M = ~190MB de espacio extra desperdiciado en una sola tabla.<\/p>\n<p>Pero no solo se malgasta espacio en disco, que la gente se puede pensar que es barato, est\u00e1 malgastando RAM cada vez que leemos una de esas p\u00e1ginas en la memoria, est\u00e1 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\u00f3n!!<\/p>\n<p>&nbsp;<br \/>\n<strong>Ejemplo 2, Fechas<\/strong><\/p>\n<p>S\u00ed, lo hab\u00e9is le\u00eddo &#8230; Veo fechas almacenadas como NVARCHAR(10) y NCHAR(10) a diario, por favor no me pregunt\u00e9is por qu\u00e9.<\/p>\n<p> <a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2018\/02\/02_meme_dates_nvarchar.jpg\"><img decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2018\/02\/02_meme_dates_nvarchar.jpg\" alt=\"\" width=\"375\" class=\"alignright size-full wp-image-536\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/02_meme_dates_nvarchar.jpg 826w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/02_meme_dates_nvarchar-300x182.jpg 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/02_meme_dates_nvarchar-768x465.jpg 768w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/02_meme_dates_nvarchar-150x91.jpg 150w\" sizes=\"(max-width: 826px) 100vw, 826px\" \/><\/a><br \/>\nEste caso es a\u00fan peor, porque DATE usa 3 bytes donde NCHAR(10) utiliza 20 bytes, as\u00ed es damas y caballeros, necesitamos m\u00e1s de 6 veces el espacio para almacenar los mismos datos.<\/p>\n<p>\u00a1Pero espera! \u00bfC\u00f3mo podemos estar seguro de que esos diez caracteres son en realidad una fecha v\u00e1lida? No podemos, a menos que reinventemos la rueda y validemos que esas fechas son realmente v\u00e1lidas y paguemos la penalizaci\u00f3n de rendimiento al tener que hacerlo.<\/p>\n<p>Usando el ejemplo anterior, este caso se vuelve a\u00fan mejor cuando multiplicas por dieciocho, 18 bytes * 100M = ~ 1.6GB Wow, ahora ya es cosa seria.<\/p>\n<p>&nbsp;<br \/>\n<strong>SQL Server 2016 SP1 al rescate<\/strong><\/p>\n<p>Pero no todo est\u00e1 perdido, porque si tienes la mala suerte de heredar un sistema que se implementa\u00f3 esa manera y no hay posibilidad de cambiarlo, a\u00fan puedes hacer algo para sobrellevarlo y tratar de no malgastar tanto espacio.<\/p>\n<p>Dije SQL Server 2016 SP1 por una raz\u00f3n, no porque lo que voy a contar no existiera antes, sino que esta es la versi\u00f3n cuando <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/sql-server\/editions-and-components-of-sql-server-2016#RDBMSSP\" rel=\"noopener\" target=\"_blank\">la funcionalidad se ha vuelto disponible para todas las ediciones de SQL Server<\/a> y esta es, compresi\u00f3n de datos.<\/p>\n<p>Hece tiempo escrib\u00ed un <a href=\"https:\/\/sqldoubleg.live-website.com\/2016\/11\/03\/database-design-matters-real-world-scenario\/\" target=\"_blank\" rel=\"noopener\">blog post<\/a> en el que detallo como pude ahorra un mont\u00f3n de espacio usando compresi\u00f3n de datos a nivel de filas.<\/p>\n<p>Como ya mencion\u00e9 en la publicaci\u00f3n, la compresi\u00f3n a nivel de filas har\u00e1 que los caracteres que no sean Unicode vuelvan a ocupar un byte. Por supuesto, pagaremos la penalizaci\u00f3n en el uso de la CPU, pero a veces vale la pena. Y ahora est\u00e1 alcance de todos el poder usarlo.<\/p>\n<p>&nbsp;<br \/>\n<strong>Literales Unicode <\/strong><\/p>\n<p>Esta es mi favorita. Recuerdo ese d\u00eda que un desarrollador estaba realmente molesto porque sus datos estaban \u00abcorruptos\u00bb porque los campos en su tabla estaban llenos de signos de interrogaci\u00f3n. \ud83d\ude42<\/p>\n<p>Algo como esto<\/p>\n<pre class=\"brush: tsql; title: ; notranslate\" title=\"\">\r\n\r\nDECLARE @Unicode_string NVARCHAR(50) = '\u043a\u0430\u043a\u0432\u043e \u0449\u0435 \u0431\u044a\u0434\u0430?'\r\n\r\nSELECT @Unicode_string AS Unicode_string\r\n<\/pre>\n<p><a href=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2018\/02\/01_unicode_string.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/sqldoubleg.live-website.com\/wp-content\/uploads\/2018\/02\/01_unicode_string.png\" alt=\"\" width=\"870\" height=\"200\" class=\"aligncenter size-full wp-image-535\" srcset=\"https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/01_unicode_string.png 870w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/01_unicode_string-300x69.png 300w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/01_unicode_string-768x177.png 768w, https:\/\/www.sqldoubleg.com\/wp-content\/uploads\/2018\/02\/01_unicode_string-150x34.png 150w\" sizes=\"(max-width: 870px) 100vw, 870px\" \/><\/a><\/p>\n<p>Todav\u00eda me r\u00edo de esto, porque le hicimos escribir en un post-it y pegarlo en su monitor lo siguiente:<\/p>\n<blockquote><p><span style=\"font-size:48px;font-weight:bold;color:red\">N\u00bb<\/span><\/p><\/blockquote>\n<p>As\u00ed que, al final, incluso si hemos previsto todo correctamente, nos podr\u00edamos enfrentarte al cl\u00e1sico <a href=\"https:\/\/en.wikipedia.org\/wiki\/Layer_8\" rel=\"noopener\" target=\"_blank\">layer 8 error<\/a>.<\/p>\n<p>&nbsp;<br \/>\n<strong>Conclusi\u00f3n<\/strong><\/p>\n<p>Podemos ver que hay usos m\u00e1s que razonables para UNICODE, por eso existen, pero a veces son simplemente un no-no.<\/p>\n<p>Este post ha sido mejor que ir al psicologo, \u00a1qu\u00e9 alivio!<\/p>\n<p>Solo para terminar de agradecer a Aaron por organizar el evento de este mes y vosotros por leer.<\/p>\n<p>Gracias.<br \/>\n&nbsp;<br \/>\n<\/p>","protected":false},"excerpt":{"rendered":"<p>En esta publicaci\u00f3n, quiero compartir mi opini\u00f3n sobre el uso de tipos de datos UNICODE de forma predeterminada para cadenas almacenadas en SQL Server&nbsp; &nbsp;Esta publicaci\u00f3n forma parte de T-SQL Tuesday, que&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,43],"tags":[24,40,60],"_links":{"self":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/534"}],"collection":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/comments?post=534"}],"version-history":[{"count":1,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/534\/revisions"}],"predecessor-version":[{"id":551,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/posts\/534\/revisions\/551"}],"wp:attachment":[{"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/media?parent=534"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/categories?post=534"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqldoubleg.com\/es\/wp-json\/wp\/v2\/tags?post=534"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}