RSS

Archivos Mensuales: enero 2013

Introducción a las columnas Sparse

Sparse

Steve_Jobs

“Ser el hombre más rico del cementerio no me importa. Irme a la cama por la noche diciendo que hemos hecho algo maravilloso, eso es lo que me importa.” – Steven Paul Jobs mejor conocido como Steve Jobs – (1955-2011) – Emprendedor y Empresario Estadounidense.

¡Saludos!

Hoy quiero hablarles de las columnas sparse algo que nos ayudara a trabajar con la información no estructurada que es hoy en día algo muy difícil de trabajar en el modelo relacional.

Las columnas sparse almacenan los valores NULL de manera muy eficiente para las tablas que contienen un alto porcentaje de valores NULL. Las columnas sparce se pueden acomodar mejorado drásticamente las velocidades de consulta cuando se utiliza junto con los índices filtrados. Cuando se utiliza con conjuntos de columnas, columnas sparce extender el límite de columnas para las tablas de conteo tradicional, proporcionando una solución mucho mejor para almacenar datos no estructurados que los antiguos e ineficientes métodos de EAV. Columna fija también representan escasos datos en un formato XML que se genera automáticamente permite la importación fácil de datos, las exportaciones y la manipulación.
Las columnas dispersas no son compatibles con las claves principales, compresión de datos, restricciones NOT NULL o valores por defecto. Las columnas que no son Sparse pueden ser alteradas para tener la propiedad Sparse, pero en su lugar se debe crear con ella. Las columnas dispersas implícitamente permiten valores NULL en la creación de tablas. Conjuntos de columnas no son compatibles con la replicación de datos, consultas distribuidas, o índices. Las columnas dispersas son compatibles con las restricciones CHECK y los índices no agrupados.

Con frecuencia las tablas incluyen columnas que admiten valores NULOS (NULL),  Aun cuando una columna admita valores nulos, dichos valores pueden consumir un espacio en disco significativo esto dependerá de la definición del tipo de datos.

SQL Server 2008 incorpora las Sparse columns, es una mejora que permite la optimización del almacenamiento “zerobyte” de valores NULOS (NULL).  Se permiten definir hasta 30,000 columnas dispersas (Sparse columns) en una tabla.

Para definir estas “Sparse column”, sólo tiene que añadir el atributo de almacenamiento “SPARSE” después de la columna de definición en un comando CREATE o ALTER TABLE,

Veamos el siguiente ejemplo:

query1

 

 

 

 

 

 

 

USE
[Test]
GO
CREATE
TABLEdbo.Paciente
(
PacienteID INT NOT NULL,
NombreCompleto VARCHAR(80) NOT NULL,
Direccion VARCHAR(50) NOT NULL,
Telefono VARCHAR(20) SPARSE NULL,
Celular VARCHAR(20)SPARSENULL,
Ciudad VARCHAR(50)NOTNULL,
Provincia VARCHAR(50)SPARSENULL,
CONSTRAINT pk_PacienteIDPRIMARYKEY (PacienteID))
GO
DROP
TABLEdbo.Paciente
GO
query2

En resumen las columnas sparse aplicaran el ZEROBYTE y ahorremos un poco más de espacio en nuestras bases de datos. Hemos visto un ejemplo detallados de cómo utilizarla esta propiedad. Soluciones con columnas sparse ofrecen muchas ventajas cuando se aplica correctamente, pero puede ser necesario si la relación de los valores NULL en valores no NULL no es lo suficientemente alta, o si la tabla no es lo suficientemente grande como para justificar el uso de un conjunto de columnas.

No olvides dejar tu comentario,

Gracias.

Anuncios
 
Deja un comentario

Publicado por en enero 15, 2013 en Uncategorized

 

Funciones Ranking Microsoft SQL Server

FuncionesRanking

MartinLutherKing

“Hemos aprendido a volar como los pájaros, a nadar como los peces, pero no hemos aprendido el arte de vivir juntos, como hermanos.” – Martin Luther King (1929-1968) Pastor Estadounidense.

Las funciones de categoría devuelven un valor de categoría para cada fila de una partición. Según la función que se utilice, algunas filas pueden recibir el mismo valor que otras. Las funciones de categoría son no deterministas. Muchas personas ya utilizan y conocen estas funciones, pero en algunos casos otros no… a estos les escribo.

Esta característica está disponible desde la version de SQL Server 2005, ya hace un tiempo estas características benefician tanto a administradores de datos como a desarrolladores orientadas a resolver necesidades de la era moderna y logrando en lo mayor posible satisfacer eficientemente las diversas necesidades y requerimientos en el tratamiento de la data empresarial. Las funciones de ranking las cuales sirven para definir diferentes maneras de enumeración secuencial para los resultados, es decir, rankear un set de resultados.

Entre los diferentes usos tenemos por ejemplo, el poder enumerar secuencialmente cada fila de los resultados, también enumerar secuencialmente grupos para un set de resultados, es decir, aquí se introduce funcionalidad para usar expresiones de ranking para un conjunto de resultados. Esta característica podemos explotarla para ciertos escenarios, por ejemplo, cuando en nuestras aplicaciones .NET se requiera paginar, clasificar y ordenar los resultados en una grilla (GridView).

Anteriormente se podía usar TOP para rankear resultados, pero no podíamos especificar el orden del ranking, y si requeríamos dicha funcionalidad se tenía que crear ciertos algoritmos específicos para lograrlo. Con las funciones de ranking podemos hacer esta tarea mucho más fácil.

Las funciones de ranking son 4: ROW_NUMBER(), RANK (), DENSE_RANK() Y NTILE(integer_expression), cuyas sintaxis pasamos a verlas:

ROW_NUMBER () OVER ([<partition_by_clause>] <order_by_clause>) RANK () OVER ([<partition_by_clause>] <order_by_clause>) DENSE_RANK () OVER ([<partition_by_clause>] <order_by_clause>) NTILE (integer_expression) OVER ([<partition_by_clause>] <order_by_clause>)

Estas expresiones de ranking de basan en ciertos algoritmos que serán aplicados a una columna específica, y donde en todo momentos se usarán en combinación con las cláusulas PARTITION BY y ORDER BY.

Función ROW_NUMBER

Devuelve el número secuencial de una fila dentro de una partición de un conjunto de resultados, comenzando con 1 para la primera fila de cada partición.

Por ejemplo:

USE AdventureWorks2012; 
GO
SELECT ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS Row, 
    FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales YTD" 
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0;

 El conjunto de resultados es el siguiente:

Ranking_1

Opcionalmente podemos usar la cláusula PARTITION BY con cada una de las funciones ranking.

En el ejemplo siguiente se usa el argumento PARTITION BY para crear particiones del conjunto de resultados de la consulta por la columna TerritoryName.La cláusula ORDER BY especificada en la cláusula OVER ordena las filas de cada partición por la columna SalesYTD.La cláusula ORDER BY de la instrucción SELECT ordena todo el conjunto de resultados de la consulta por TerritoryName.

USE AdventureWorks2012;

GO

SELECT FirstName, LastName, TerritoryName, ROUND(SalesYTD,2,1),

ROW_NUMBER() OVER(PARTITION BY TerritoryName ORDER BY SalesYTD DESC) AS Row

FROM Sales.vSalesPerson

WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0

ORDER BY TerritoryName;

El conjunto de resultados es el siguiente.

Ranking_2

Función RANK

Rankea los datos de acuerdo a lo que se especifique para la cláusula ORDER BY, y lo hace rankeando verdaderamente la enumeración los resultados. Se diferencia de ROW_NUMBER() en lo siguiente. ROW_NUMBER() enumera así: 1,2,3,4,5… cada fila, en cambio RANK() no tendría por qué hacerlo necesariamente de la misma manera, pudiendo enumerar así: 1,2,4,4,7,8,8,8,9…

Por ejemplo:

USE AdventureWorks2012;

GO

SELECT i.ProductID, p.Name, i.LocationID, i.Quantity

,RANK() OVER

(PARTITION BY i.LocationID ORDER BY i.Quantity DESC) AS Rank

FROM Production.ProductInventory AS i

INNER JOIN Production.Product AS p

ON i.ProductID = p.ProductID

WHERE i.LocationID BETWEEN 3 AND 4

ORDER BY i.LocationID;

GO

Ranking_3

Función DENSE_RANK

Es parecido a RANK(), y se diferencia en que no produce saltos en la enumeración de los conjuntos de resultados. Es decir, la enumeración sería así: 1,2,2,3,4,5,5,6,7,8,8,9. Enumeración repetida pero secuencial, sin saltar números.

 
USE AdventureWorks2012;
GO
SELECT i.ProductID, p.Name, i.LocationID, i.Quantity
    ,DENSE_RANK() OVER 
    (PARTITION BY i.LocationID ORDER BY i.Quantity DESC) AS Rank
FROM Production.ProductInventory AS i 
INNER JOIN Production.Product AS p 
    ON i.ProductID = p.ProductID
WHERE i.LocationID BETWEEN 3 AND 4
ORDER BY i.LocationID;
GO

 Ranking_4

Función NTILE

Esta función lo que hace es limitar la numeración máxima de los resultados, por ejemplo, si es especifica NTILE(3000) entonces la numeración será hasta 3000 a partir, obviamente, desde 1.

Por ejemplo:

USE AdventureWorks2012; 
GO
SELECT p.FirstName, p.LastName
    ,NTILE(4) OVER(ORDER BY SalesYTD DESC) AS Quartile
    ,CONVERT(nvarchar(20),s.SalesYTD,1) AS SalesYTD
    , a.PostalCode
FROM Sales.SalesPerson AS s 
INNER JOIN Person.Person AS p 
    ON s.BusinessEntityID = p.BusinessEntityID
INNER JOIN Person.Address AS a 
    ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;
GO

 Ranking_5

Para finalizar, cabe destacar que a todas las funciones se le puede la cláusula PARTITION BY y que las mismas pueden trabajar en juntas como muestra el siguiente ejemplo.

— Trabajando las funciones Ranking todas USE AdventureWorks2012;

GO

SELECT p.FirstName, p.LastName

,ROW_NUMBER() OVER (ORDER BY a.PostalCode) AS “Row Number”

,RANK() OVER (ORDER BY a.PostalCode) AS Rank

,DENSE_RANK() OVER (ORDER BY a.PostalCode) AS “Dense Rank”

,NTILE(4) OVER (ORDER BY a.PostalCode) AS Quartile

,s.SalesYTD, a.PostalCode

FROM Sales.SalesPerson AS s

INNER JOIN Person.Person AS p

ON s.BusinessEntityID = p.BusinessEntityID

INNER JOIN Person.Address AS a

ON a.AddressID = p.BusinessEntityID

WHERE TerritoryID IS NOT NULL

AND SalesYTD <> 0;

FuncionesRanking

Con estas funciones se pueden crear muchas combinaciones y las mismas vienen a ayudar sobremanera a administradores de bases de datos y desarrolladores. A solucionar problemas que antes se consideraban complicados de una manera sumamente sencilla.

Espero aprendieras algo nuevo con este artículo y que fuera lo bastante sencillo, escribeme o deja tu comentario sobre cualquier duda o preguntas sobre este tema.

 

 
Deja un comentario

Publicado por en enero 8, 2013 en Microsoft, SQL Server