Saya sedang mengembangkan database SQL Server 2012 dan saya punya pertanyaan tentang hubungan One-to-Zero-Or-One.
Saya punya dua meja, Codes
dan HelperCodes
. Kode dapat memiliki nol atau satu kode pembantu. Ini adalah skrip sql untuk membuat dua tabel ini dan hubungannya:
CREATE TABLE [dbo].[Code]
(
[Id] NVARCHAR(20) NOT NULL,
[Level] TINYINT NOT NULL,
[CommissioningFlag] TINYINT NOT NULL,
[SentToRanger] BIT NOT NULL DEFAULT 0,
[LastChange] NVARCHAR(50) NOT NULL,
[UserName] NVARCHAR(50) NOT NULL,
[Source] NVARCHAR(50) NOT NULL,
[Reason] NVARCHAR(200) NULL,
[HelperCodeId] NVARCHAR(20) NULL,
CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED
(
[Id] ASC
),
CONSTRAINT [FK_Code_LevelConfiguration]
FOREIGN KEY ([Level])
REFERENCES [dbo].[LevelConfiguration] ([Level]),
CONSTRAINT [FK_Code_HelperCode]
FOREIGN KEY ([HelperCodeId])
REFERENCES [dbo].[HelperCode] ([HelperCodeId])
)
CREATE TABLE [dbo].[HelperCode]
(
[HelperCodeId] NVARCHAR(20) NOT NULL,
[Level] TINYINT NOT NULL,
[CommissioningFlag] TINYINT NOT NULL,
[LastChange] NVARCHAR(50) NOT NULL,
CONSTRAINT [PK_HelperCode] PRIMARY KEY CLUSTERED
(
[HelperCodeId] ASC
),
CONSTRAINT [FK_HelperCode_LevelConfiguration]
FOREIGN KEY ([Level])
REFERENCES [dbo].[LevelConfiguration] ([Level])
)
Apakah itu benar?
Kode dan HelperCode keduanya merupakan entitas yang berbeda. HelperCode dapat digunakan (tidak ada Kode yang merujuknya), atau digunakan (hanya satu Kode yang merujuknya).
Mungkin Code.HelperCodeId harus menjadi bagian dari kunci utama tabel kode. Tapi saya tidak yakin apakah kolom nol bisa menjadi bagian dari primer. Melakukan ini, saya ingin mencegah dua atau lebih kode referensi HelperCode yang sama.
database-design
sql-server-2012
VansFannel
sumber
sumber
HelperCodeId
menjadi bagian dari PK? Apakah itu, kebetulan, karena Anda ingin mencegah dua atau lebih Kode untuk referensi HelperCode yang sama?HelperCodeId
kolom sebagai Unik.Jawaban:
Untuk menjawab pertanyaan dalam judul, tidak, semua kolom utama harus
NOT NULL
.Tetapi tanpa mengubah desain tabel, Anda bisa menambahkan indeks yang difilter pada
Code (HelperCodeId)
kolom:Filter (
WHERE HelperCodeId IS NOT NULL
) diperlukan karena cara SQL-Server memperlakukan nulls dalam batasan unik dan indeks unik. Tanpa filter, SQL-Server tidak akan memungkinkan lebih dari satu baris denganNULL
diHelperCodeId
.Desain alternatif akan menghapus
HelperCodeId
dariCode
dan menambahkan tabel ketiga yang akan menyimpanCode
-HelperCode
hubungan. Hubungan antara dua entitas tampaknya Zero-atau-One - to-Zero-atau-One (kedua Kode tidak dapat memiliki HelperCode dan HelperCode dapat digunakan oleh Kode tidak):HelperCode
tetap tidak berubah:Tabel tambahan akan memiliki dua
UNIQUE
batasan (atau satu primer dan satu unik) untuk memastikan bahwa setiap Kode terkait dengan (maksimum) satu HelperCode dan setiap HelperCode terkait dengan (maksimum) satu Kode. Kedua kolom tersebut adalahNOT NULL
:sumber
Coba gunakan batasan unik sebagai gantinya. Seharusnya standar ANSI menyatakan nulls sebagai kunci utama tidak valid, tetapi saya belum pernah melihat standar dan tidak ingin membelinya untuk memverifikasi ini.
Tidak memiliki kunci nol tampaknya menjadi salah satu hal yang para pengembang memiliki keyakinan sangat keras pada satu atau lain cara. Preferensi saya adalah menggunakannya karena menurut saya bermanfaat untuk tabel pencarian yang berisi tooltips dan data terkait untuk kotak kombo yang belum diisi.
Saya diajari bahwa nilai Null menunjukkan bahwa suatu variabel tidak pernah ditetapkan dan nilai kosong menunjukkan bahwa nilai tersebut telah ditetapkan sebelumnya. Tentu saja ini tergantung pada pengembang untuk menentukan aplikasi, tetapi saya merasa tidak masuk akal untuk mengizinkan kunci primer kosong tetapi bukan kunci primer nol.
sumber