Saya mewarisi aplikasi yang mengaitkan berbagai jenis kegiatan dengan situs. Ada sekitar 100 jenis aktivitas yang berbeda, dan masing-masing memiliki set bidang yang berbeda 3-10. Namun, semua aktivitas memiliki setidaknya satu bidang tanggal (bisa berupa kombinasi tanggal, tanggal mulai, tanggal akhir, tanggal mulai yang dijadwalkan, dll.), Dan satu bidang orang yang bertanggung jawab. Semua bidang lainnya sangat bervariasi dan bidang tanggal mulai tidak harus disebut "Tanggal Mulai".
Membuat satu tabel subtipe untuk setiap jenis aktivitas akan menghasilkan skema dengan 100 tabel subtipe berbeda, yang akan terlalu sulit untuk dihadapi. Solusi saat ini untuk masalah ini adalah untuk menyimpan nilai aktivitas sebagai pasangan nilai kunci. Ini adalah skema yang sangat disederhanakan dari sistem saat ini untuk menyampaikan maksudnya.
Setiap Kegiatan memiliki beberapa ActivityFields; setiap Situs memiliki beberapa Kegiatan, dan tabel SiteActivityData menyimpan KVP untuk setiap SiteActivity.
Ini membuat aplikasi (berbasis web) sangat mudah untuk dikodekan karena yang perlu Anda lakukan hanyalah mengulang catatan di SiteActivityData untuk aktivitas tertentu dan menambahkan label dan kontrol input untuk setiap baris ke formulir. Tetapi ada banyak masalah:
- Integritas buruk; dimungkinkan untuk meletakkan bidang di SiteActivityData yang bukan milik tipe aktivitas, dan DataValue adalah bidang varchar sehingga angka dan tanggal harus terus-menerus dilemparkan.
- Pelaporan dan permintaan ad-hoc data ini sulit, rawan kesalahan, dan lambat. Misalnya, mendapatkan daftar semua aktivitas dari jenis tertentu yang memiliki Tanggal Berakhir dalam rentang yang ditentukan membutuhkan pivot dan casting varchars ke tanggal. Penulis laporan BENCI skema ini, dan saya tidak menyalahkan mereka.
Jadi yang saya cari adalah cara untuk menyimpan sejumlah besar kegiatan yang hampir tidak memiliki bidang yang sama sehingga membuat pelaporan menjadi lebih mudah. Sejauh ini yang saya pikirkan adalah menggunakan XML untuk menyimpan data aktivitas dalam format pseudo-noSQL:
Tabel Aktivitas akan berisi XSD untuk setiap aktivitas, menghilangkan kebutuhan untuk tabel ActivityField. SiteActivity akan berisi nilai kunci XML sehingga setiap aktivitas untuk situs sekarang akan berada dalam satu baris.
Suatu kegiatan akan terlihat seperti ini (tapi saya belum menyempurnakannya sepenuhnya):
<SomeActivityType>
<SomeDateField type="StartDate">2000-01-01</SomeDateField>
<AnotherDateField type="EndDate">2011-01-01</AnotherDateField>
<EmployeeId type="ResponsiblePerson">1234</EmployeeId>
<SomeTextField>blah blah</SomeTextField>
...
Keuntungan:
- XSD akan memvalidasi XML, menangkap kesalahan seperti meletakkan string di bidang angka di tingkat database, sesuatu yang tidak mungkin dengan skema lama yang menyimpan segala sesuatu di varchar.
- Recordset KVP yang digunakan untuk membangun formulir web dapat dengan mudah direproduksi menggunakan
select ... from ActivityXML.nodes('/SomeActivityType/*') as T(r)
- Subquery xpath dari XML dapat digunakan untuk menghasilkan set hasil yang memiliki kolom untuk tanggal mulai, tanggal akhir, dll tanpa menggunakan pivot, sesuatu seperti
select ActivityXML.value('.[@type=StartDate]', 'datetime') as StartDate, ActivityXML.value('.[@type=EndDate]', 'datetime') as EndDate from SiteActivity where...
Apakah ini sepertinya ide yang bagus? Saya tidak bisa memikirkan cara lain untuk menyimpan sejumlah besar set properti yang berbeda. Pikiran lain yang saya miliki adalah menjaga skema yang ada dan menerjemahkannya menjadi sesuatu yang lebih mudah di-query di gudang data, tetapi saya belum pernah merancang skema bintang sebelumnya dan tidak tahu harus mulai dari mana.
Pertanyaan tambahan: Jika saya mendefinisikan tag sebagai memiliki tipe data tanggal dalam XSD menggunakan xs:date
, apakah SQL Server akan mengindeksnya sebagai nilai tanggal? Saya khawatir jika saya kueri berdasarkan tanggal, maka string tanggal harus dilemparkan ke nilai tanggal dan menghancurkan peluang menggunakan indeks.