@Joe の回答でVARCHAR(27)
説明されている技術的側面と提案された回避策(列を使用)の外では、OPで表現されている「[a]広い非正規化テーブルを作成する必要がある」と質問します。しなければならない単一のテーブルでも、私はお勧めします/必要なだけの「兄弟」のテーブルとして渡ってそれらを広げるお勧めします。兄弟テーブルは次のようなテーブルです。
- 互いに1対1の関係にあり、
- すべてがまったく同じ主キーを持ち、
- 1つだけが
IDENTITY
列を持っている(他のFKはない)
- 残りは、(PK列に)外部キーがあり、
IDENTITY
ここでは、論理行を2つ以上の物理テーブルに分割しています。しかし、それが本質的に正規化の本質であり、リレーショナルデータベースが処理するように設計されています。
このシナリオでは、PKを複製することによって使用される余分なスペースが発生しINNER JOIN
、テーブルを一緒にする必要があるためにクエリがさらに複雑になります(すべてのSELECT
クエリがすべての列を使用しない限り、頻繁ではありませんが、通常は発生しません)。または明示的なトランザクションを作成するINSERT
か、UPDATE
それらを一緒に作成します(FKのセットをDELETE
介して処理できますON DELETE CASCADE
)。
ただし、適切なネイティブデータ型を備えた適切なデータモデルがあり、後で予期しない結果が生じる可能性のある不正操作を行わないという利点があります。VARCHAR(27)
これを使用して技術的なレベルで機能する場合でも、実用的には、小数点以下を文字列として格納することはあなたの/プロジェクトの最大の利益になるとは思いません。
したがって、単一の論理エンティティを単一のコンテナで物理的に表現する必要がないことを認識していないために単一のテーブルのみが「必要」である場合、それが機能するときにこれらすべてを単一のテーブルに強制することを試みないでください。複数のテーブルにわたって優雅に。
次の例は、基本的な概念を示しています。
セットアップ
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
テスト
EXEC #TestInsert 'aa', 454567678989;
EXEC #TestInsert 'bb', 12312312312234;
SELECT *
FROM tempdb.dbo.T1
INNER JOIN tempdb.dbo.T2
ON T2.[ID] = T1.[ID];
戻り値:
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
フィールドをテーブルに入れることができます。ページ圧縮ではなくvardecimalを有効にすると、オーバーヘッドが1 Kを超えます。値によっては、vardecimalなしでページごとにより多くのフィールドを格納できる可能性があります。