Untuk validasi data pendukung ORM, haruskah kendala juga ditegakkan dalam database?

13

Saya selalu menerapkan batasan di tingkat basis data selain model (ActiveRecord) saya. Tapi saya sudah bertanya-tanya apakah ini benar-benar diperlukan?

Sedikit latar belakang

Baru-baru ini saya harus menguji unit metode pembuatan stempel waktu otomatis dasar untuk suatu model. Biasanya, tes akan membuat instance model dan menyimpannya tanpa validasi. Tetapi ada bidang lain yang diperlukan yang tidak dapat dibatalkan pada definisi tabel, yang berarti saya tidak dapat menyimpan instance bahkan jika saya melewatkan validasi ActiveRecord. Jadi saya berpikir jika saya harus menghilangkan kendala seperti itu dari db itu sendiri, dan biarkan ORM yang menanganinya?

Kemungkinan keuntungan jika saya melewati batasan dalam db, imo -

  • Dapat memodifikasi aturan validasi dalam model, tanpa harus memigrasi basis data.
  • Dapat melewati validasi dalam pengujian.

Kerugian yang mungkin?

Jika dimungkinkan validasi ORM gagal atau dilewati, bagaimanapun, database tidak memeriksa kendala.

Bagaimana menurut anda?

EDIT Dalam hal ini, saya menggunakan Kerangka Yii , yang menghasilkan model dari basis data, maka aturan basis data juga dihasilkan (meskipun saya juga selalu dapat menulisnya setelah generasi).

na
sumber
3
Jika data dalam database Anda dapat secara rutin dimodifikasi tanpa menggunakan ORM Anda (aplikasi lain tanpa ORM Anda, atau, lebih buruk lagi, akses db langsung oleh pengguna), validasi benar-benar perlu ada dalam database.
Marjan Venema

Jawaban:

16

Prinsip panduan Anda haruslah Jangan Ulangi Diri Anda Sendiri :

Dalam rekayasa perangkat lunak, Don't Repeat Yourself (DRY) adalah prinsip pengembangan perangkat lunak yang bertujuan mengurangi pengulangan semua jenis informasi, terutama berguna dalam arsitektur multi-tier. Prinsip KERING dinyatakan sebagai "Setiap bagian pengetahuan harus memiliki representasi tunggal, tidak ambigu, otoritatif dalam suatu sistem."

ORM pada dasarnya adalah lapisan tambahan (atau tingkat jika Anda suka), duduk dengan nyaman di antara aplikasi Anda dan penyimpanan data Anda. Kendala Anda harus berada di satu tempat, dan satu tempat saja, baik itu ORM atau penyimpanan data, jika tidak segera Anda akan berakhir dengan mempertahankan versi yang berbeda dari mereka. Anda benar - benar tidak ingin melakukan itu.

Namun, dalam praktiknya, sebagian besar ORM yang layak secara otomatis menghasilkan banyak model Anda dari skema data Anda. Meskipun masih ada duplikasi, kemungkinan neraka pemeliharaan minimal karena kode ORM digandakan dihasilkan mengikuti pola yang sama setiap kali. Akan ideal untuk tidak memiliki kode duplikat, tetapi kendala yang dihasilkan secara otomatis adalah hal terbaik berikutnya.

Selain itu, memiliki kendala di satu tempat tidak selalu berarti Anda harus memiliki semua kendala di tempat yang sama. Beberapa, seperti batasan integritas referensial, mungkin lebih cocok untuk penyimpanan data (tetapi mungkin hilang jika Anda pindah ke penyimpanan data lain), dan beberapa, sebagian besar yang tentang logika bisnis yang kompleks, lebih cocok untuk ORM Anda. Lebih disukai memiliki semua apel Anda di keranjang yang sama, tetapi ...

Kegagalan

Anda menyebutkan ORM gagal. Itu sama sekali tidak relevan dengan pertanyaan Anda, aplikasi Anda harus memikirkan ORM dan penyimpanan data sebagai satu kesatuan. Jika gagal, gagal, melewati ORM untuk berbicara dengan penyimpanan data secara langsung bukanlah ide yang baik.

Memotong ORM untuk hal lain

Juga bukan ide yang bagus. Namun, itu bisa terjadi karena berbagai alasan:

  1. Bagian lawas dari aplikasi yang dibangun sebelum ORM diperkenalkan.

    Itu yang sulit, dan persis situasi yang saya hadapi sekarang , maka saya terus-menerus mengulangi "neraka pemeliharaan". Entah Anda mempertahankan bagian-bagian yang bukan ORM, atau Anda menulis ulang untuk menggunakan ORM. Opsi kedua mungkin lebih masuk akal pada awalnya, tetapi ini adalah keputusan yang hanya didasarkan pada apa yang sebenarnya dilakukan bagian aplikasi Anda, dan seberapa berharganya penulisan ulang yang lengkap dalam jangka panjang.

    Coba ubah kunci dalam tabel MySQL 2 * 10 ^ 8 yang dirancang dengan buruk (tanpa downtime) dan Anda akan mengerti dari mana saya berasal.

  2. Bagian non-warisan dari aplikasi yang benar-benar perlu berbicara langsung dengan penyimpanan data:

    Lebih rumit lagi. ORM adalah alat mewah, dan mereka menangani hampir semua hal, tetapi kadang-kadang mereka hanya menghalangi atau bahkan sama sekali tidak berguna. Kata kunci (buzzphrase betul-betul) adalah ketidakcocokan impedansi objek-relasional , sederhananya itu tidak memungkinkan secara teknis bagi ORM Anda untuk melakukan semua yang dilakukan oleh basis data relasional Anda, dan untuk beberapa hal yang mereka lakukan, ada penalti kinerja yang signifikan.

Komentar

Dari titik integritas data, kendala HARUS pada database, dan HARUS pada aplikasi. Bagaimana jika aplikasi Anda diakses dari web dan aplikasi desktop, atau aplikasi seluler, atau layanan web? - Luiz Damim

Di sinilah menambahkan lapisan tambahan akan sangat membantu, dan jika kita berbicara tentang aplikasi web saya akan menggunakan REST API. Sebuah desain terlalu sederhana untuk ini akan menjadi:

masukkan deskripsi gambar di sini

ORM akan berada di antara API dan penyimpanan data, dan segala sesuatu di belakang API (termasuk itu) akan dianggap sebagai entitas tunggal dari berbagai aplikasi.

yannis
sumber
Biasanya Anda akan mendefinisikan skema dalam ORM Anda yang kemudian dicerminkan ke dalam basis data sehingga Anda memiliki tingkat jaminan kedua.
Josh K
2
@JoshK Anda mengatakan tingkat jaminan kedua, saya katakan pemeliharaan neraka. Namun, tidak mengatakan bahwa Anda tidak benar ...
yannis
Masuk akal. Saya mengikuti rute ini sekarang. Terima kasih!
na
1
Setelah Anda melewati titik di mana satu atau dua pengembang melakukan pekerjaan kode dan basis data, itu menjadi kejahatan yang perlu. Jika Anda menggunakan ORM yang baik, itu akan menghasilkan migrasi untuk Anda juga. Ketika Anda tumbuh ke titik memiliki DBA khusus tidak ada jalan lain, mereka tidak akan membiarkan meja melayang tanpa kendala. Cara sederhana untuk mencegah orang mendaftar tanpa email adalah membuat tingkat penyimpanan menjadi kendala.
Josh K
1
Dari titik integritas data, kendala HARUS pada database, dan HARUS pada aplikasi. Bagaimana jika aplikasi Anda diakses dari web dan aplikasi desktop, atau aplikasi seluler, atau layanan web?
Luiz Damim
20

Ini sebenarnya adalah pertanyaan yang sangat sulit untuk dijawab dan saya telah menemukan itu menjadi topik yang sangat kontroversial.

Seperti Yannis Rizos tunjukkan dalam jawabannya, memiliki logika kendala di database dan lapisan ORM tampaknya melanggar KERING, yang "dapat menyebabkan mimpi buruk pemeliharaan, anjak piutang yang buruk, dan kontradiksi logis".

Namun, menghapus logika kendala dari database dan menyimpannya hanya pada lapisan ORM tidak akan berfungsi jika Anda memiliki salah satu dari kondisi berikut:

  1. Pembaruan DB manual (tampaknya terjadi di setiap perusahaan)

  2. DB memperbarui dari sistem lain yang tidak dapat selalu berbagi logika kendala ORM dengan mudah (ex / skrip Perl yang melakukan tugas-tugas rutin ketika lapisan ORM diimplementasikan dalam Hibernate dan digunakan oleh aplikasi Java untuk aktivitas sehari-hari)

Ini akan menyarankan Anda hanya menambahkan logika kendala ke DB dan menghapus dari lapisan ORM Anda untuk mencegah pelanggaran KERING. Namun, ini dapat menyebabkan kasus di mana kode aplikasi tidak berhasil menangkap masalah aktual dan menyampaikan ke pengguna (meskipun sebagai pengembang men-debug masalah, Anda kemungkinan besar bisa). Ini mungkin tidak dapat diterima untuk beberapa proyek.

Pilihan terakhir Anda adalah untuk mengotomatiskan pembuatan kendala dalam ORM (dan sistem lainnya) dari kendala DB (atau, benar-benar ... sebaliknya). Meskipun pada akhirnya Anda akan berakhir dengan dua atau lebih implementasi kendala, itu tidak akan melanggar prinsip KERING seperti yang dijelaskan dalam "Programmer Pragmatis" karena mereka merekomendasikan pemanfaatan pembuatan kode untuk menghindari pelanggaran KERING. Tentu saja, itu tidak sesederhana itu karena, misalnya, setiap perubahan pada batasan DB dapat memaksa membangun kembali dan menyebarkan kembali semua aplikasi Anda yang menggunakannya (tidak sepele untuk mengotomatisasi).

Sungguh, itu harus dievaluasi berdasarkan kasus per kasus . Saya dapat memberitahu Anda bahwa, sampai titik ini, saya telah bertemu dengan tatapan kosong ketika saya menyarankan agar logika kendala tidak diulang.

smp7d
sumber
2
Baru saja pulang kerja dan sedang berpikir untuk memperluas jawaban saya menjadi lebih atau kurang dari apa yang baru saja Anda posting. Jawaban yang bagus!
yannis
3

Saya pasti akan menambahkan kendala ke database sebagai opsi default saya. Ini karena untuk data perusahaan adalah raja dan kualitas data adalah yang terpenting. @Yannis Rizos membawa prinsip KERING ke diskusi. Nah prinsip lain adalah Pertahanan dalam Kedalaman. Untuk Data saya akan menggunakan prinsip ini.

Saya telah bekerja di perusahaan nyata di mana DB memiliki data yang dibuat 30 tahun yang lalu. Itu dan masih diakses oleh aplikasi COBOL dan sekarang oleh aplikasi .Net. Dalam waktu 10 tahun mungkin itu adalah aplikasi vendor, siapa tahu. Ada merger dan jutaan baris data dikonversi dan dimigrasikan dari perusahaan lain ke database ini menggunakan SQL. Tidak ada ORM yang bisa melakukan ini. Intinya adalah Data tetap, aplikasi berubah, cara Data dihasilkan perubahan. Jadi mengapa tidak mengurangi kemungkinan korupsi data?

softveda
sumber
2

Saya pikir Anda melakukan keduanya sampai batas tertentu.

  • Kendala utama harus hidup dalam ORM - bahasa pemrograman jauh lebih fleksibel, lebih mudah untuk menguji dan lebih mudah untuk tweak ketika persyaratan berubah; tidak perlu khawatir tentang perbaikan DDL setidaknya. Dan Anda biasanya menghindari kesulitan untuk menguji masalah regresi data.

  • Beberapa kendala yang sangat sulit dan cepat juga harus hidup dalam database. Saya tidak berbicara tentang nama yang tidak dapat dibatalkan, misalnya. Saya sedang berbicara tentang hal-hal seperti integritas referensial atau memerlukan beberapa pengidentifikasi yang sangat penting. Persyaratan struktural sehingga kode Anda tidak perlu berurusan dengan "bagaimana jika Pesanan memiliki produk yang tidak ada".

Wyatt Barnett
sumber
1

Basis data adalah IMO satu-satunya tempat di mana KERING dapat dilanggar, karena jika sesuatu memotong ORM Anda dan memiliki data yang buruk, itu saja. Permainan telah berakhir. Memiliki data yang korup adalah pukulan mematikan.

Wayne Molina
sumber
Hanya basis data? Saya bisa memikirkan banyak kasus di mana perilaku yang terkait dengan data harus ada pada beberapa lapisan (logis atau fisik) bahkan jika data tidak bertahan sama sekali. Terkadang dimungkinkan untuk memiliki satu kode sumber dan mengurangi "duplikasi" ke dll yang digunakan.
mike30