Fora dos aspectos técnicos e da solução alternativa proposta (usando VARCHAR(27)
colunas) discutidos na resposta de @ Joe , questiono a " necessidade de criar [uma] ampla tabela desnormalizada" conforme expressa pelo OP A menos que haja algum requisito técnico estranho de que todas essas colunas deve estar em uma única tabela, eu sugeriria / recomendaria espalhá-las por quantas tabelas de "irmãos" forem necessárias. Tabelas de irmãos sendo tabelas que:
- ter um relacionamento de 1 para 1,
- todos têm exatamente a mesma chave primária,
- apenas um tem a
IDENTITY
coluna (e nenhum FK para os outros)
- o restante possui uma chave estrangeira (na coluna PK) apontando para a PK da tabela que possui o
IDENTITY
Aqui você está dividindo a linha lógica em duas ou mais tabelas físicas. Mas isso é essencialmente o que é normalização, e quais bancos de dados relacionais são projetados para lidar.
Nesse cenário, você incorre em espaço extra usado pela duplicação da PK e em alguma complexidade adicional de consulta devido à necessidade de INNER JOIN
juntar as tabelas (frequentemente, mas nem sempre, a menos que todas as SELECT
consultas usem todas as colunas, mas isso geralmente não acontece) ou criar uma transação explícita a INSERT
ou UPDATE
-los juntos ( DELETE
pode ser tratada através ON DELETE CASCADE
set no FK).
NO ENTANTO, você obtém os benefícios de ter um modelo de dados adequado com tipos de dados nativos adequados e nenhum truque que possa ter consequências imprevisíveis posteriormente. Mesmo que o uso VARCHAR(27)
permita que isso funcione em um nível técnico, pragmaticamente, não acho que armazenar decimais como seqüências de caracteres seja do seu interesse / do projeto.
Portanto, se você estiver apenas "precisando" de uma única tabela devido a não perceber que uma única entidade lógica não precisa ser representada fisicamente em um único contêiner, não tente forçar tudo isso em uma única tabela quando ela funcionar. graciosamente em várias tabelas.
O exemplo abaixo ilustra o conceito básico:
CONFIGURAÇÃO
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
TESTE
EXEC #TestInsert 'aa', 454567678989;
EXEC #TestInsert 'bb', 12312312312234;
SELECT *
FROM tempdb.dbo.T1
INNER JOIN tempdb.dbo.T2
ON T2.[ID] = T1.[ID];
Devoluções:
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 em uma tabela, sem compactação de página ou compactação decimal. Ativando a compactação vardecimal, mas não a página, a sobrecarga salta para mais de 1 K. Há uma chance externa de que você possa armazenar mais campos por página sem vardecimal, dependendo dos seus valores.