Profesor memberi tahu kami untuk menyimpan objek Java bersambung sebagai gumpalan alih-alih mendefinisikan tabel relasional


21

Alih-alih mendefinisikan sebuah tabel dengan atribut yang benar, profesor saya memberi tahu kami bahwa kami dapat memetakan objek ke id seperti ini:

id (int)  |   Serialized Object (blob)
   1               10010110110

Saya bisa melihat begitu banyak masalah dengan ini; redundansi data, harus melacak id secara terpisah, harus menarik seluruh tabel ke memori untuk mencari apa pun, dan ** jika saya ingin mengubah model saya dalam kode Java saya tidak akan lagi dapat menghapus bakteri gumpalan yang tersimpan di database ke dalam model itu.

Entah saya selamanya terjebak dengan model itu atau saya harus melakukan beberapa hal yang benar-benar jelek untuk mengubah model saya. ** Semua ini tampak seperti bentuk yang buruk bagi saya. Apakah saya dibenarkan karena tidak setuju dengan profesor saya? Adakah manfaat melakukan hal ini yang belum saya pikirkan? Jika saya benar haruskah saya mengatakan sesuatu kepada profesor saya tentang ini? Dia mengkhotbahkan ini ke seluruh kelas saya dan bahkan mengatakan bahwa dia telah membangun proyek seperti itu. Pendapat kedua akan bagus.

Kursus ini bernama Desain Perangkat Lunak .

Profesor saya tidak mengatakan bahwa ini adalah cara terbaik, tetapi dia mengatakan bahwa ini adalah alternatif yang sah untuk mendefinisikan tabel relasional.

Modelnya tidak dinamis sama sekali.


Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Paul White mengatakan GoFundMonica

Jawaban:


34
  1. Itu sendiri bukanlah hal yang buruk - sama sekali. Berargumen tentang "mana yang lebih baik" tanpa konteks yang tepat (= persyaratan yang tepat) adalah latihan yang sia-sia.

  2. Bagian dalam huruf tebal salah. Anda dapat dengan mudah memperluas objek yang sudah diserialisasi untuk menambahkan bidang baru dan mencapai kompatibilitas biner penuh dengan objek yang lebih lama. Anda juga bisa membuat kelas baru alih-alih mengubah yang asli.

Diskusi Anda dengan profesor harus fokus pada pro dan kontra dari "relasional" versus "kunci-nilai toko" dalam skenario yang berbeda, bukan pada "kepahitan" abstrak. Atau Anda bisa berdiskusi tentang apakah Natal lebih unggul daripada Thanksgiving.

- hasil edit, setelah membaca jawaban lain.

Salah satu jawaban lainnya menyatakan bahwa "sulit membayangkan kasus di mana pro lebih besar daripada kontra".

Karena seluruh diskusi harus tentang masalah nyata (jika tidak kita bahkan tidak dapat mendefinisikan "lebih baik" dan "lebih buruk"), izinkan saya memberi Anda satu contoh nyata. Itu benar-benar dibuat-buat, tetapi saya mencoba menyempurnakan sebanyak mungkin detail.

Bayangkan Anda memiliki situs game online, dengan basis data yang menyimpan statistik pemain di berbagai game online (dimainkan di browser, ditulis dalam GWT dan dikompilasi silang ke javascript). Beberapa game strategis, beberapa game aksi, beberapa platformers. Basis data bersifat relasional dan menyimpan para pemain dan sejarah permainan serta skornya.

Suatu hari Anda mendapatkan persyaratan tambahan: biarkan para pemain menyimpan status permainan ke cloud, selama pertandingan, sehingga mereka dapat memulai kembali permainan nanti, pada titik yang sama. Tidak perlu dikatakan, satu-satunya alasan untuk menyimpan keadaan sementara ini adalah untuk kembali ke permainan, negara itu sendiri tidak akan pernah introspeksi.

Sekarang Anda memiliki dua pilihan dasar:

  • karena gim-gim ini ditulis dalam Java, Anda dapat dengan mudah mengambil model, mengirimkannya ke server, membuat serialisasi dalam satu baris kode dan menyimpannya sebagai gumpalan. Tabel akan disebut "Saved_games" dan itu akan memiliki kunci asing ke pemain dan sebagainya. Dari sudut pandang basis data, "save game" adalah gumpalan buram yang tidak dapat dibagi.

  • Anda dapat membuat model relasional terpisah untuk masing-masing dari 100 game Anda (ini akan menjadi puluhan tabel per game). Untuk pacman saja, misalnya, Anda harus memiliki meja yang menyimpan posisi semua pelet yang tidak dimakan, bonus, posisi dan keadaan hantu saat ini. Jika seseorang, suatu hari, memodifikasi game, bahkan sedikit, Anda harus memperbarui model relasional. Juga, untuk setiap jenis permainan, Anda harus menerapkan logika untuk menulis model Java ke database, dan membacanya kembali.

Jawaban oleh Justin Cave mengatakan, bahwa Anda harus pergi dengan opsi kedua. Saya pikir ini akan menjadi kesalahan besar.

Juga, saya punya firasat bahwa persepsi Justin Cave adalah bahwa apa yang saya sajikan di atas adalah kasus "tepi" atau "langka". Saya percaya bahwa kecuali dia dapat menyajikan semacam data keras (berdasarkan pengambilan sampel representatif dari semua proyek TI di dunia, bukan hanya, katakanlah, aplikasi perusahaan di AS), saya akan menganggap pendapat seperti itu sebagai kasus klasik dari proyeksi bias.

Sebenarnya, masalah objek Java serial dalam database relasional jauh lebih dalam dari yang terlihat. Menyentuh inti 1NF, yaitu apa domain atribut? . Jika Anda benar-benar tertarik dengan topik ini, ada artikel bagus oleh CJ Date, dalam Date on Database-nya: Writings 2000-2006 .


Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Paul White mengatakan GoFundMonica

22

Bisakah (dan apakah) orang berhasil menyelesaikan proyek yang melakukan hal semacam ini? Sayangnya, ya, mereka sering melakukannya.

Apakah ini pendekatan yang baik? Tidak, tidak. Anda pada dasarnya mengambil basis data yang relatif mahal dan mengubahnya menjadi sistem file yang relatif lambat. Jika Anda benar-benar ingin membangun sistem yang menyimpan keadaannya dengan membuat objek bersambung dan tidak bersambung, Anda mungkin juga menggunakan sistem file daripada menggunakan database.

Jika Anda membangun sistem yang menyimpan data dengan mengelompokkan objek ke dalam basis data, Anda tidak akan berteman dengan DBA Anda. Anda akhirnya akan menyimpan data yang berlebihan. Anda akan berakhir dengan data yang sangat tidak konsisten - setiap kali data yang dibagikan diperbarui, beberapa objek akan berakhir dengan nilai-nilai baru dan beberapa objek akan berakhir dengan nilai-nilai lama. Anda tidak akan dapat melakukan segala jenis pelaporan data - segala sesuatu yang ingin dilakukan oleh siapa pun dengan data tersebut akan mengharuskan seseorang untuk menulis kode tambahan. Itu adalah masalah besar di sebagian besar perusahaan karena mereka ingin melakukan hal-hal seperti mengekstraksi data dari satu sistem untuk dimuat ke sistem lain atau memiliki sistem pelaporan yang dapat mengirimkan laporan dari berbagai aplikasi front-end. Plus, seperti yang Anda tunjukkan, Anda akan selalu harus berurusan dengan masalah ketika Anda

Apakah ada manfaat dari pendekatan ini? Saya kira Anda bisa berpendapat bahwa itu cukup mudah untuk mengimplementasikan versi pertama aplikasi. Dan itu membuat pengembang benar-benar mengabaikan segala hal yang berkaitan dengan berinteraksi dengan benar dengan database. Saya sulit membayangkan banyak kasus di mana keunggulan ini lebih banyak daripada banyak kerugian dari pendekatan.

Adapun bagaimana Anda harus berurusan dengan profesor khusus ini, itu masalah terpisah (dan yang mungkin di luar jangkauan forum ini). Jika profesor Anda secara aktif mengembangkan proyek-proyek di dunia nyata, dia mungkin tidak akan terlalu reseptif terhadap argumen dari seorang siswa bahwa pendekatannya secara fundamental salah (bahkan jika pendekatan itu benar-benar salah secara fundamental). Anda mungkin lebih baik melakukan proyek Anda seperti yang diinginkan profesor dan mempelajari cara yang tepat untuk menyimpan data Anda sendiri (atau dalam kursus yang berbeda).


2
Apa yang Anda katakan, ditambah dua sen saya. Dapat digunakan kembali adalah tentang modularitas dan berbagi. Model objek fokus pada berbagi objek dan menggunakan kembali kode. Model basis data berfokus pada berbagi dan menggunakan kembali data. Tidak ada model yang benar-benar bodoh. Tidak ada model yang sempurna. Dan sangat, sangat sulit untuk mendamaikan keduanya.
Walter Mitty

1
Saya setuju dengan ini, tetapi saya benci melihat seorang profesor mengajar sesuatu dan mengatakan itu adalah cara yang lebih baik tanpa dihadapkan dengan hal itu. Bagaimana dengan semua siswa miskin lainnya yang kelasnya akan pergi ke dunia nyata berpikir ini adalah cara yang benar?
Kevin

Yakin. Formulasi ini sama dengan objek yang berpura-pura menjadi data. Dan mereka adalah data, tetapi bukan data yang sangat berguna.
Walter Mitty

Keuntungannya hampir selalu terhapus begitu Anda ingin merilis v2 aplikasi Anda.
Andy

10

Ada situasi di mana desain semacam ini masuk akal, tanpa Anda menjelaskan tentang proyek Anda dan bagaimana menggunakannya, sulit untuk mengatakan apakah ini sesuai atau tidak.

DBA Anda mungkin membenci Anda jika Anda menyimpan Gumpalan, tetapi dalam banyak situasi satu-satunya alternatif lain adalah mengubah tabel menjadi nilai atribut-Entitas, yang mendapat lebih banyak kebencian dari DBA. Alternatif lain adalah dengan menggunakan basis data non-relasional, biasanya berbasis objek atau basis data berbasis kamus atau database berorientasi dokumen, yang beberapa DBA, terutama yang hanya tahu relasional, akan membenci dengan lebih bersemangat. Database non-relasional memiliki masalah mereka sendiri untuk ditangani, tentu saja dapat menjadi kasus bahwa menggunakan database objek untuk menyimpan objek dapat memunculkan masalah lain yang Anda akan dapat dengan mudah menyelesaikannya dalam sistem relasional.

Adakah manfaat melakukan hal ini yang belum saya pikirkan?

Menyimpan objek berseri berarti Anda dapat menyimpan data schemaless (perhatikan bahwa meskipun namanya, schemaless biasanya tidak berarti bahwa sebenarnya tidak ada skema sama sekali, tetapi hanya ada skema implisit). Ada banyak domain masalah di mana Anda tidak mungkin mendefinisikan skema sebelumnya pada waktu pengembangan, dan di mana mengikuti desain database relasional tradisional berarti Anda harus mengubah skema database setiap minggu, atau Anda berakhir dengan tabel yang memiliki 80% dari kolom yang tidak digunakan 80% dari waktu, atau ratusan tabel berbeda untuk menyimpan data yang benar-benar sama, tidak ada yang menunjukkan desain yang baik. Akar masalah ini biasanya karena Anda dipaksa memasukkan domain masalah non-relasional ke dalam basis data relasional.

Tentu saja, ada banyak proyek di mana orang berpikir mereka perlu menggunakan EAV, schemaless, atau blob store yang ternyata tidak perlu menyebabkan apa yang seharusnya menjadi rasa sakit yang bisa dihindari. Anda harus mendiskusikan dengan profesor Anda apa alasannya dan memberikan argumen Anda sendiri; dengarkan argumen, dan bersiaplah bahwa Anda mungkin akhirnya setuju dengannya, atau tidak, mungkin dia salah.


7

Saya telah melakukan ini sebelumnya - ini adalah teknik yang berguna dalam skenario tertentu namun tergantung pada format serialisasi yang digunakan. Jika saya melakukan ini, saya memastikan bahwa saya menggunakan format serialisasi yang memungkinkan saya untuk menghapus serial model versi lama saya (misalnya XML).

Saya biasanya menggunakan ini dalam skenario di mana format data akan menghasilkan model relasional rumit yang tidak menawarkan keuntungan (misalnya ketika persyaratan bisnis tidak memerlukan penyaringan dll ...) dan saya sudah menggunakan database (untuk data relasional lainnya). Salah satu kasus tersebut adalah aplikasi yang memiliki permintaan pengguna - model relasional memiliki beberapa tabel untuk menyimpan hal-hal seperti kondisi, kondisi bersarang (OR / DAN dll ...), mengurutkan pilihan dll ... Itu cukup rumit dan ketika kami perlu menambahkan fitur baru yang memerlukan perubahan pada basis data. Saya mengganti semuanya dengan satu tabel pertanyaan dengan gumpalan berserat yang mewakili semua opsi lain.

Kasus lain adalah sistem yang memproses berbagai "pekerjaan". Ada beberapa jenis pekerjaan yang berbeda dan setiap pekerjaan memiliki parameter yang berbeda, tanpa persyaratan bisnis untuk dapat mencari / menyaring pekerjaan berdasarkan parameter tersebut. Menyimpan ini sebagai database relasional akan membutuhkan setidaknya 1 tabel baru per jenis pekerjaan, sehingga sulit untuk menambahkan jenis pekerjaan baru. Alih-alih parameter disimpan sebagai gumpalan dalam database - setiap jenis pekerjaan bertanggung jawab untuk serialisasi dan de-serialisasi parameternya sendiri.

Ini tidak terlalu sering Anda akan menemukan skenario seperti ini, namun setiap sekarang dan kemudian situasi seperti tanaman di atas di mana serialisasi data gumpalan menghemat banyak upaya, membuat aplikasi Anda lebih mudah dikelola dan tidak memiliki kerugian nyata.


6

Justin Cave benar bahwa ini dapat menyebabkan data yang berlebihan, tetapi ini benar-benar tergantung pada bagaimana Anda mendesain database Anda.

Pendekatan serialisasi seluruh objek menjadi gumpalan tidak keterlaluan seperti kebanyakan orang di sini berpikir itu. Bahkan, untuk beberapa aplikasi, ini bisa menjadi desain terbaik yang dapat Anda lakukan, seperti yang saya jelaskan di sini: /programming//a/12644223/1121352 .

Memang, membuat cerita bersambung pada suatu objek setidaknya menghasilkan dua manfaat:

1- Mengurangi ketidakcocokan impedansi : beberapa tipe Java tidak tersedia dalam SQL, terutama jika Anda menggunakan banyak kelas dan tipe kustom, sehingga mengubah bolak-balik dari objek Java ke SQL bisa menjadi masalah besar, dan bahkan menyebabkan ambiguitas.

2- Lebih fleksibel dalam skema Anda . Memang, skema relasional sangat bagus untuk data yang memiliki struktur yang sama, tetapi jika beberapa objek Anda dalam satu kelas dapat memiliki properti yang berbeda tergantung pada kondisi saat runtime, skema relasional dapat menghambat alur kerja Anda secara signifikan.

Jadi, tentu saja ada manfaat untuk pendekatan ini (setidaknya dua, tapi tentu saja yang lain saya tidak mengutip), tetapi tentu saja biaya besar untuk membayar adalah bahwa Anda kehilangan hampir semua manfaat skema relasional.

Namun, Anda bisa mendapatkan yang terbaik dari kedua dunia jika Anda merancang dengan hati-hati database Anda: Anda masih dapat menetapkan skema relasional (yaitu: kolom kunci unik) dengan menggunakan atribut yang unik untuk setiap objek, dan kemudian menyimpan objek dalam gumpalan . Dengan cara ini, Anda masih dapat memastikan pengambilan cepat dari objek Anda diberi beberapa pengidentifikasi unik yang ditentukan oleh atribut objek Anda, juga mengurangi redundansi, sementara Anda memusnahkan ketidakcocokan impedansi dan menjaga fleksibilitas penuh objek Java.

Sebagai catatan, ada beberapa upaya oleh beberapa pembuat DB untuk memadukan model relasional dan objek bersama, seperti tipe data JSON di PostSQL dan PostgreSQL sehingga Anda dapat langsung memproses JSON seperti halnya kolom relasional, dan juga SQL3 dan OQL (Obyek Query Language) untuk menambahkan (terbatas) objek yang mendukung SQL.

Pada akhirnya, ini semua masalah desain dan kompromi antara model relasional dan model objek.

/ EDIT setelah membaca komentar: tentu saja, jika data Anda harus dapat dicari ("queryable"), Anda TIDAK harus menyimpan data Anda sebagai gumpalan. Tetapi jika beberapa bagian dari data Anda tidak dimaksudkan untuk dapat dicari , melainkan semacam meta-data, maka menyimpan bagian data ini sebagai objek di dalam gumpalan dapat menjadi solusi yang baik, terutama jika meta-data ini memiliki struktur yang fleksibel dan dapat berubah dari satu objek ke objek lainnya.


5

Mari kita berikan contoh praktis ketika saya melakukan ini di masa lalu.

Kami memiliki database yang berisi semua data untuk aplikasi muli-user; database juga memiliki tabel pengguna dengan hak akses mereka. Semua data ini dinormalisasi seperti yang diharapkan.

Kemudian kami memiliki permintaan agar aplikasi mengingat jendela apa yang telah dibuka pengguna dan apa yang mereka lakukan, sehingga dapat memulihkan keadaan saat pengguna mulai bekerja keesokan paginya.

  • Pertama jika ini kadang gagal, apakah itu tidak sopan

    • Misalnya, jika pertama kali seseorang menggunakan versi baru dari aplikasi itu lupa jendela yang telah mereka buka, jadi apa ...
  • Karena itu, ada 100% mundur jika objek berubah, jadi kami tidak dapat membaca blok.

  • Kami sudah memiliki database terpusat dengan kontrol akses, pencadangan, dll.
  • Biaya penyimpanan data dalam file tinggi, karena file harus diletakkan pada semacam server file yang dapat diakses oleh semua mesin pengguna, atau API harus ditulis untuk membaca file-file ini.

Lain waktu , kami memiliki sebuah aplikasi yang melakukan banyak berjalan lama perhitungan dan pengguna berharap untuk dapat me-restart perhitungan dari terakhir titik know baik jika ada pemadaman listrik, dll Tidak ada cara bahwa versi yang berbeda dari aplikasi dapat diharapkan untuk memulai kembali perhitungan, dan karena ada banyak objek yang perlu disimpan, normalisasi data akan menjadi mahal.

Karena database sudah ada dan digunakan untuk data aplikasi dinormalisasi yang terdefinisi dengan baik, dan tidak ada alasan nyata untuk tidak menggunakannya untuk menyimpan blog, kami mengambil pilihan yang masuk akal dan cepat.


4

Faktor yang sangat penting: serialisasi Java (yang dilakukan yang diaktifkan dengan menerapkan Serializable) adalah format yang sangat buruk, jadi Anda seharusnya tidak benar-benar menggunakannya untuk penyimpanan objek permanen.

Kerugian serialisasi java meliputi:

  • Data tidak benar-benar dapat dibaca dari bahasa lain.
  • Sangat tidak mudah untuk mempertahankan kompatibilitas maju objek berseri, yaitu: jika Anda menambahkan (atau menghapus) bidang ke kelas, tidak mudah untuk membaca objek yang dibuat oleh versi kelas sebelumnya.
  • Ini tidak secepat itu (tetapi jarak tempuh Anda mungkin beragam)

Jadi jika Anda menggunakan format serialisasi lainnya, Anda mendapatkan toko Key-Value yang bagus, jika Anda menggunakan serialisasi java, Anda mendapatkan kekacauan.


Fakta-fakta dalam jawaban itu hanya salah: 1) formatnya dicakup oleh spesifikasi lengkap; 2) menambahkan bidang bukan masalah sama sekali, formatnya sangat fleksibel; 3) kecepatan tergantung pada data aktual, tetapi sebanding (kadang-kadang lebih cepat, kadang-kadang lebih lambat) dengan format seperti JSON atau XML. Pada dasarnya, seluruh jawaban salah, kecuali satu baris: "data tidak benar-benar dapat dibaca dari bahasa lain".
fdreger

1
Terlepas dari 1)yang salah sisa jawabannya adalah IMO valid. Jika Anda ingin memiliki kontrol atas deserialisaton - yang diperlukan ketika Anda menambahkan / menghapus bidang (dan terutama ketika memiliki bidang terakhir) antarmuka tampak kikuk, dan Anda perlu menimpa lebih banyak metode yang diperlukan readObjectdan readReplace(untuk bidang terakhir).
jb.

Anda salah, menambahkan dan menghapus bidang tidak perlu menulis metode apa pun. Adapun bidang terakhir - jawaban asli Anda tidak menyebutkan sama sekali, dan jika itu benar, itu tidak relevan (masalahnya akan umum untuk semua format lain). Akhirnya, mengatakan "Ini tidak secepat itu (tetapi jarak tempuh Anda mungkin bervariasi)" tidak berarti apa-apa. Anda hanya memiliki satu fakta yang benar: satu tentang bahasa lain. Itu adalah dasar yang sangat lemah untuk menyebut sesuatu "berantakan".
fdreger

1
Menambahkan bidang tidak mengharuskan Anda untuk menulis metode apa pun, tetapi jika Anda ingin memengaruhi cara deserialisasi Anda harus menentukan perilaku itu. Saya akan mencoba menggali beberapa referensi untuk masalah dengan deserialisasi skema objek yang berkembang.
jb.

3

Ini adalah utas yang menarik dengan beberapa jawaban yang dipikirkan dengan matang. Tidak fasih dengan semua implikasi menyimpan dan mengambil objek bersambung saya pikir akan menarik untuk memberikan jawaban yang mungkin saya berikan kepada tim DBA atau tim pengembangan:

Kuncinya adalah untuk memenuhi persyaratan saat ini dan masa depan, dan menjaga solusinya sesederhana mungkin untuk meminimalkan pekerjaan dukungan di masa depan. Kedua persyaratan fungsional dan persyaratan non-fungsional (misalnya infrastruktur dan database) harus dipenuhi. Ingat aturan 80/20. Memahami pentingnya Aplikasi untuk bisnis dan upaya pengembangan apa yang sesuai.

Jangan terpaku pada ruang basis data, kecepatan dan memori jika tidak ada masalah.

Jika DBMS ada dalam daftar yang Anda setujui, Anda dapat menggunakannya dalam suatu solusi selama biayanya sesuai. Tidak ada masalah menggunakan Database Relasional untuk menyimpan gumpalan sederhana, terutama jika ini menyederhanakan hal-hal.

Jika solusinya adalah menjadi prototipe atau tahap / versi awal, ada lebih banyak tekanan yang harus dilakukan untuk menjaga hal-hal sederhana. Anda selalu dapat memperpanjang skema data nanti selama Anda berencana untuk itu.

Ingat database relasional tidak menegakkan integritas atau konsistensi kecuali jika skema mencakup area bisnis mandiri dan aturan bisnis yang ketat. (misalnya solusi untuk Pertanyaan Obyek Serial dapat mempertimbangkan repositori gaya kamus / ontologi untuk menegakkan aturan).

Layak mempertimbangkan bahwa semua database relasional tidak menggunakan skema database relasional murni (misalnya bintang, spasi, non-relasional ..), juga aplikasi dapat menggunakan database relasional sebagai toko non-relasional, seperti dalam pertanyaan. Banyak basis data bisnis inti bekerja dengan cara ini.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.