Cara terbaik untuk mengatur permintaan SQL yang disimpan dalam kode Anda? (atau haruskah Anda?) [ditutup]

13

Saya yakin saya bukan satu-satunya yang frustrasi ketika mereka melihat halaman kode yang dikotori dengan query SQL. ActiveRecord dan pola ORM lainnya membantu mengurangi jumlah SQL yang digunakan dalam proyek, tetapi dalam banyak kasus pertanyaan kompleks, penggunaan SQL tampaknya tidak dapat dihindari.

Saya mencari pendapat tentang bagaimana query SQL harus diatur dengan sisa kode (atau eksternal untuk itu) agar tidak tersebar di semua tempat? Satu ide yang jelas adalah penggunaan Views, tetapi sering Views dapat menjadi sumber masalah kinerja ketika berhadapan dengan banyak tabel besar yang diindeks, dll.

EDIT 1 - Saya berasumsi Anda sudah memisahkannya ke dalam lapisan model

ubur-ubur
sumber
3
Pertanyaan ini sangat tepat di sini - organisasi kode: 'menginspirasi jawaban yang menjelaskan "mengapa" dan "bagaimana".' dan merupakan mata pelajaran 'Pola desain' dan 'Arsitektur' (dari Faq )
Michael K
1
Saya baru saja akan menanyakan pertanyaan yang sama. Saya berharap ada lebih banyak jawaban di sini.
Michael Kristofik

Jawaban:

10

Bagi saya, SQL adalah bagian mendasar (dalam banyak kasus, mayoritas) dari kode logika bisnis. Jika Anda mencoba untuk memisahkannya dari kode yang beroperasi pada data yang dikembalikan, Anda lebih cenderung tidak menyeimbangkan pengertian dan keteraturan kode.

Ketika saya melihatnya, membaca data, memproses data, menulis data, mencari data ... mereka semua adalah operasi yang sama, dan paling baik disimpan di tempat yang sama.

Jika Anda mulai merasakan duplikasi upaya dengan kueri, maka mungkin Anda memerlukan tampilan basis data atau objek yang dapat merangkum aspek akses basis data itu.

Tip lainnya adalah benar-benar memiliki metode kueri basis data yang baik. Dalam perangkat lunak yang saya tulis (PostgreSQL, MySQL, SQL Server), saya telah memastikan bahwa sebagian besar operasi permintaan saya dapat dilakukan sebagai pernyataan kode tunggal.

GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])

Itulah (kira-kira) panggilan fungsi utama yang saya pastikan adalah bagian dari "objek koneksi" saya. Itu tergantung pada bahasa, apa yang sebenarnya Anda implementasikan, tetapi poin saya adalah menjaganya tetap benar-benar sederhana dan tidak menyakitkan.

Singkatnya, perlakukan SQL sebagai bagian asli pemrograman, dan jangan abstraksi demi abstraksi.

gahooa
sumber
1
jawaban yang bagus mungkin saya hanya perlu melangkah mundur dan mulai melihat SQL sebagai bagian dari kode, tidak hanya tersebar di antara itu.
Ubur
1
"jangan abstrak demi abstraksi" - Poin bagus. Abstrak demi kode yang lebih dimengerti.
Jason Baker
'Tip lain adalah benar-benar memiliki metode kueri basis data yang baik': Saya sangat setuju. Ini sangat membantu ketika hanya ada satu tempat untuk mengubah kode ketika logika bisnis berubah.
Michael K
1
Di mana Anda meletakkan SQL? Apakah ini dikompilasi ke dalam aplikasi dan dikirim menggunakan metode di atas?
johnny
Berdasarkan komentar OP pada jawaban Jason Baker, "menatap ke bawah laras query SQL raksasa ...", bagaimana ini mengatasi masalah membaca blok besar teks SQL?
JeffO
0

Secara umum, memiliki lapisan model terpisah adalah pendekatan terbaik. Ada sejumlah pola desain perusahaan yang memberi jalan kepada arsitek ini.

Jason Baker
sumber
maaf, saya seharusnya lebih spesifik ... Saya sudah mengasumsikan Anda punya mereka dipisahkan menjadi lapisan model. Tetapi lapisan model masih bisa menjadi sangat tersebar dengan kode SQL. Mungkin ini tidak bisa dihindari. Hal lain yang membuat saya takut dalam kode model adalah kode yang "membangun permintaan SQL" berdasarkan beberapa logika ... mungkin ini harus dipisahkan menjadi pabrik sendiri atau sesuatu ...
jellyfishtree
2
@ jellyfishtree - Saya khawatir saya tidak mengerti apa masalahnya. Maksud saya, Anda takut lapisan model Anda mungkin berakhir dengan terlalu banyak kode model?
Jason Baker
bantahan yang valid. Saya khawatir tentang keterbacaan. Kode model yang baik biasanya cukup mudah untuk dipahami, tetapi menatap laras dari query SQL raksasa tidak memiliki artinya melompat ke arah Anda. Jelas hal pertama yang harus dilakukan adalah mengomentari dengan benar pertanyaan-pertanyaan itu, tetapi itu tidak sama dengan kode yang baik, dokumentasi sendiri dan jenis-jenis bagian ini tersebar di seluruh model. Saya menerimanya, tapi saya bertanya-tanya apakah ada cara yang lebih baik untuk mengisolasi atau mengatur pernyataan SQL gila dalam model ...
jellyfishtree
0

Mungkin ide yang baik untuk memisahkan layer model Anda menjadi 3 sub-layer - "entitas", "repositori" dan "layanan". Ini akan memberi Anda pemisahan kekhawatiran dan mengumpulkan SQL di satu tempat, di luar logika bisnis Anda.

Dalam skenario ini semua kode pengambilan data, termasuk SQL kompleks - akan ditempatkan di repositori. Jadi tujuan repositori adalah untuk menyembunyikan pernyataan SQL yang rumit di belakang metode self-explanatory like getUsersWithActiveSubscription().

Abstrak entitas yang benar-benar nama bidang tabel DB dengan getter dan setter, dapat memberikan beberapa konversi data antara jenis dan tipe bidang DB yang tersedia di aplikasi / bahasa pemrograman Anda. Jika ORM Anda mendukung bahwa - entitas dapat menangani asosiasi.

Lapisan layanan adalah tempat untuk logika bisnis. Layanan mengambil entitas menggunakan repositori, bertindak atas mereka dan menyimpannya kembali.

GerKirill
sumber