Di luar aspek teknis dan usulan penyelesaian (menggunakan VARCHAR(27)
kolom) yang dibahas dalam jawaban @ Joe , saya mempertanyakan " kebutuhan untuk membuat tabel denormalized luas" sebagaimana diungkapkan oleh OP Kecuali jika ada beberapa persyaratan teknis aneh bahwa semua kolom ini harus dalam satu tabel, saya akan menyarankan / merekomendasikan menyebar mereka di banyak "saudara" tabel yang diperlukan. Tabel saudara adalah tabel yang:
- memiliki hubungan 1-ke-1 satu sama lain,
- semua memiliki Kunci Utama yang sama persis,
- hanya satu yang memiliki
IDENTITY
kolom (dan tidak ada FK ke yang lain)
- sisanya memiliki Kunci Asing (pada kolom PK) yang menunjuk ke PK tabel yang memiliki
IDENTITY
Di sini Anda membelah baris logis di dua atau lebih tabel fisik. Tapi itu pada dasarnya apa itu normalisasi, dan database relasional apa yang dirancang untuk ditangani.
Dalam skenario ini Anda mengeluarkan beberapa ruang tambahan yang digunakan dengan menduplikasi PK, dan beberapa kompleksitas kueri tambahan karena kebutuhan untuk INNER JOIN
tabel bersama (sering tetapi tidak selalu, kecuali jika semua SELECT
kueri menggunakan semua kolom, tapi itu biasanya tidak terjadi) atau membuat Transaksi eksplisit untuk INSERT
atau UPDATE
mereka bersama-sama ( DELETE
dapat ditangani melalui ON DELETE CASCADE
set di FK).
NAMUN, Anda mendapatkan manfaat dari memiliki model data yang tepat dengan tipe data asli yang tepat, dan tidak ada tipu daya yang dapat memiliki konsekuensi yang tidak terduga nantinya. Bahkan jika menggunakan VARCHAR(27)
memungkinkan ini bekerja pada tingkat teknis, secara pragmatis saya tidak berpikir menyimpan desimal karena string adalah untuk kepentingan terbaik Anda / proyek.
Jadi, jika Anda hanya "membutuhkan" satu tabel karena tidak menyadari bahwa satu entitas logis tidak perlu diwakili secara fisik dalam satu wadah, maka jangan mencoba untuk memaksa semua ini menjadi satu tabel ketika itu akan bekerja anggun di beberapa tabel.
Contoh di bawah menggambarkan konsep dasar:
MENDIRIKAN
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
UJI
EXEC #TestInsert 'aa', 454567678989;
EXEC #TestInsert 'bb', 12312312312234;
SELECT *
FROM tempdb.dbo.T1
INNER JOIN tempdb.dbo.T2
ON T2.[ID] = T1.[ID];
Pengembalian:
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
bidang ke dalam tabel, tanpa kompresi halaman atau kompresi desimal. Mengaktifkan kompresi vardecimal tetapi tidak halaman, overhead melompat ke lebih dari 1 K. Ada kemungkinan di luar bahwa Anda akan dapat menyimpan lebih banyak bidang per halaman tanpa vardecimal, tergantung pada nilai Anda.