Al di fuori degli aspetti tecnici e della soluzione proposta (usando le VARCHAR(27)
colonne) discussi nella risposta di @ Joe , metto in dubbio la " necessità di creare [una] ampia tabella denormalizzata" come espressa dall'OP A meno che non ci siano dei requisiti tecnici dispari che tutte queste colonne deve essere in una singola tabella, suggerirei / raccomanderei di distribuirli su tutte le tabelle "fratelli" necessarie. Le tabelle di pari livello sono tabelle che:
- avere una relazione 1 a 1 tra loro,
- tutti hanno la stessa chiave primaria esatta,
- solo uno ha la
IDENTITY
colonna (e nessun FK per gli altri)
- il resto ha una chiave esterna (sulla colonna PK) che punta al PK della tabella che ha il
IDENTITY
Qui stai dividendo la sua riga logica su due o più tabelle fisiche. Ma questo è essenzialmente ciò che è la normalizzazione e quali database relazionali sono progettati per gestire.
In questo scenario si incorre in uno spazio aggiuntivo utilizzato duplicando il PK e una maggiore complessità delle query a causa della necessità di entrambe INNER JOIN
le tabelle insieme (spesso ma non sempre, a meno che tutte le SELECT
query non utilizzino tutte le colonne, ma ciò non accade di solito) o creare una Transazione esplicita a loro INSERT
o UPDATE
insieme ( DELETE
può essere gestita tramite ON DELETE CASCADE
set sull'FK).
TUTTAVIA, si ottengono i vantaggi di disporre di un modello di dati adeguato con tipi di dati nativi adeguati e senza inganni che potrebbero avere conseguenze impreviste in seguito. Anche se l'utilizzo VARCHAR(27)
consente di farlo funzionare a livello tecnico, pragmaticamente non penso che archiviare i decimali poiché le stringhe siano nel miglior interesse del progetto.
Quindi, se stai solo "necessitando" di una singola tabella perché non ti rendi conto che una singola entità logica non ha bisogno di essere rappresentata fisicamente in un singolo contenitore, allora non tentare di forzare tutto questo in una singola tabella quando funzionerà con grazia su più tavoli.
L'esempio seguente illustra il concetto di base:
IMPOSTARE
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
TEST
EXEC #TestInsert 'aa', 454567678989;
EXEC #TestInsert 'bb', 12312312312234;
SELECT *
FROM tempdb.dbo.T1
INNER JOIN tempdb.dbo.T2
ON T2.[ID] = T1.[ID];
Ritorna:
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
campi in una tabella, senza compressione di pagina o compressione decimale. Abilitando la compressione vardecimal ma non la pagina, l'overhead passa a oltre 1 K. Esiste una possibilità esterna che sarai in grado di memorizzare più campi per pagina senza vardecimal, a seconda dei tuoi valori.