Saya biasanya mendesain basis data saya mengikuti aturan berikut:
- Tidak ada orang lain selain db_owner dan sysadmin yang memiliki akses ke tabel database.
- Peran pengguna dikontrol pada lapisan aplikasi. Saya biasanya menggunakan satu peran db untuk memberikan akses ke pandangan, prosedur dan fungsi yang tersimpan, tetapi dalam beberapa kasus, saya menambahkan aturan kedua untuk melindungi beberapa prosedur yang tersimpan.
- Saya menggunakan PEMICU awalnya memvalidasi informasi penting.
CREATE TRIGGER <TriggerName>
ON <MyTable>
[BEFORE | AFTER] INSERT
AS
IF EXISTS (SELECT 1
FROM inserted
WHERE Field1 <> <some_initial_value>
OR Field2 <> <other_initial_value>)
BEGIN
UPDATE MyTable
SET Field1 = <some_initial_value>,
Field2 = <other_initial_value>
...
END
- DML dijalankan menggunakan prosedur tersimpan:
sp_MyTable_Insert(@Field1, @Field2, @Field3, ...);
sp_MyTable_Delete(@Key1, @Key2, ...);
sp_MyTable_Update(@Key1, @Key2, @Field3, ...);
Apakah Anda berpikir bahwa, dalam skenario ini, layak untuk menggunakan DEFAULT CONSTRAINTs, atau saya menambahkan pekerjaan tambahan dan tidak perlu ke server DB?
Memperbarui
Saya mengerti bahwa dengan menggunakan batasan DEFAULT saya memberikan lebih banyak informasi kepada orang lain yang harus mengelola database. Tapi saya lebih tertarik pada kinerja.
Saya berasumsi bahwa database selalu memeriksa nilai default, bahkan jika saya memberikan nilai yang benar, maka saya melakukan pekerjaan yang sama dua kali.
Sebagai contoh, Apakah ada cara untuk menghindari batasan DEFAULT dalam eksekusi pemicu?
sql-server
dantsql
karena kode dalam pertanyaan Anda sangat spesifik untuk DBMS ituJawaban:
Um, mengapa Anda menganggap itu? ;-). Mengingat bahwa Default ada untuk memberikan nilai ketika kolom yang dilampirkan tidak ada dalam
INSERT
pernyataan, saya akan mengasumsikan sebaliknya: bahwa mereka sepenuhnya diabaikan jika kolom terkait hadir diINSERT
pernyataan.Untungnya, tidak satu pun dari kita perlu berasumsi apa pun karena pernyataan ini dalam pertanyaan:
Pertanyaan tentang kinerja hampir selalu dapat diuji. Jadi kita hanya perlu membuat tes untuk mengizinkan SQL Server (otoritas sebenarnya di sini) untuk menjawab pertanyaan ini.
MEMPERSIAPKAN
Jalankan yang berikut ini sekali:
Jalankan tes 1A dan 1B secara individual, tidak bersamaan karena itu mengacaukan waktunya. Jalankan masing-masing beberapa kali untuk mendapatkan rasa waktu rata-rata untuk masing-masing.
Tes 1A
Tes 1B
Jalankan tes 2A dan 2B secara individual, tidak bersamaan karena itu mengacaukan waktunya. Jalankan masing-masing beberapa kali untuk mendapatkan rasa waktu rata-rata untuk masing-masing.
Tes 2A
Tes 2B
Anda harus melihat bahwa tidak ada perbedaan nyata dalam pengaturan waktu antara tes 1A dan 1B, atau antara tes 2A dan 2B. Jadi, tidak, tidak ada penalti kinerja yang telah
DEFAULT
ditentukan tetapi tidak digunakan.Selain itu, selain hanya mendokumentasikan perilaku yang dituju, Anda perlu diingat bahwa sebagian besar Anda yang peduli tentang pernyataan DML yang sepenuhnya terkandung dalam prosedur tersimpan Anda. Orang-orang pendukung tidak peduli. Pengembang masa depan mungkin tidak menyadari keinginan Anda untuk memiliki semua DML yang dienkapsulasi dalam prosedur yang tersimpan, atau peduli bahkan jika mereka tahu. Dan siapa pun yang mempertahankan DB ini setelah Anda pergi (baik proyek atau pekerjaan lain) mungkin tidak peduli, atau mungkin tidak dapat mencegah penggunaan ORM tidak peduli berapa banyak mereka memprotes. Jadi, Defaults, dapat membantu karena mereka memberi orang "keluar" saat melakukan
INSERT
, terutama ad-hocINSERT
dilakukan oleh perwakilan dukungan, karena itu adalah satu kolom yang tidak perlu mereka sertakan (itulah sebabnya saya selalu menggunakan default pada audit kolom tanggal).DAN, hanya terpikir oleh saya bahwa itu dapat ditampilkan agak objektif apakah
DEFAULT
diperiksa atau tidak ketika kolom terkait hadir dalamINSERT
pernyataan: cukup berikan nilai yang tidak valid. Tes berikut tidak hanya itu:Seperti yang Anda lihat, ketika kolom (dan nilai, bukan kata kunci
DEFAULT
) diberikan, Defaultnya adalah 100% diabaikan. Kami tahu ini karenaINSERT
berhasil. Tetapi jika Default digunakan, ada kesalahan karena akhirnya dieksekusi.Meskipun perlu menghindari Batasan Default (setidaknya dalam konteks ini) sama sekali tidak perlu, demi kelengkapan, dapat dicatat bahwa hanya mungkin untuk "menghindari" Kendala Default dalam
INSTEAD OF
Pemicu, tetapi tidak dalamAFTER
Pemicu. Menurut dokumentasi untuk CREATE TRIGGER :Tentu saja, menggunakan
INSTEAD OF
Pemicu akan membutuhkan:AFTER
Trigger yang memungkinkan ConstraintNamun, saya tidak akan merekomendasikan hal ini.
sumber
CURRENT_TIMESTAMP
kolom datetime. Jadi, tes "mudah" menggunakan ekspresi yang tidak valid tidak akan berfungsi di sana (dan nilai yang tidak valid tidak dapat digunakanCREATE TABLE
karena itu divalidasi), dan saya tidak punya waktu untuk membuat tes kinerja. Tetapi saya menduga bahwa sebagian besar RDBMS akan memperlakukan mereka dengan cara yang sama.Saya melihat tidak ada kerugian yang signifikan dalam memiliki kendala standar. Bahkan, saya melihat satu keuntungan khusus - Anda telah mendefinisikan default pada level logika yang sama dengan definisi tabel itu sendiri. Jika Anda memiliki nilai default yang Anda berikan dalam prosedur tersimpan Anda, seseorang harus pergi ke sana untuk mencari tahu apa nilai defaultnya; dan, itu bukan sesuatu yang akan jelas bagi seseorang yang baru dalam sistem, tentu saja (jika, misalnya, Anda mewarisi satu miliar dolar besok, membeli pulau tropis Anda sendiri, dan berhenti dan pindah ke sana, meninggalkan beberapa getah miskin lainnya untuk memikirkan hal-hal keluar sendiri).
sumber