Los GUID pueden parecer una opción natural para su clave principal, y si realmente debe hacerlo, probablemente podría argumentar que la usará para la CLAVE PRIMARIA de la tabla. Lo que recomiendo encarecidamente que no haga es usar la columna GUID como clave de agrupación , que SQL Server hace de manera predeterminada, a menos que se lo indique específicamente.
Realmente necesitas mantener dos problemas separados:
la clave primaria es una construcción lógica, una de las claves candidatas que identifica de manera única y confiable cada fila de su tabla. Esto puede ser cualquier cosa, realmente, un INT
, un GUID
, una cadena, elija lo que tenga más sentido para su escenario.
la clave de agrupamiento (la columna o columnas que definen el "índice agrupado" en la tabla) - esto es algo relacionado con el almacenamiento físico , y aquí, un tipo de datos pequeño, estable y en constante aumento es su mejor elección, INT
o BIGINT
como su Opción por defecto.
Por defecto, la clave principal en una tabla de SQL Server también se usa como clave de agrupación, ¡pero eso no tiene por qué ser así! Personalmente, he visto ganancias masivas de rendimiento al dividir la Clave primaria / agrupada basada en GUID anterior en dos claves separadas: la clave primaria (lógica) en el GUID y la clave de agrupamiento (orden) en una INT IDENTITY(1,1)
columna separada .
Como Kimberly Tripp , la reina de la indexación, y otros han declarado muchas veces, GUID
ya que la clave de agrupamiento no es óptima, ya que debido a su aleatoriedad, conducirá a una fragmentación masiva de páginas e índices y a un mal rendimiento en general.
Sí, lo sé, hay newsequentialid()
en SQL Server 2005 y versiones posteriores, pero incluso eso no es secuencial y completamente secuencial y, por lo tanto, también sufre los mismos problemas que el GUID
, solo que un poco menos prominente.
Luego, hay otro problema a considerar: la clave de agrupación en una tabla se agregará a todas y cada una de las entradas de todos y cada uno de los índices no agrupados en su tabla, por lo que realmente desea asegurarse de que sea lo más pequeña posible. Por lo general, una INT
con más de 2 mil millones de filas debería ser suficiente para la gran mayoría de las tablas, y en comparación con una GUID
clave de agrupación, puede ahorrarse cientos de megabytes de almacenamiento en el disco y en la memoria del servidor.
Cálculo rápido: usando INT
vs. GUID
como clave principal y de agrupamiento:
- Tabla base con 1'000'000 filas (3.8 MB vs. 15.26 MB)
- 6 índices no agrupados (22.89 MB frente a 91.55 MB)
TOTAL: 25 MB frente a 106 MB , ¡y eso es solo en una sola mesa!
Algo más para pensar: cosas excelentes de Kimberly Tripp: léelo, léelo de nuevo, ¡digerirlo! Es el evangelio de indexación de SQL Server, de verdad.
PD: por supuesto, si se trata de unos pocos cientos o miles de filas, la mayoría de estos argumentos realmente no tendrán un gran impacto en usted. Sin embargo: si entras en las decenas o cientos de miles de filas, o comienzas a contar en millones, entonces esos puntos se vuelven cruciales y muy importantes de entender.
Actualización: si desea tener su PKGUID
columna como su clave principal (pero no su clave de agrupación) y otra columna MYINT
( INT IDENTITY
) como su clave de agrupación, use esto:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
Básicamente: solo tiene que decir explícitamente la PRIMARY KEY
restricción que es NONCLUSTERED
(de lo contrario, se crea como su índice agrupado, de forma predeterminada), y luego crea un segundo índice que se define comoCLUSTERED
Esto funcionará, y es una opción válida si tiene un sistema existente que necesita ser "rediseñado" para su rendimiento. Para un nuevo sistema, si comienzas desde cero y no estás en un escenario de replicación, siempre elegiría ID INT IDENTITY(1,1)
como mi clave principal agrupada, ¡mucho más eficiente que cualquier otra cosa!