Apakah ORM alat yang buruk untuk struktur DB seperti pohon?

8

Saya tahu pertanyaan ini mungkin ditutup berdasarkan opini, tetapi yang saya butuhkan saat ini adalah beberapa pendapat yang didukung oleh argumen.

Saya membangun aplikasi dengan Postgres dan Ecto (Elixir) sebagai layer persistence. Ada entitas yang mereferensikan dirinya sendiri sehingga Anda dapat membangun struktur seperti pohon dengannya. Semakin saya mencoba melakukan ini dengan Ecto, semakin frustrasi saya.

Apakah ORM hanyalah alat yang buruk untuk membuat struktur DB yang kompleks dengan banyak asosiasi? Cara berorientasi objek yang mencoba diterapkan oleh ORM pada data relasional tampaknya merupakan pendekatan yang buruk di sini. Objek terisolasi. Jika mereka berinteraksi dengan objek lain, mereka (seharusnya) mengirim pesan. Detail batin mereka harus tetap disembunyikan. Data relasional membentuk grafik yang terbuka dan transparan. Kedua dunia ini sepertinya sama sekali tidak cocok untukku.

Namun, ORM sangat umum dan populer. Apakah sebagian besar aplikasi web bekerja dengan entitas yang agak terisolasi yang cocok dengan ORM, atau mengapa begitu? Tampak bagi saya bahwa jika Anda ingin menerapkan model ERD rumit rata-rata menggunakan kerangka kerja ORM, Anda harus mengorbankan kode ringkas atau kinerja.

Adam Libuša
sumber
1
Setiap sistem basis data mungkin memiliki implementasi yang sedikit berbeda untuk mendukung struktur data hierarki atau pohon. Sebagai contoh, Oracle telah MULAI DENGAN dan MENGHUBUNGKAN OLEH dan Sql Server memiliki Common Table Expressions (CTEs). Jadi, sebelum memilih ORM, seseorang harus menentukan apakah ia memiliki dukungan yang tepat untuk jenis struktur data ini. Beberapa menawarkan dukungan yang sangat baik, sementara yang lain mungkin tidak mencakup skenario itu. Pertanyaan ini harus diucapkan kembali: Apakah Ecto mendukung struktur pohon?
Jon Raynor
Karena Anda menyebutkan postgres secara khusus, ini mendukung permintaan rekursif untuk hal semacam ini (meskipun saya belum menggunakannya sendiri)
Izkata
1
Tentu saja ORM adalah alat yang buruk. Sudah ada bahasa untuk mengekspresikan kueri pada database secara eksplisit: SQL.
Miles Rout
@Miles Rout Dalam kebanyakan kasus ketika Anda menggunakan SQL bukan ORM Anda sering mengulangi sendiri.
Jimmy T.
@ JimmyT. Itu salah.
Miles Rout

Jawaban:

9

Pada akhirnya ORM hanyalah abstraksi yang menghasilkan sql untuk Anda dan memetakan data ke objek Anda. Menyimpan (tm) Anda beberapa kode 'boiler plate'.

Jadi tidak ada yang ORM secara keseluruhan buruk pada definisi. Masalahnya adalah bahwa Anda tidak menggunakan ORM secara keseluruhan, Anda harus memilih yang spesifik dan menggunakannya!

ORM individu mungkin tidak melakukan hal tertentu dengan sangat baik. Procs Tersimpan, sql dinamis, bidang terhitung, gabungan rumit dll.

Masalah yang lebih halus adalah bahwa ketika ORM mencoba menangani semua skenario ini dengan cara yang generik, ia menjadi lebih besar dan lebih rumit untuk digunakan.

Jika Anda memiliki aplikasi besar atau rumit, kemungkinan bahwa pada titik tertentu Anda akan mengalami masalah dengan ORM yang Anda pilih. Jadi masuk akal untuk merencanakan ini sebelumnya dan memastikan bahwa Anda menyembunyikan ORM di belakang repositori. Dengan begitu Anda bebas untuk menukarnya dengan alternatif, atau kembali ke kode SQL tangan jika diperlukan.

Ewan
sumber
1
Perlu dicatat bahwa, dalam banyak ORM (setidaknya setiap ORM yang saya gunakan ), Anda dapat menulis dan menjalankan SQL mentah . Oleh karena itu, jika ORM tidak memenuhi beberapa kendala dengan baik, Anda selalu dapat menggunakan melakukannya dengan SQL asli, sementara secara bersamaan mengurangi operasi 'boilerplate' SELECT * FROM some_table WHERE x = whateveryang sangat umum. Struktur hierarkis ditangani dengan baik di beberapa ORM, dan sangat di yang lain, jadi jenis pertimbangan ini harus diteliti sebelum memutuskan untuk sepenuhnya melupakan ORM.
Chris Cirefice
Anda biasanya dapat melakukan ini, tetapi itu tidak selalu berhasil seperti yang Anda inginkan! baru-baru ini memiliki masalah ini dengan pemetaan lapangan nHibernate dan nullable
Ewan
Saya tidak pernah menggunakan nHibernate, tetapi saya telah menggunakan beberapa seperti RailR 'ActiveRecord, OrmLite (Java), dan ActiveJdbc (Java). Masing-masing menangani mengeksekusi SQL mentah berbeda, misalnya ActiveRecord membuatnya sangat mudah, dan OrmLite membuatnya sangat sulit. ActiveRecord telah dikembangkan selama bertahun-tahun, jadi pasti ada hubungannya dengan itu. Semua nuansa kecil ini adalah bagian dari pengujian kelayakan, tetapi kadang-kadang Anda melewatkan hal-hal kecil yang kembali menggigit Anda nanti ...
Chris Cirefice
ya, itu sebabnya saya katakan menaruh pembungkus di sekitarnya. Anda masih dapat menggunakan orm, tetapi Anda tidak terkunci jika membiarkan Anda jatuh
Ewan
Menyimpan (tm) - Saya sedikit terkekeh karenanya.
corsiKa
7

Apakah ORM hanyalah alat yang buruk untuk membuat struktur DB yang kompleks dengan banyak asosiasi?

Tidak. Sebagai contoh, Ruby on Rails menggunakan ActiveRecord, yang menangani asosiasi. Dalam contoh di sini: /programming/5109893/rails-how-do-self-referential-has-many-models-work , struktur mirip pohon diselesaikan dengan 2 baris kode.

Jadi saya berpendapat bahwa itu waaaaay lebih mudah daripada mencoba untuk menggulung query sql Anda sendiri.

Apakah sebagian besar aplikasi web bekerja dengan entitas yang agak terisolasi yang cocok dengan ORM, atau mengapa begitu?

Mungkin tidak, tapi itu hanya dugaan saja. ORM ada dalam ekosistem di mana mereka berkembang, menunjukkan bahwa mereka sedang digunakan. Saya telah menggunakan ORM untuk sistem dengan lebih dari 20 model terkait dan ternyata baik-baik saja. Saya tidak pernah memaksa benda untuk diisolasi dengan hanya pesan yang lewat.

Sebagai pendapat ringkas, jika Anda membuat model ERD "kompleks", tidak ada alat yang membuatnya mudah. Hanya alat yang membuatnya bekerja.

cmonkey
sumber
Yap - Saya menggunakan Entity Framework untuk proyek yang memiliki CustomerId (PK) dan ParentCustomerId (nullable FK menunjuk kembali ke tabel pelanggan) untuk membuat n level pohon hierarki pelanggan. Tidak punya masalah di sini (walaupun banyak cek kosong / .Any()pernyataan LINQ)
USER_8675309
Hibernate (Java) adalah contoh bagus lain dari ORM yang dapat menangani pohon tanpa masalah, membutuhkan hampir nol upaya ekstra . Kompleksitas kueri tersembunyi dari klien. Orang tua dan anak-anak bisa malas. ID objek induk hanyalah kolom lain dalam database. Daftar simpul anak yang diurutkan dapat didukung secara transparan juga dengan penambahan kolom yang menyimpan indeks daftar. (Pertimbangan koleksi tanpa urutan vs pesanan tidak unik untuk pohon di sini.)
Jason C
Saya tidak bisa membantu tetapi merasa bahwa ini adalah jawaban yang menyesatkan. Karena satu ORM menangani kasus ini, tidak berarti ORM secara umum dapat menangani hal ini. Memang google cepat menunjukkan bahwa catatan aktif TIDAK memiliki bug dan bug dalam beberapa versi sekitar referensi diri github.com/rails-api/active_model_serializers/issues/211 dan coderwall.com/p/4d2utg/…
Ewan
@ Ewan - Saya terbuka untuk mengulangi jawaban saya, tapi saya pikir itu cukup menjawab pertanyaan jika ORM secara umum buruk. Ini adalah pertanyaan yang berbeda untuk ditanyakan apakah semua ORM dapat menangani kasus ini, atau apakah mereka adalah solusi terbaik. Keberadaan alat ORM yang kurang cocok, atau bug dalam versi tidak mengubah generalisasi. Saya juga tahu saya punya bug di SQL saya juga.
cmonkey
5

Sebagaimana dicatat dalam setidaknya satu jawaban lain di sini, semua ORM tidak sama. Beberapa ORM membuat asumsi yang sangat signifikan tentang bagaimana database harus disusun. Tooling harus memberikan beberapa dukungan untuk keluar dari model ini, tetapi semakin banyak Anda keluar dari model itu, semakin sedikit nilai ORM yang dimilikinya. Jika Anda bekerja dengan alat ORM yang lebih dominan, Anda akan memiliki pengalaman yang jauh lebih baik jika Anda mendesain database berdasarkan asumsi implisitnya.

Saya tidak pernah benar-benar mengerti mengapa ORM dilihat oleh banyak pengembang dan arsitek sebagai hal yang penting. Ini mungkin karena fakta bahwa saya hampir tidak pernah memiliki database lapangan hijau untuk bekerja dan waktu dan upaya yang diperlukan untuk menyelesaikan pemetaan ORM jauh lebih banyak pekerjaan daripada menulis SQL. Entah pemetaannya sederhana (dan juga SQL) atau rumit dan saya tetap membutuhkan SQL (atau yang serupa). 'Dukungan' transaksional yang termasuk dalam ORM lebih merupakan sumber bug dan masalah daripada bantuan, menurut pengalaman saya.

Jarak tempuh Anda mungkin berbeda-beda, tetapi saya percaya bahwa lebih baik memikirkan ketekunan basis data hanya sebagai kasus khusus serialisasi data. Dan sama seperti saya pikir tidak masuk akal untuk percaya Anda dapat 'mengirim' objek melalui kawat, saya tidak berpikir itu benar-benar masuk akal untuk berpikir menulis objek ke database. Saya bahkan berpikir itu benar-benar valid untuk memiliki beberapa representasi objek dari data yang sama untuk kebutuhan yang berbeda. Memetakan objek ke tabel dan sebaliknya telah menjadi akhir dari dirinya sendiri sebagai lawan dari solusi untuk masalah. Saya tidak yakin kebanyakan orang yang menggunakan alat-alat ini bahkan memiliki alasan yang jelas untuk ingin melakukannya. Itu menjadi default.

JimmyJames
sumber
1
totes setuju, setelah Anda mengundurkan diri untuk mengetik sql dan memetakannya jarang membutuhkan waktu lebih lama dalam jangka panjang dan Anda memiliki kontrol total
Ewan
@ Ewan Agar adil, saya pikir butuh sedikit pengalaman untuk tahu bagaimana membangun abstraksi yang tepat antara logika dan DB. ORM dapat membantu pengembang mencapai sesuatu yang bisa dikerjakan dengan cepat. Gagasan bahwa objek dapat diterjemahkan ke tabel dan sebaliknya di mana saya pikir ada masalah. Memang benar untuk subset data-model dan objek-model tetapi tidak secara umum.
JimmyJames
1
@ JimmyJames Memang benar jika semua yang Anda butuhkan sangat sederhana per operasi tabel CRUD. Selain itu, ORM non-mikro adalah kutukan. (Dan saya pribadi menemukan ide untuk membuat objek untuk setiap set kolom yang berbeda yang kembali untuk mikro-ORM menjadi mengganggu, meskipun mungkin lebih sedikit hal-hal yang mengganggu dalam bahasa yang diketik secara statis.)
jpmc26
1
@ jpmc26 Saya ingin memiringkan quagmire statis vs dinamis tapi saya pikir Anda menyoroti hal-hal yang saya bicarakan. Jika semua yang ingin saya lakukan adalah menarik beberapa data, mengubahnya secara minimal, dan kembali adalah sebagai JSON, misalnya, saya tidak benar-benar perlu memetakan ke objek untuk mencapai ini. Objek tidak memiliki fungsi nyata. Karena berfungsi sebagai peta tempat data disimpan sementara. Tapi saya pernah melihat ORM digunakan untuk memecahkan masalah semacam itu. Seringkali jawabannya adalah menghasilkan kelas untuk objek-objek itu, tapi saya pikir itu hanya menyoroti betapa tidak perlunya mereka.
JimmyJames
Entah bagaimana, saya mengabaikan hal yang awalnya ingin saya katakan: Situasi tidak lebih baik dengan database baru yang Anda kembangkan. Itu hanya tergantung pada jenis pertanyaan yang perlu Anda tulis. Untuk CRUD per tabel yang sangat sederhana, ini dapat menghemat sedikit waktu. Tetapi jika Anda memiliki kueri yang mencampur dan mencocokkan data dari berbagai tabel atau kueri yang kompleks (pengelompokan kompleks, CTE, subkueri), apa pun yang non-mikro secara otomatis jauh lebih banyak masalah daripada nilainya. Bahkan jika Anda bisa lolos dengan CRUD yang sangat sederhana di awal, Anda bertaruh bahwa kesuksesan tidak akan menghasilkan kompleksitas yang lebih besar.
jpmc26