Kapan lebih baik untuk membongkar pekerjaan ke RDBMS daripada melakukannya dalam kode?

12

Oke, saya akan mengatasinya: Saya pembuat kode yang lebih baik daripada saya di basis data, dan saya bertanya-tanya di mana pemikiran tentang "praktik terbaik" terletak pada subjek melakukan perhitungan "sederhana" dalam kueri SQL vs. di kode, seperti contoh MySQL ini (saya tidak menulisnya, saya hanya harus memeliharanya!) - Ini mengembalikan nama pengguna, dan usia pengguna pada peristiwa terakhir.

SELECT u.username as user, 
       IF ((DAY(max(e.date)) - DAY(u.DOB)) < 0 ,   
       TRUNCATE(((((YEAR(max(e.date))*12)+MONTH(max(e.date)))
       -((YEAR(u.DOB)*12)+MONTH(u.DOB)))-1)/12, 0),  
       TRUNCATE((((YEAR(max(e.date))*12)+MONTH(max(e.date))) -            
       ((YEAR(u.DOB)*12)+MONTH(u.DOB)))/12, 0)) AS age   
FROM users as u
JOIN events as e ON u.id = e.uid
...

Dibandingkan dengan melakukan "lifting" kode:

Pertanyaan:

SELECT u.username, u.DOB as dob, e.event_date as edate
FROM users as u
JOIN events as e ON u.id = e.uid

kode:

function ageAsOfDate($birth, $aod)
{    //expects dates in mysql Y-m-d format...
     list($by,$bm,$bd) = explode('-',$birth);
     list($ay,$am,$ad) = explode('-',$aod);

     //Insert Calculations here 
     ...
     return $Dy; //Difference in years
}

echo "Hey! ". $row['user'] ." was ". ageAsOfDate($row['dob'], $row['edate']) . " when we last saw him."; 

Saya cukup yakin dalam kasus sederhana seperti ini tidak akan membuat banyak perbedaan (selain perasaan ngeri ketika saya harus membuat perubahan pada pertanyaan seperti yang pertama), tapi saya pikir itu membuatnya lebih jelas apa yang saya ' Saya sedang mencari.

Terima kasih!

GeminiDomino
sumber
1
Ini adalah pertanyaan yang bagus - saya telah menemukan masalah yang sama.
Michael K
Berikut adalah contoh yang baik ketika tidak melakukannya: calendar.sql (Ya, itu adalah keburukan saya, ya, itu adalah ide yang buruk, dan tidak, itu tidak lambat.)
greyfade
Kamu membalik dewa ... Aku bertaruh MD5 untuk hal itu keluar menjadi "CthulhuFhtagn"
GeminiDomino

Jawaban:

13

Anda ingin melakukan semua operasi berbasis set di database untuk alasan kinerja. Jadi fungsi agregasi, fungsi penyortiran, bergabung dll.

Perhitungan umur ini, saya akan lakukan dalam kode. Satu-satunya alasan saya mungkin melakukan sesuatu seperti ini dalam permintaan basis data adalah jika diperlukan banyak kolom yang tidak akan saya pilih yang sebenarnya bisa berjumlah cukup data untuk memperlambat permintaan saya. Memilih beberapa nilai integer tidak akan membuat perbedaan kinerja yang berarti. Dan bahkan jika itu membuat perbedaan kinerja moderat saya akan bias menjaga logika ini dalam kode aplikasi.

Jeremy
sumber
Saya setuju. Kode yang mengutak-atik nilai untuk tujuan tampilan harus dalam kode aplikasi Anda.
TehShrike
4

Setiap kasing berbeda

Apakah logika ...

  • dibutuhkan oleh klien lain? KERING: dalam database
  • digunakan untuk diproses lebih lanjut? mis. urutkan berdasarkan usia menurun: dalam database
  • membutuhkan pengaturan regional? dd / mm / yyyy atau mm / dd / yyyy: di klien
  • sering digunakan? Mengapa menghitungnya berulang-ulang: gunakan kolom yang dihitung dan bertahan dalam basis data

Dalam hal ini, saya mungkin menggunakan kolom yang dihitung dan tetap dalam database

Ini bisa lebih buruk: Anda bisa memiliki ini di database:

"Hey! ". u.username." was ". <datecalc>. " when we last saw him."
gbn
sumber
3

Pada dasarnya Anda harus melihat dua hal: penggunaan CPU dan lalu lintas jaringan. Anda seharusnya tidak menghasilkan respons yang luar biasa, mentransfernya melalui jaringan dan kemudian merangkumnya di frontend, karena database dapat melakukan ini dengan lebih baik.

Untuk manipulasi data , ini merupakan pertukaran. Jika database menghabiskan jumlah siklus cpu yang sebanding dengan kode frontend Anda melakukan hal yang sama - mengingat bahwa jumlah data yang ditransfer kira-kira setara), maka tidak masalah di mana. Kemudian lakukan di mana Anda memiliki jumlah keahlian pemrograman terbesar. Seringkali, Anda bisa mendapatkan cara yang SANGAT panjang dengan pemilihan yang cermat dan itu mungkin sangat berguna.


sumber
1

Anda menyebutkan satu: bidang keahlian. Mungkin struktur basis data tidak terlalu intensif, jadi Anda memutuskan untuk menurunkan beberapa pengembangan logika ke anggota tim yang lebih berpusat pada basis data. Mungkin tidak ideal, tetapi jika Anda punya waktu ...

Perangkat keras basis data memiliki sumber daya yang jauh lebih banyak daripada server lain dan Anda tidak dapat mengubahnya. Ini mungkin tidak berlaku untuk situasi khusus ini, tetapi mungkin perlu dipertimbangkan.

Ada aplikasi lain yang mungkin memerlukan logika di luar kode Anda. Beberapa alat penulisan laporan mungkin tidak dapat memanfaatkan layanan web atau API. Anda dapat menduplikasi logika atau jika Anda merasa persyaratannya mungkin berbeda.

JeffO
sumber
"Perangkat keras basis data memiliki sumber daya yang jauh lebih banyak daripada server lain dan Anda tidak dapat mengubahnya." - eh? Dari mana dua pernyataan itu berasal?
Peter Boughton
Saya pikir Jeff mungkin berbicara tentang server Database mandiri. Saya mungkin seharusnya menentukan bahwa saya bekerja sebagian besar pada pengaturan LA [MP] P.
GeminiDomino
1
Pengaturan LAMP bukan alasan untuk tidak memiliki server database mandiri, dan server database mandiri juga tidak menjamin lebih banyak sumber daya atau tidak dapat mengubahnya.
Peter Boughton
Hrm Tidak yakin kalau begitu.
GeminiDomino
@Peter Boughton, DB dan aplikasi di server yang sama memiliki urutan besarnya lebih sedikit waktu untuk koneksi antarmuka dan besarnya IO lebih besar di seluruh, ada alasan nyata untuk menemukan keduanya bersama-sama.
Jé Queue
0

Saya selalu keliru menempatkan banyak pemrosesan di DB. Sintaks Anda di atas juga dapat ditulis dengan fungsi DB yang akan menjadi IMO solusi yang sangat bersih.

Jé Queue
sumber