Saya belum melakukan studi formal, tetapi dari pengalaman saya sendiri, saya menduga bahwa lebih dari 80% kelemahan desain database dihasilkan dari desain dengan kinerja sebagai pertimbangan yang paling penting (jika tidak hanya).
Jika desain yang baik membutuhkan beberapa tabel, buat beberapa tabel. Jangan secara otomatis berasumsi bahwa bergabung adalah sesuatu yang harus dihindari. Mereka jarang menjadi penyebab sebenarnya dari masalah kinerja.
Pertimbangan utama, pertama dan terpenting dalam semua tahap desain database, adalah integritas data. "Jawabannya mungkin tidak selalu benar, tetapi kami dapat memberikannya kepada Anda dengan sangat cepat" bukanlah tujuan yang harus dicapai oleh toko mana pun. Setelah integritas data dikunci, jika kinerja menjadi masalah , dapat diatasi. Jangan mengorbankan integritas data, terutama untuk memecahkan masalah yang mungkin tidak ada.
Dengan mengingat hal itu, lihat apa yang Anda butuhkan. Anda memiliki pengamatan yang perlu Anda simpan. Pengamatan ini dapat bervariasi dalam jumlah dan jenis atribut dan dapat berupa hal-hal seperti nilai pengukuran, pemberitahuan suatu peristiwa dan perubahan status, antara lain dan dengan kemungkinan pengamatan di masa mendatang ditambahkan.
Ini tampaknya cocok dengan pola "tipe/subtipe" standar, dengan entri "Pengamatan" menjadi tipe dan setiap tipe atau jenis pengamatan menjadi subtipe, dan menyarankan beberapa bentuk bidang indikator tipe seperti:
create table Observations(
...,
ObservationKind char( 1 ) check( ObservationKind in( 'M', 'E', 'S' )),
...
);
Tetapi hardcoding daftar seperti ini dalam batasan pemeriksaan memiliki tingkat rawatan yang sangat rendah. Itu menjadi bagian dari skema dan hanya dapat diubah dengan pernyataan DDL. Bukan sesuatu yang diharapkan DBA Anda.
Jadi, miliki jenis pengamatan di tabel pencarian mereka sendiri:
ID Name Meaning
== =========== =======
M Measurement The value of some system metric (CPU_Usage).
E Event An event has been detected.
S Status A change in a status has been detected.
(Bidang char bisa berupa int atau smallint. Saya menggunakan char di sini sebagai ilustrasi.)
Kemudian isi tabel Pengamatan dengan PK dan atribut yang akan umum untuk semua pengamatan.
create table Observations(
ID int identity primary key,
ObservationKind char( 1 ) not null,
DateEntered date not null,
...,
constraint FK_ObservationKind foreign key( ObservationKind )
references ObservationKinds( ID ),
constraint UQ_ObservationIDKind( ID, ObservationKind )
);
Mungkin tampak aneh untuk membuat indeks unik pada kombinasi bidang Kind dan PK, yang unik dengan sendirinya, tetapi bersabarlah sebentar.
Sekarang setiap jenis atau subtipe mendapatkan tabelnya sendiri. Perhatikan bahwa setiap jenis pengamatan mendapatkan tabel, bukan tipe datanya.
create table Measurements(
ID int not null,
ObservationKind char( 1 ) check( ObservationKind = 'M' ),
Name varchar( 32 ) not null, -- Such as "CPU Usage"
Value double not null, -- such as 55.00
..., -- other attributes of Measurement observations
constraint PK_Measurements primary key( ID, ObservationKind ),
constraint FK_Measurements_Observations foreign key( ID, ObservationKind )
references Observations( ID, ObservationKind )
);
Dua bidang pertama akan sama untuk jenis pengamatan lainnya kecuali batasan pemeriksaan akan memaksa nilai ke jenis yang sesuai. Kolom lainnya mungkin berbeda dalam jumlah, nama, dan tipe data.
Mari kita periksa contoh tupel yang mungkin ada di tabel Pengukuran:
ID ObservationKind Name Value ...
==== =============== ========= =====
1001 M CPU Usage 55.0 ...
Agar tupel ini ada dalam tabel ini, entri yang cocok harus terlebih dahulu ada di tabel Pengamatan dengan nilai ID 1001 dan nilai jenis pengamatan 'M'. Tidak ada entri lain dengan nilai ID 1001 yang bisa ada di tabel Pengamatan atau tabel Pengukuran dan tidak bisa ada sama sekali di tabel "jenis" lainnya (Peristiwa, Status). Ini bekerja dengan cara yang sama untuk semua jenis tabel.
Saya akan merekomendasikan lebih lanjut untuk membuat tampilan untuk setiap jenis pengamatan yang akan memberikan gabungan dari setiap jenis dengan tabel pengamatan utama:
create view MeasurementObservations as
select ...
from Observations o
join Measurements m
on m.ID = o.ID;
Kode apa pun yang hanya berfungsi dengan pengukuran hanya perlu mencapai tampilan ini alih-alih tabel yang mendasarinya. Menggunakan tampilan untuk membuat dinding abstraksi antara kode aplikasi dan data mentah sangat meningkatkan kemampuan pemeliharaan database.
Sekarang pembuatan jenis observasi lain, seperti "Error", melibatkan pernyataan Insert sederhana ke tabel ObservationKinds:
F Fault A fault or error has been detected.
Tentu saja, Anda perlu membuat tabel dan tampilan baru untuk pengamatan kesalahan ini, tetapi hal itu tidak akan berdampak pada tabel, tampilan, atau kode aplikasi yang ada (kecuali, tentu saja, untuk menulis kode baru agar berfungsi dengan pengamatan baru) .