Fuera de los aspectos técnicos y la solución propuesta (usando VARCHAR(27)
columnas) discutidas en la respuesta de @ Joe , cuestiono la " necesidad de crear [una] tabla desnormalizada amplia" como lo expresa el OP A menos que haya algún requisito técnico extraño de que todas estas columnas debe estar en una sola tabla, sugeriría / recomendaría distribuirlas en tantas tablas de "hermanos" como sea necesario. Las tablas hermanas son tablas que:
- tener una relación de 1 a 1 entre sí,
- todos tienen exactamente la misma clave primaria,
- solo uno tiene la
IDENTITY
columna (y no FK para los demás)
- el resto tiene una clave externa (en la columna PK) que apunta a la PK de la tabla que tiene
IDENTITY
Aquí está dividiendo la fila lógica en dos o más tablas físicas. Pero eso es esencialmente lo que es la normalización de todos modos, y qué bases de datos relacionales están diseñadas para manejar.
En este escenario, se incurre en algo de espacio adicional utilizado al duplicar la PK, y en una complejidad de consulta adicional debido a la necesidad de INNER JOIN
unir las tablas (con frecuencia pero no siempre, a menos que todas las SELECT
consultas usen todas las columnas, pero eso generalmente no sucede) o cree una Transacción explícita a ellos INSERT
o UPDATE
juntos ( DELETE
puede manejarse a través del ON DELETE CASCADE
conjunto en el FK).
SIN EMBARGO, obtienes los beneficios de tener un modelo de datos adecuado con tipos de datos nativos y adecuados, y ningún truco que podría tener consecuencias imprevistas más adelante. Incluso si el uso VARCHAR(27)
permite que esto funcione a nivel técnico, pragmáticamente no creo que almacenar decimales como cadenas sea lo mejor para su / el proyecto.
Entonces, si solo está "necesitando" una sola tabla debido a que no se da cuenta de que una sola entidad lógica no necesita ser representada físicamente en un solo contenedor, entonces no intente forzar todo esto en una sola tabla cuando funcione con gracia en varias mesas.
El siguiente ejemplo ilustra el concepto básico:
PREPARAR
CREATE TABLE tempdb.dbo.T1
(
[ID] INT NOT NULL IDENTITY(11, 2) PRIMARY KEY,
[Col1] VARCHAR(25),
[Col2] DATETIME NOT NULL DEFAULT (GETDATE())
);
CREATE TABLE tempdb.dbo.T2
(
[ID] INT NOT NULL PRIMARY KEY
FOREIGN KEY REFERENCES tempdb.dbo.T1([ID]) ON DELETE CASCADE,
[Col3] UNIQUEIDENTIFIER,
[Col4] BIGINT
);
GO
CREATE PROCEDURE #TestInsert
(
@Val1 VARCHAR(25),
@Val4 BIGINT
)
AS
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN;
DECLARE @InsertedID INT;
INSERT INTO tempdb.dbo.T1 ([Col1])
VALUES (@Val1);
SET @InsertedID = SCOPE_IDENTITY();
INSERT INTO tempdb.dbo.T2 ([ID], [Col3], [Col4])
VALUES (@InsertedID, NEWID(), @Val4);
COMMIT TRAN;
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN;
END;
THROW;
END CATCH;
SELECT @InsertedID AS [ID];
GO
PRUEBA
EXEC #TestInsert 'aa', 454567678989;
EXEC #TestInsert 'bb', 12312312312234;
SELECT *
FROM tempdb.dbo.T1
INNER JOIN tempdb.dbo.T2
ON T2.[ID] = T1.[ID];
Devoluciones:
ID Col1 Col2 ID Col3 Col4
11 aa 2017-07-04 10:39:32.660 11 44465676-E8A1-4F38-B5B8-F50C63A947A4 454567678989
13 bb 2017-07-04 10:41:38.180 13 BFE43379-559F-4DAD-880B-B09D7ECA4914 12312312312234
DECIMAL(26, 8) NULL
campos en una tabla, sin compresión de página o compresión decimal. Al habilitar la compresión vardecimal pero no la página, la sobrecarga salta a más de 1 K. Existe la posibilidad externa de que pueda almacenar más campos por página sin vardecimal, dependiendo de sus valores.