Kapan saya harus menggunakan prosedur tersimpan?

19

Jika saya memiliki semua logika bisnis saya dalam kode dan menggunakan Entity Framework, dalam situasi apa (jika ada) saya akan lebih baik memindahkan beberapa logika bisnis ke prosedur tersimpan, daripada menyimpannya semua dalam kode?

Agar lebih jelas, maksud saya bersamaan dengan pengaturan saat ini (logika bisnis dalam kode), bukan sebagai ganti. Saya telah melihat sejumlah pertanyaan serupa yang meminta pro dan kontra memiliki semua logika bisnis dalam prosedur tersimpan, tetapi saya belum menemukan banyak tentang penggunaan prosedur tersimpan hemat untuk logika kasus tepi, sambil tetap menjaga sisa logika bisnis dalam kode.

Jika ada bedanya, saya menggunakan MSSQL dan Entity Framework.


Ini adalah situasi di mana saya telah menggunakan prosedur tersimpan sebelumnya:

  • Laporan rumit yang memerlukan waktu beberapa menit untuk dijalankan (ini adalah halaman di aplikasi web). Saya menemukan saya bisa menulis SQL yang jauh lebih efisien (hanya butuh beberapa detik untuk menjalankan) daripada apa yang disediakan LINQ.
  • Aplikasi web perlu membaca dan menulis ke beberapa tabel pada database terpisah yang berisi banyak informasi sensitif lainnya yang tidak relevan dengan aplikasi tersebut. Daripada memberikannya akses ke semuanya, saya menggunakan prosedur tersimpan yang hanya melakukan apa yang dibutuhkan, dan hanya mengembalikan informasi terbatas. Aplikasi web kemudian dapat diberikan akses ke prosedur tersimpan ini saja, tanpa akses ke tabel apa pun dll.

Posting lain yang telah saya lihat sebelum mengajukan pertanyaan ini:

Amy Barrett
sumber
4
Kedua situasi Anda adalah alasan yang sah untuk menulis prosedur tersimpan. Apakah Anda bertanya mengapa itu sah?
Robert Harvey
@RobertHarvey Saya memastikan mereka sah dan mencari skenario atau alasan lain mengapa Anda membuat pengecualian dan menulis prosedur tersimpan daripada menyimpannya dalam kode.
Amy Barrett
Anda akan membuat pengecualian dan menulis prosedur tersimpan ketika Anda memutuskan bahwa itu memecahkan masalah lebih baik daripada teknik lain yang tersedia untuk Anda, yang persis apa yang Anda lakukan.
Robert Harvey

Jawaban:

10

Anda sudah memiliki beberapa skenario yang sangat bagus.

Ada banyak alasan lain juga. EF sangat pandai dalam CRUD dan dalam pelaporan yang cukup mudah. Namun, kadang-kadang, EF bukanlah alat yang sempurna. Beberapa alasan lain (skenario) untuk mempertimbangkan penggunaan prosedur tersimpan dalam kombinasi dengan Entity Framework akan mencakup:

  • Anda memiliki unit kerja yang kompleks, mungkin melibatkan banyak tabel, yang tidak dapat dibungkus dalam suatu transaksi dengan mudah menggunakan fitur EF.
  • Basis data Anda tidak cocok dengan EF karena gagal memanfaatkan integritas referensial deklaratif (batasan kunci asing). Ini biasanya merupakan skenario buruk untuk ditemukan, tetapi terkadang ada skenario yang sesuai, seperti database yang digunakan untuk proses ETL.
  • Anda perlu bekerja dengan data yang melintasi batas server dengan server tertaut.
  • Anda memiliki skenario pengambilan data yang sangat kompleks di mana "bare metal" SQL diperlukan untuk memastikan kinerja yang memadai. Misalnya, Anda memiliki gabungan kompleks yang memerlukan petunjuk kueri untuk berfungsi dengan baik dalam situasi spesifik Anda.
  • Aplikasi Anda tidak memiliki izin CRUD penuh di atas meja, tetapi aplikasi Anda dapat diizinkan berjalan di bawah konteks keamanan yang dipercayai oleh server Anda (misalnya identitas aplikasi, bukan identitas pengguna). Ini mungkin muncul dalam situasi di mana DBA membatasi akses tabel ke procs yang disimpan hanya karena memberikan mereka kontrol lebih rinci tentang siapa yang bisa melakukan apa.

Saya yakin ada banyak lagi selain ini. Cara untuk menentukan jalur terbaik ke depan dalam keadaan tertentu adalah dengan menggunakan akal sehat dan untuk fokus pada tujuan utama, yang harus menulis kode kualitas tinggi, mudah dikelola. Pilih alat yang memberi Anda hasil ini dalam setiap kasus.

Joel Brown
sumber
Terima kasih Joel, Anda telah menyebutkan beberapa skenario lain yang tidak saya pikirkan.
Amy Barrett
Jawaban bagus. Namun, saya bertanya-tanya apakah Anda memiliki banyak pengguna yang terhubung ke database dan menjalankan kueri yang rumit atau prosedur yang tersimpan, tidakkah Anda akan meletakkan banyak beban pada server database?
Ripal Barot
1
@RipalBarot Tidak ada pertanyaan bahwa semakin banyak yang terjadi dengan beban kerja (semakin banyak pengguna, semakin banyak pertanyaan kompleks), semakin banyak tuntutan di server database Anda. Satu hal yang perlu diingat, bagaimanapun, adalah bahwa menggunakan prosedur tersimpan daripada ORM seperti Entity Framework sering mengurangi beban kerja (komparatif) karena prosedur tersimpan dapat memiliki rencana kueri yang telah dikompilasi sebelumnya. Ketika kueri datang dari ORM, DBMS sering harus mulai dengan mengetahui cara menangani kueri. Saat Anda memanggil prosedur tersimpan yang setara, basis data sudah tahu cara memenuhinya secara efisien.
Joel Brown
2

Mungkin masuk akal, untuk membalikkan pertanyaan dan menemukan usecases di mana hanya prosedur tersimpan dapat melakukan, apa yang ingin Anda capai. Mungkin benar-benar ada kasus penggunaan, di mana prosedur tersimpan menonjol.

Jika ada bedanya, saya menggunakan MSSQL dan Entity Framework.

Pengetahuan saya tentang EF terbatas, tetapi sejauh yang saya bisa lihat, EF ( hanya ) ORM seperti yang lainnya; dan untungnya mampu menggunakan SQL mentah .

Jika saya mengambil dua poin utama Anda:

Laporan rumit yang memerlukan waktu beberapa menit untuk dijalankan (ini adalah halaman di aplikasi web). Saya menemukan saya bisa menulis SQL yang jauh lebih efisien (hanya butuh beberapa detik untuk menjalankan) daripada apa yang disediakan LINQ.

LINQ / EF gagal, saat melakukan laporan. Dan seperti yang Anda perhatikan, SQLjauh lebih cepat, daripada menggunakan ORM. Tetapi apakah ini mendukung prosedur tersimpan atau hanya menentang penggunaan ORM untuk semuanya?

Masalah Anda jelas dapat diselesaikan dengan SQL . Jika kueri itu disimpan dan versi yang dikontrol dalam basis kode Anda membuat - sesuai dengan contoh Anda - setidaknya tidak ada perbedaan .

Aplikasi web perlu membaca dan menulis ke beberapa tabel pada database terpisah yang berisi banyak informasi sensitif lainnya yang tidak relevan dengan aplikasi tersebut. Daripada memberikannya akses ke semuanya, saya menggunakan prosedur tersimpan yang hanya melakukan apa yang dibutuhkan, dan hanya mengembalikan informasi terbatas. Aplikasi web kemudian dapat diberikan akses ke prosedur tersimpan ini saja, tanpa akses ke tabel apa pun dll.

Hal yang sama di sini: string koneksi sederhana dan dan PEMBARUAN dan masalah Anda selesai. Masalah ini dapat diselesaikan bahkan dengan ORM : cukup gunakan layanan web di depan DB lain dan kompartementalisasi / isolasi yang sama tercapai.

Jadi tidak ada yang bisa dilihat di sini.

Melihat beberapa poin yang dibuat orang lain:

Anda memiliki unit kerja yang kompleks, mungkin melibatkan banyak tabel, yang tidak dapat dibungkus dalam suatu transaksi dengan mudah menggunakan fitur EF.

Tetapi SQLbisa melakukan itu. Tidak ada sihir yang terlibat di sini.

Basis data Anda tidak cocok dengan EF

Lagi: Gunakan EF saat yang tepat.

Anda perlu bekerja dengan data yang melintasi batas server dengan server tertaut

Saya tidak melihat, bagaimana prosedur yang tersimpan membantu. Jadi saya tidak bisa melihat keuntungan dari prosedur yang tersimpan; tapi mungkin seseorang menjelaskan hal itu.

Anda memiliki skenario pengambilan data yang sangat kompleks di mana "bare metal" SQL diperlukan untuk memastikan kinerja yang memadai

Lagi: "Batas EF ".

Aplikasi Anda tidak memiliki izin CRUD penuh di atas meja, tetapi aplikasi Anda dapat diizinkan berjalan di bawah konteks keamanan yang dipercayai oleh server Anda

Baik. Saya pergi dengan mungkin .

Sejauh ini hanya setengah poin yang mendukung prosedur yang tersimpan.


Mungkin ada pertimbangan kinerja, yang mendukung prosedur tersimpan.

1) Menyimpan kueri memiliki manfaat dari panggilan sederhana ke prosedur tersimpan yang merangkum kompleksitas. Karena perencana kueri mengetahui kueri, maka "lebih mudah" untuk mengoptimalkan. Tapi penghematannya adalah perencana kueri canggih saat ini _minimal.

Di atas semua itu, bahkan jika ada sedikit biaya menggunakan pertanyaan ad hoc , jika data Anda terstruktur dengan baik dan diindeks dengan hati-hati, database hanyalah hambatan dari aplikasi Anda. Jadi, bahkan jika ada delta kecil, itu dapat diabaikan mengingat faktor-faktor lain.

2) Namun demikian ia berpendapat untuk menyimpan pertanyaan kompleks dalam DB. Ada dua hal yang perlu dipertimbangkan:

a) kueri yang kompleks memanfaatkan infrastruktur DB secara masif, yang meningkatkan waktu asnwering untuk setiap kueri lainnya. Anda tidak dapat menjalankan banyak permintaan mahal secara paralel . Ini tidak berbicara pro atau kontra prosedur tersimpan, tetapi terhadap pertanyaan kompleks .

b) Jika kueri membutuhkan waktu, mengapa harus repot dengan kemenangan kecil dari prosedur tersimpan.

tl; dr

Tidak ada yang berbicara langsung terhadap prosedur tersimpan. Jadi menggunakan prosedur tersimpan tidak masalah - jika itu membuat Anda bahagia.

Tapi di sisi lain: Saya tidak bisa membayangkan yang tepat kasus penggunaan yang berbicara tegas pro.

Kapan saya harus menggunakan prosedur tersimpan?

Jawaban yang tepat adalah: Kapan pun Anda suka . Tetapi ada opsi lain.

Thomas Junk
sumber
0

Untuk kasus spesifik Anda, karena Anda menggunakan kerangka entitas, orang harus mempertimbangkan menggunakan prosedur tersimpan ketika kerangka entitas gagal memenuhi persyaratan atau masalah.

Kerangka kerja entitas melakukan pekerjaan yang layak dan kinerja akan dekat atau sama dengan menggunakan prosedur yang tersimpan. Anda memilih kerangka entitas karena Anda tidak ingin peduli dengan SQL dan akan membiarkan kerangka kerja menghasilkan SQL untuk Anda.

Tetapi mungkin ada kasus tepi di mana kerangka kerja entitas gagal dan tidak dapat memenuhi kebutuhan Anda. Dalam hal ini orang akan menulis SQL dengan tangan menggunakan prosedur tersimpan atau permintaan parameter dan kemudian menggunakan kerangka kerja entitas untuk memanggil prosedur tersimpan / pernyataan SQL secara langsung.

Jadi, saya tidak akan memindahkan apa pun ke prosedur tersimpan kecuali kerangka kerja yang digunakan tidak dapat memenuhi persyaratan.

Saya pikir hal terburuk yang dapat terjadi adalah seseorang memilih untuk menggunakan kerangka kerja entitas dan kemudian menulis semua prosedur tersimpan. Sekarang seseorang memiliki lapisan tambahan yang tidak menambah nilai.

Jon Raynor
sumber
100% setuju dengan paragraf terakhir
Ewan
0

Memiliki kebutuhan teknis bukanlah pilihan yang paling mungkin. Pemrogram lebih suka alat mereka dan biasanya lebih beradaptasi dalam memecahkan masalah mereka dengan mereka. Menempatkan logika dalam sproc akan menjadi pengecualian. Utang teknis dan pengembang masa depan harus meluangkan waktu untuk bekerja dengan pengecualian harus dipertimbangkan. Mungkin ada peningkatan kinerja dalam RDBMS khusus Anda yang hanya lebih mudah diimplementasikan dalam sproc atau mungkin bahkan objek db lain seperti tampilan yang diindeks.

Akan ada saat-saat ketika Anda membutuhkan data dari database dan Anda tidak bisa mendapatkannya dari kode aplikasi Anda. Dalam banyak situasi perusahaan / perusahaan besar, kebutuhan bisnis dapat melebihi genggaman Departemen TI. Perusahaan dibeli dan dijual dan aplikasi mereka datang dan pergi bersama mereka. Agensi pengatur dan bank tidak peduli jika Anda tidak bisa membuat aplikasi Anda yang memiliki skalabilitas tinggi dan kode indah. Mereka dapat membuat hidup menjadi sulit untuk bisnis, jadi Anda harus menyelesaikannya.

Saya telah mengalami situasi di mana aplikasi Pihak Ketiga atau alat penulisan laporan tidak memungkinkan Anda memahami kode Anda. Tidak ada kode sumber terbuka, tidak ada API, tidak ada antarmuka web dan tidak ada layanan. Satu-satunya yang mereka miliki adalah alat penulisan laporan khusus mereka sendiri yang hanya berfungsi dengan objek basis data: tabel, tampilan, sprocs, fungsi yang ditentukan pengguna, dll. Anda menempatkan logika di mana pun Anda bisa mendapatkannya.

Jika Anda memiliki DBA yang sangat baik dalam menulis prosedur tersimpan, Anda dapat memanfaatkan bakat itu dalam beberapa situasi. Anda mungkin ingin memicu cadangan dari aplikasi Anda karena Anda akan membuat perubahan data besar, jadi mengapa tidak menggunakan apa yang digunakan dba Anda?

Beberapa permintaan Ad hoc lebih mudah untuk menulis proc hingga Anda bisa mendapatkan semua fungsionalitas di aplikasi Anda. Kami membencinya. Kami mendorong kembali, tetapi pertunjukan harus berlanjut.

JeffO
sumber
0

Saya akan sangat menyarankan untuk tidak menempatkan logika bisnis dalam prosedur tersimpan. Namun, mungkin ada kasus (Anda mencantumkan dua contoh bagus) di mana lebih baik untuk menempatkan logika akses data di sana.

Secara umum, jika Anda merasa tergoda untuk menggunakan SP, itu adalah tanda (bau kode) yang mengisyaratkan bahwa model data Anda tidak cocok dengan kebutuhannya.

Sunting: Ketika pengembang bertanya kepada saya tentang logika akses bisnis / data, saya mengatakan bahwa logika bisnis adalah tentang bagaimana data berperilaku dan berinteraksi, sedangkan logika akses data adalah tentang bagaimana data disimpan dan diambil.

Sebagai contoh: Dalam model domain Anda, Anda mungkin memiliki entitas "Siswa" dan "Guru", keduanya berasal dari "Orang". (Tidak mengatakan ini lebih disukai, hanya sebuah contoh). Ini dapat disimpan dalam database relasional sebagai satu, dua atau tiga tabel. Pilihannya tergantung pada berapa banyak properti yang mereka bagikan, dan pada persyaratan kinerja baca / tulis.

Dalam logika Bisnis seharusnya tidak peduli bagaimana entitas tersebut disimpan. (Atau apakah mereka tinggal di RDB sama sekali). Logika akses data adalah semua tentang bagaimana mereka disimpan secara fisik.

Jadi, berkenaan dengan pertanyaan awal: Jika prosedur tersimpan membuat menyimpan dan mengambil data lebih efisien (atau lebih kuat) Anda memiliki kasing. Jika prosedur tersimpan hanya untuk memaksakan aturan yang saya valid terlepas dari bagaimana data disimpan, hindari. Itu membuat kode Anda lebih erat dengan database.

Guran
sumber
2
Bagaimana Anda mendefinisikan logika bisnis dan logika akses data ?
Amy Barrett
@AmyBarrett: Logika Bisnis , Lapisan Akses Data .
Robert Harvey
@RobertHarvey Terima kasih atas tautannya. Apakah lapisan akses data sama dengan logika akses data? Saya bertanya karena tampaknya tidak ada banyak logika aktual yang terlibat dalam lapisan akses data - hanya operasi CRUD sederhana.
Amy Barrett
@AmyBarrett: Ya, terkadang Anda menulis metode khusus di lapisan Akses Data, jadi itu tidak selalu CRUD.
Robert Harvey
@RobertHarvey Bukankah metode kustom itu termasuk dalam lapisan logika bisnis?
Amy Barrett
-4

Saya pikir ada tiga masalah di sini.

  1. Logika bisnis dalam SQL buruk. Bahkan jika itu berjalan lebih cepat secara individual, itu tidak skala.

  2. Secara tradisional, SPROC harus selalu digunakan untuk semua akses data sebagai lapisan abstraksi. Mengaktifkan DBA untuk memperkenalkan perubahan kinerja atau datalayer lainnya tanpa memengaruhi aplikasi yang mengonsumsi.

  3. EF tidak bermain bagus dengan sprocs. Anda akan kehilangan banyak fitur 'baik' dan peningkatan produktivitas dengan beralih dari generasi kueri dinamis Linq.

Jadi saran saya secara keseluruhan adalah untuk

  • Gunakan SPROCs untuk semua kueri SQL,

  • Jangan masukkan logika bisnis atau jenis loop apa pun di dalamnya,

  • Jangan gunakan EF.

Ewan
sumber
Karena semua SQL berjalan di server db, Anda hanya dapat menskalakan dengan db ekstra daripada kotak komputasi ekstra.
Ewan
1
Saya melihat. Tetapi poin # 1 adalah murni tentang pertukaran antara dua masalah kinerja. Tetapi akan ada saat-saat ketika solusi SQL adalah kemenangan yang jelas dalam hal kinerja, jadi saya tidak melihat bagaimana hal itu dapat dianggap kategoris "buruk" atas dasar ini.
1
katakanlah Anda memiliki layanan web yang melakukan perhitungan. Anda dapat melakukannya dalam kode atau dalam sql. katakanlah sql lebih cepat dalam tes head to head dari satu perhitungan. Tetapi ketika layanan ini maksimal cpu itu sangat murah dan mudah untuk menambahkan kotak kedua, ketiga, keempat .. menjalankan layanan web tetapi sulit dan mahal untuk menambahkan database kedua direplikasi
Ewan
1
itu adalah contoh dari satu skenario tertentu di mana SQL mungkin desain yang buruk karena skalabilitas. Tetapi meskipun itu tidak jelas: itu tergantung pada jumlah pengguna yang diharapkan, biaya relatif melakukan perhitungan dalam database dibandingkan dengan di luar, dan sebagainya. Tentu saja Anda benar dalam beberapa kasus, saya rasa itu bukan aturan universal.
3
Ini saran yang buruk, secara keseluruhan. Ada banyak opsi untuk akses data yang memiliki kelebihan dibandingkan dengan prosedur tersimpan yang dikodekan secara manual dan berkinerja sama baiknya. Anda dapat menjalankan sprocs langsung dari EF; bahkan, Anda dapat menjalankan kueri sql apa pun langsung dari EF. Beberapa logika bisnis berjalan lebih baik di server database, sehingga Anda tidak dapat menyatakan dengan pasti bahwa itu dilarang di sana. Pemetaan relasional objek adalah alat 80%; mereka tidak pernah dimaksudkan untuk sepenuhnya menggantikan proses akses data Anda. Gunakan prosedur tersimpan untuk tujuan penggunaannya: 20% yang tidak dilakukan ORM dengan baik.
Robert Harvey