2012-02-08 35 views
5

que tiene la siguiente tablarestricción de fila única en SQL Server

CREATE TABLE [dbo].[LogFiles_Warehouse](
    [id] [int] IDENTITY(1,1) NOT NULL, 
    [timestamp] [datetime] NOT NULL, 
    [clientNr] [int] NOT NULL, 
    [server] [nvarchar](150) COLLATE Latin1_General_CI_AS NOT NULL, 
    [storeNr] [int] NOT NULL, 
    [account] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL, 
    [software] [nvarchar](300) COLLATE Latin1_General_CI_AS NOT NULL, 
CONSTRAINT [PK_Astoria_LogFiles_Warehouse] PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

y quiere evitar tener filas duplicadas en mi mesa. Pensé en crear un índice ÚNICO en la tabla completa, pero luego SQL Manager Studio me dice que esto no es posible porque la clave sería demasiado grande.

¿Hay alguna otra manera en la que podría imponer filas exclusivas en todas las columnas, además de los índices?

+0

¿Quieres fila única basada en las columnas? –

+2

Seguramente tener una identidad significa que no habrá filas únicas, ¿está hablando de algo único en el resto de las columnas? –

+0

¿Podría decirnos cuál es el interés de tal restricción? Con campos como timestamp y clientNr, dudo que incluso pueda obtener filas duplicadas. –

Respuesta

8

crear un índice UNIQUE en valores hash:

CREATE TABLE [dbo].[LogFiles_Warehouse] 
     (
     [id] [int] IDENTITY(1,1) NOT NULL, 
     [timestamp] [datetime] NOT NULL, 
     [clientNr] [int] NOT NULL, 
     [server] [nvarchar](150) COLLATE Latin1_General_CI_AS NOT NULL, 
     [storeNr] [int] NOT NULL, 
     [account] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL, 
     [software] [nvarchar](300) COLLATE Latin1_General_CI_AS NOT NULL, 
     serverHash AS CAST(HASHBYTES('MD4', server) AS BINARY(16)), 
     accountHash AS CAST(HASHBYTES('MD4', account) AS BINARY(16)), 
     softwareHash AS CAST(HASHBYTES('MD4', software) AS BINARY(16)) 
     ) 

CREATE UNIQUE INDEX 
     UX_LogFilesWarehouse_Server_Account_Software 
ON  LogFiles_Warehouse (serverHash, accountHash, softwareHash) 
+0

¿No sería más fácil hacer hash en la fila completa y crear el índice sobre ese hash? –

+0

@Florian: ¿más fácil para quién y cómo "hash la fila completa"? Un índice en 3 campos de 16 bytes no es un problema para el servidor. Y si va a concatenar todos los valores, entonces es una posible fuente de confusión entre, por ejemplo, 'server = MSSQLServer, account = 20081' y' server = MSSQLServer2008, account = 1'. – Quassnoi

+0

Bien, eso tiene sentido. ¿Puedo agregar las otras filas al índice también? (es decir, marca de tiempo, cliente y guarda) Entonces, ¿el índice efectivamente será sobre todas las columnas al final? Sin la IDENTIDAD, por supuesto. –

2

Utilice desencadenantes + un índice no exclusivo más pequeño sobre los campos más distintivos para evitar el problema de lata de la tabla.

Esto se reduce a un mal diseño de base de datos para empezar. Campos como Software, Cuenta no pertenecen a esa tabla para comenzar (o si cuenta, luego no cliente nr). Tu tabla es tan simple porque, para empezar, violas las bases del diseño de la base de datos.

Además, para evitar campos no únicos, tiene NT para tener el campo Id en las pruebas únicas, de lo contrario, nunca tendrá dobles para empezar.

+1

Esto es solo una tabla para contener los valores de un archivo de registro. __Ninguno__ de los campos tiene funcional, transitivo, multivalor o cualquier otra dependencia entre sí. Por supuesto, eso significa que nunca puede haber dos filas idénticas, pero, como los archivos de registro se importan, un usuario podría importar el mismo archivo de registro dos veces y, por lo tanto, crear dos filas idénticas. –

Cuestiones relacionadas