Apakah tampilan bersarang merupakan desain basis data yang baik?

42

Saya telah membaca suatu tempat sejak lama. Buku ini menyatakan bahwa kita tidak boleh membiarkan memiliki tampilan bersarang di SQL Server. Saya tidak yakin alasan mengapa kita tidak bisa melakukan itu atau saya mungkin ingat pernyataan yang salah.

Siswa

SELECT studentID, first_name, last_name, SchoolID, ... FROM students

CREATE VIEW vw_eligible_student
AS 
SELECT * FROM students
WHERE enroll_this_year = 1

Guru

SELECT TeacherID, first_name, last_name, SchoolID, ... FROM teachers

CREATE VIEW vw_eligible_teacher
AS 
SELECT * FROM teachers
WHERE HasCert = 1 AND enroll_this_year = 1

Sekolah

CREATE VIEW vw_eligible_school
AS 
SELECT TOP 100 PERCENT SchoolID, school_name 

FROM schools sh 
JOIN
     vw_eligible_student s 
     ON s.SchoolID = sh.SchoolID
JOIN 
     vw_eligible_teacher t
     ON s.SchoolID = t.SchoolID

Di tempat kerja saya, saya telah menyelidiki salah satu aplikasi basis data kami sendiri. Saya memeriksa benda-benda yang ditemukan bahwa ada dua atau tiga lapisan tampilan yang saling bertumpuk. Jadi itu mengingatkan saya tentang apa yang saya baca di masa lalu. Adakah yang bisa menjelaskannya?

Jika tidak OK untuk melakukannya, saya ingin tahu bahwa itu terbatas pada SQL Server atau untuk desain database secara umum.

Info Tambahan: Saya memperbarui contoh dari perusahaan saya. Saya mengubah sedikit menjadi lebih umum tanpa terlalu banyak teknis (terlalu banyak kolom dalam contoh ini). Sebagian besar tampilan bersarang yang kami gunakan didasarkan pada tampilan abstrak atau agregat. Sebagai contoh, kami memiliki meja siswa besar dengan ratusan kolom. Katakanlah, Eligible Student Viewdidasarkan pada siswa yang mendaftar tahun ini. Dan pandangan siswa yang memenuhi syarat dapat menggunakan tempat lain seperti dalam prosedur tersimpan.

Richard Sayakanit
sumber
3
Saya akan menyampaikan bahwa pro dan kontra yang sama kira-kira akan menyamakan terlepas dari platform tertentu.
Aaron Bertrand

Jawaban:

47

Terlepas dari platform, pernyataan berikut ini berlaku.

(-) Tampilan bersarang:

  • lebih sulit untuk dipahami dan di-debug

    misal kolom tabel apa yang dimaksud kolom tampilan ini? Saya akan menggali melalui 4 level definisi tampilan ...

  • mempersulit pengoptimal kueri untuk membuat rencana kueri yang paling efisien

    Lihat ini , ini , ini , dan ini untuk bukti anekdotal. Bandingkan dengan ini , yang menunjukkan bahwa pengoptimal sering kali cukup pintar untuk membongkar dengan benar tampilan bersarang dan memilih paket optimal, tetapi bukan tanpa biaya kompilasi.

    Anda dapat mengukur biaya kinerja dengan membandingkan kueri tampilan dengan yang setara dengan tabel dasar.

(+) Di sisi lain, tampilan bersarang memungkinkan Anda:

  • memusatkan dan menggunakan kembali agregasi atau aturan bisnis
  • abaikan struktur dasar Anda (katakanlah, dari pengembang basis data lainnya)

Saya menemukan bahwa mereka jarang diperlukan.


Dalam contoh Anda, Anda menggunakan tampilan bersarang untuk memusatkan dan menggunakan kembali definisi bisnis tertentu (mis. "Apakah siswa yang memenuhi syarat?"). Ini adalah penggunaan yang valid untuk tampilan bersarang. Jika Anda memelihara atau menyetel basis data ini, timbang biaya untuk mempertahankannya dibandingkan dengan menghapusnya.

  • Tetap: Dengan menjaga pandangan bersarang Anda mendapatkan keuntungan dan kerugian yang disebutkan di atas.

  • Hapus: Untuk menghapus tampilan bersarang:

    1. Anda perlu mengganti semua kemunculan tampilan dengan permintaan dasar mereka.

    2. Anda harus ingat untuk memperbarui semua pertanyaan yang relevan jika definisi Anda tentang siswa / guru / sekolah yang berubah, bukan hanya memperbarui definisi tampilan yang relevan.

Nick Chammas
sumber
1
+1, kecuali saya akan mengganti "lebih keras" untuk pengoptimal kueri, dengan "hampir tidak mungkin". :)
Jason
1
@Jason - Saya setuju, dan saya berharap saya bisa menautkan ke beberapa contoh nyata. Apakah Anda tahu ada referensi yang menjelaskan atau menunjukkan mengapa demikian?
Nick Chammas
1
Yang bisa saya temukan adalah bukti anekdotal bahwa ketika pandangan bersarang digunakan, mereka mengalami masalah kinerja dibandingkan dengan SQL "rata". sqlservercentral.com/blogs/2cents/archive/2010/04/05/... Masalahnya muncul karena fakta bahwa DB (SQL Server dalam kasus ini) tidak akan menerapkan filter tertentu sebelum bergabung dengan tabel, dan karenanya akan membuat kueri memakan waktu lebih lama dari yang seharusnya.
Jason
7
Saya tidak setuju pada masalah optimizer kueri, karena kueri yang dihasilkan setelah menyelesaikan semua tampilan akan sama tidak peduli berapa banyak transformasi tampilan yang telah dilaluinya (kecuali beberapa kolom tambahan dalam set hasil menengah, yang dapat dihilangkan oleh optimizer dengan baik). Ini meninggalkan debugging; IMO membuat debugging lebih mudah untuk memiliki tampilan bersarang karena saya bisa melihat hasil antara untuk melihat di mana ia salah.
Simon Richter
1
Saya telah menulis server database tertanam, dan bagi saya, menyelesaikan pandangan pertama dan kemudian mengoptimalkan permintaan yang dihasilkan adalah rute yang jelas, karena sebenarnya sangat tidak mungkin bahwa semua permintaan pada tampilan akan mengembalikan semua kolom. Saya bahkan tidak bisa memikirkan alasan mengapa mewujudkan data tampilan di tengah kueri akan mendapatkan sesuatu, jadi itu adalah no-brainer bagi saya.
Simon Richter
26

Terkadang tampilan bersarang digunakan untuk mencegah pengulangan agregat. Katakanlah Anda memiliki tampilan yang menghitung pesan dan mengelompokkannya menurut userid, Anda mungkin memiliki pandangan terhadap jumlah yang menghitung jumlah pengguna yang memiliki> 100 pesan, hal semacam itu. Ini paling efektif ketika tampilan dasar adalah tampilan yang diindeks - Anda belum tentu ingin membuat lagi tampilan yang diindeks untuk mewakili data dengan pengelompokan yang sedikit berbeda, karena sekarang Anda membayar pemeliharaan indeks dua kali di mana kinerja mungkin memadai terhadap tampilan asli.

Jika ini semua hanya tampilan bersarang di mana Anda melakukan pilih * tetapi mengubah urutan atau atas, tampaknya ini akan lebih baik dienkapsulasi sebagai prosedur tersimpan dengan parameter (atau fungsi bernilai tabel inline) daripada sekelompok tampilan bersarang. MENURUT OPINI SAYA.

Aaron Bertrand
sumber
4
"Ini paling efektif ketika tampilan dasar adalah tampilan yang diindeks." Poin penting.
Nick Chammas
7

Versi SQL yang lebih baru (2005+) tampaknya lebih baik dalam mengoptimalkan penggunaan tampilan. Tampilan terbaik untuk mengkonsolidasikan aturan bisnis. EG: tempat saya bekerja, kami memiliki basis data produk telekomunikasi. Setiap produk ditugaskan ke rateplan, dan rateplan itu dapat ditukar, dan tarif pada rateplan dapat diaktifkan / dinonaktifkan karena tarif dinaikkan atau dimodifikasi.

Untuk membuatnya mudah, kita dapat membuat tampilan bersarang. Tampilan pertama hanya menggabungkan rateplan ke tarifnya menggunakan tabel apa pun yang diperlukan, dan mengembalikan data yang diperlukan tingkat tampilan berikutnya. Tampilan kedua hanya dapat mengisolasi rateplan aktif dan laju aktifnya. Atau, hanya tarif pelanggan. Atau tarif karyawan (untuk diskon karyawan). Atau tarif bisnis vs. pelanggan residensial. (rateplan bisa menjadi rumit). Intinya adalah, pandangan dasar memastikan logika bisnis keseluruhan kami untuk rateplan dan tarif digabung bersama dengan benar di satu lokasi. Lapisan tampilan selanjutnya memberi kita lebih banyak fokus pada rateplan spesifik (tipe, aktif / tidak aktif, dll).

Saya setuju bahwa tampilan dapat membuat debugging menjadi berantakan jika Anda membuat permintaan dan tampilan secara bersamaan. Tetapi, jika Anda menggunakan tampilan yang dicoba-n-tepercaya, itu membuat proses debug lebih mudah. Anda tahu bahwa pandangan telah melalui dering, jadi Anda tahu itu kemungkinan besar tidak menyebabkan masalah.

Namun, masalah bisa muncul dengan pandangan Anda. "Bagaimana jika suatu produk hanya dikaitkan dengan rateplan yang tidak aktif?" atau "bagaimana jika rateplan hanya memiliki tingkat tidak aktif di atasnya?" Nah, itu bisa tertangkap di level front-end dengan logika yang menangkap kesalahan pengguna. "Kesalahan, produk berada pada rateplan yang tidak aktif ... mohon perbaiki". Kami juga dapat menjalankan audit kueri untuk memeriksa ulang sebelum menjalankan penagihan. (pilih semua paket dan gabung kiri ke tampilan rateplan aktif, hanya kembalikan paket yang tidak mendapatkan rateplan aktif sebagai masalah yang perlu ditangani).

Hal yang baik tentang hal ini adalah pandangan yang memungkinkan Anda menyingkat permintaan untuk pelaporan, penagihan, dll. Anda dapat memiliki tampilan akun pelanggan, kemudian tampilan tingkat 2 dari pelanggan yang aktif saja. Tim itu dengan tampilan alamat pelanggan. Tim yang dengan tampilan produk (bergabung dengan produk apa yang dimiliki pelanggan). Tim itu untuk melihat produk rateplan. Tim itu dengan tampilan fitur produk. Lihat, lihat, lihat, setiap percobaan-n-kesalahan untuk memastikan integritas. Permintaan akhir Anda menggunakan tampilan sangat kompak.

edit:

Sebagai contoh bagaimana tampilan akan lebih baik daripada sekadar kueri tabel yang datar ... kami memiliki kontraktor temporer yang datang untuk membuat beberapa perubahan. Mereka mengatakan kepadanya bahwa ada beberapa hal yang dilihat, tetapi dia memutuskan untuk meratakan semua pertanyaannya. Penagihan menjalankan beberapa pertanyaannya. Mereka terus mendapatkan banyak rateplan dan tarif untuk berbagai hal. Ternyata pertanyaannya kriteria yang hilang hanya memungkinkan tarif untuk menagih jika mereka berada di antara tanggal awal & akhir rencana tingkat seharusnya menggunakan tarif itu / mereka selama. Ups. Jika dia menggunakan pandangan itu, itu sudah memperhitungkan logika itu.

Pada dasarnya, Anda harus mempertimbangkan kinerja vs kewarasan. Mungkin Anda bisa melakukan semua jenis barang mewah untuk meningkatkan kinerja database. Tetapi, jika itu berarti mimpi buruk bagi orang baru untuk mengambil alih / mempertahankan, apakah itu benar-benar layak? Apakah itu benar-benar layak bagi orang baru yang harus bermain memukul-mondar-mandir harus menemukan semua pertanyaan yang perlu untuk mengubah logika mereka (dan risiko dia lupa / gemar meraba mereka) b / c seseorang memutuskan bahwa pandangan "buruk" dan tidak menggabungkan beberapa logika bisnis inti menjadi logika yang dapat digunakan di 100 pertanyaan lainnya? Ini benar-benar terserah pada bisnis Anda dan tim IT / IS / DB Anda. Tapi, saya lebih suka kejelasan dan konsolidasi sumber tunggal daripada kinerja.

bla bla
sumber
4

Masalah sebenarnya bukanlah pandangan bersarang dalam diri mereka sendiri. Masalah sebenarnya adalah proliferasi pandangan bersarang sebagai pengembang lapisan tweak tambahan pada pandangan yang ada. Saya telah menemukan pertanyaan dengan tampilan bersarang 4 lapisan yang benar-benar bergabung dengan salah satu tampilan dalam definisi itu. Kecenderungan kami untuk mengambil jalan keluar yang mudah alih-alih menganalisis dan memecahkan masalah adalah akar masalah.

sinar
sumber
0

Di lingkungan saya, kami mereplikasi banyak tabel dari server produksi ke server laporan. Pada server laporan, kami memiliki banyak tampilan yang didasarkan pada tabel produksi yang direplikasi DAN disarangkan. Sebelum replikasi dimulai, kami harus menghapus semua tampilan untuk memungkinkan replikasi (kami menggunakan drop dan buat karena struktur tabel sering berubah dalam produksi). Setelah replikasi berakhir, kita harus membangun kembali semua pandangan.

Sekarang inilah bagian yang menyenangkan: Karena banyak pandangan yang bersarang, kita harus membangunnya kembali dalam urutan tertentu. Saat membuat perubahan apa pun dalam definisi tampilan, kita harus memperhatikan untuk menjaga agar urutan pembangunan kembali yang benar. Ini berantakan total. Saya sangat tidak menyarankan menggunakan tampilan bersarang jika Anda menggunakan replikasi atau hanya menjatuhkan dan membangun kembali tabel Anda, yang merupakan sumber untuk tampilan.

Kinerja adalah hal lain. Tampilan yang didasarkan pada tampilan lain tidak lain adalah beberapa query untuk dieksekusi. Lebih mudah untuk menyatukan kueri yang lebih besar, menciptakan pekerjaan, dan membuat tabel darinya. Lebih mudah dan meningkatkan kinerja.

Narwhal
sumber