Abgesehen von den technischen Aspekten und der vorgeschlagenen Problemumgehung (unter Verwendung von VARCHAR(27)
Spalten), die in @ Joes Antwort erörtert wurden , stelle ich die " Notwendigkeit , eine [breite] denormalisierte Tabelle zu erstellen " in Frage, wie sie vom OP ausgedrückt wird, es sei denn, es gibt eine merkwürdige technische Anforderung, dass alle diese Spalten muss in einer einzigen Tabelle sein, ich würde vorschlagen / empfehlen, sie auf so viele "Geschwister" -Tische wie nötig zu verteilen. Geschwistertabellen sind Tabellen, die:
- eine 1: 1-Beziehung zueinander haben,
- alle haben genau den gleichen Primärschlüssel,
- nur einer hat die
IDENTITY
Spalte (und keine FK zu den anderen)
- Der Rest hat einen Fremdschlüssel (in der PK-Spalte), der auf die PK der Tabelle zeigt, in der sich die befindet
IDENTITY
Hier teilen Sie die logische Zeile auf zwei oder mehr physische Tabellen auf. Aber das ist im Wesentlichen das, was Normalisierung sowieso ist und wofür relationale Datenbanken ausgelegt sind.
In diesem Szenario entsteht durch das Duplizieren der PK zusätzlicher Speicherplatz und zusätzliche Abfragekomplexität, da entweder INNER JOIN
die Tabellen zusammen verwendet werden müssen (häufig, aber nicht immer, es sei denn, alle SELECT
Abfragen verwenden alle Spalten, dies geschieht jedoch normalerweise nicht). oder erstellen Sie eine explizite Transaktion zu INSERT
oder UPDATE
zusammen ( DELETE
kann über ON DELETE CASCADE
set auf dem FK abgewickelt werden ).
Sie erhalten jedoch die Vorteile eines ordnungsgemäßen Datenmodells mit geeigneten nativen Datentypen und ohne Tricks, die später unvorhergesehene Folgen haben könnten. Selbst wenn die Verwendung VARCHAR(27)
dies auf technischer Ebene ermöglicht, denke ich pragmatisch nicht, dass das Speichern von Dezimalstellen als Zeichenfolgen im besten Interesse Ihres / des Projekts liegt.
Wenn Sie also nur eine einzelne Tabelle "benötigen", weil Sie nicht wissen, dass eine einzelne logische Entität nicht physisch in einem einzelnen Container dargestellt werden muss, versuchen Sie nicht, all dies in eine einzelne Tabelle zu zwingen, wenn dies funktioniert elegant über mehrere Tabellen.
Das folgende Beispiel veranschaulicht das Grundkonzept:
INSTALLIEREN
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
PRÜFUNG
EXEC #TestInsert 'aa', 454567678989;
EXEC #TestInsert 'bb', 12312312312234;
SELECT *
FROM tempdb.dbo.T1
INNER JOIN tempdb.dbo.T2
ON T2.[ID] = T1.[ID];
Kehrt zurück:
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
Felder in eine Tabelle bekommen, ohne Seitenkomprimierung oder Dezimalkomprimierung. Wenn Sie die vardezimale, aber nicht die Seitenkomprimierung aktivieren, springt der Overhead auf über 1 K. Es besteht die Möglichkeit, dass Sie abhängig von Ihren Werten mehr Felder pro Seite ohne vardezimal speichern können.