Crear un índice en una variable de tabla
¿Se puede crear un índice en una variable de tabla en SQL Server 2000?
es decir
DECLARE @TEMPTABLE TABLE (
[ID] [int] NOT NULL PRIMARY KEY
,[Name] [nvarchar] (255) COLLATE DATABASE_DEFAULT NULL
)
¿Puedo crear un índice en Name
?
La pregunta está etiquetada como SQL Server 2000, pero para beneficio de las personas que desarrollan la última versión, la abordaré primero.
Servidor SQL 2014
Además de los métodos para agregar índices basados en restricciones que se analizan a continuación, SQL Server 2014 también permite especificar índices no únicos directamente con sintaxis en línea en declaraciones de variables de tabla.
La sintaxis de ejemplo para eso se encuentra a continuación.
/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);
Actualmente, los índices filtrados y los índices con columnas incluidas no se pueden declarar con esta sintaxis; sin embargo, SQL Server 2016 lo relaja un poco más. Desde CTP 3.1 ahora es posible declarar índices filtrados para variables de tabla. Según RTM, puede darse el caso de que las columnas incluidas también estén permitidas, pero la posición actual es que "probablemente no lleguen a SQL16 debido a limitaciones de recursos".
/*SQL Server 2016 allows filtered indexes*/
DECLARE @T TABLE
(
c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/
)
Servidor SQL 2000 - 2012
¿Puedo crear un índice en Nombre?
Respuesta corta: sí.
DECLARE @TEMPTABLE TABLE (
[ID] [INT] NOT NULL PRIMARY KEY,
[Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
UNIQUE NONCLUSTERED ([Name], [ID])
)
Una respuesta más detallada se encuentra a continuación.
Las tablas tradicionales en SQL Server pueden tener un índice agrupado o estar estructuradas como montones .
Los índices agrupados se pueden declarar como únicos para no permitir valores de clave duplicados o por defecto como no únicos. Si no es único, SQL Server agrega silenciosamente un unificador a cualquier clave duplicada para hacerla única.
Los índices no agrupados también se pueden declarar explícitamente como únicos. De lo contrario, para el caso no único, SQL Server agrega el localizador de filas (clave de índice agrupada o RID para un montón) a todas las claves de índice (no solo duplicadas), esto nuevamente garantiza que sean únicas.
En SQL Server 2000 - 2012, los índices de las variables de la tabla solo se pueden crear implícitamente mediante la creación de una restricción UNIQUE
o PRIMARY KEY
. La diferencia entre estos tipos de restricciones es que la clave principal debe estar en columnas que no aceptan valores NULL. Las columnas que participan en una restricción única pueden ser anulables. (aunque la implementación de restricciones únicas de SQL Server en presencia de NULL
s no se ajusta a lo especificado en el Estándar SQL). Además, una tabla solo puede tener una clave principal pero múltiples restricciones únicas.
Ambas restricciones lógicas se implementan físicamente con un índice único. Si no se especifica explícitamente lo contrario, se PRIMARY KEY
convertirá en el índice agrupado y las restricciones únicas no agrupadas, pero este comportamiento se puede anular especificando CLUSTERED
o NONCLUSTERED
explícitamente con la declaración de restricción (sintaxis de ejemplo).
DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)
Como resultado de lo anterior, los siguientes índices se pueden crear implícitamente en variables de tabla en SQL Server 2000 - 2012.
+-------------------------------------+-------------------------------------+
| Index Type | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index | Yes |
| Nonunique Clustered Index | |
| Unique NCI on a heap | Yes |
| Non Unique NCI on a heap | |
| Unique NCI on a clustered index | Yes |
| Non Unique NCI on a clustered index | Yes |
+-------------------------------------+-------------------------------------+
El último requiere un poco de explicación. En la definición de variable de tabla al comienzo de esta respuesta, el índice no únicoName
y no agrupado se simula mediante un índice únicoName,Id
(recuerde que SQL Server agregaría silenciosamente la clave de índice agrupado a la clave NCI no única de todos modos).
También se puede lograr un índice agrupado no único agregando manualmente una IDENTITY
columna para que actúe como unificador.
DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)
Pero esta no es una simulación precisa de cómo normalmente se implementaría un índice agrupado no único en SQL Server, ya que esto agrega el "Uniqueificador" a todas las filas. No sólo aquellos que lo requieren.