Proyek saya saat ini pada dasarnya adalah menjalankan sistem manajemen dokumen pabrik.
Konon, ada beberapa kerutan (surprise, surprise). Sementara beberapa kerutan cukup spesifik untuk proyek ini, saya percaya ada beberapa pengamatan umum dan pertanyaan yang muncul yang tidak memiliki jawaban kanonik (yang bisa saya temukan), dan yang berlaku untuk domain masalah yang lebih luas . Ada banyak hal di sini dan saya tidak yakin itu cocok untuk format Tanya Jawab StackExchange, tetapi saya pikir itu a) pertanyaan yang dapat dijawab dan b) tidak spesifik sehingga dapat bermanfaat bagi masyarakat. Beberapa pertimbangan saya khusus untuk saya, tetapi saya pikir pertanyaan itu bisa berguna bagi siapa saja yang dihadapkan dengan memutuskan SQL vs NoSQL vs keduanya.
Latar belakang:
Aplikasi web yang kami bangun berisi data yang jelas bersifat relasional dan juga data yang berorientasi dokumen. Kami ingin memiliki kue kami dan memakannya juga.
TL; DR: Saya pikir # 5 di bawah ini lulus uji bau. Apakah kamu? Adakah yang punya pengalaman dengan integrasi SQL dan NOSQL dalam satu aplikasi? Saya mencoba membuat daftar semua pendekatan yang mungkin untuk kelas masalah ini di bawah. Apakah saya melewatkan alternatif yang menjanjikan?
Kompleksitas:
- Ada banyak kelas dokumen yang berbeda. Persyaratan sudah meminta puluhan dokumen yang berbeda. Jumlah ini hanya akan naik. Kasus terbaik yang mungkin terjadi adalah di mana kita dapat memanfaatkan bahasa spesifik domain sederhana, pembuatan kode, dan skema yang fleksibel sehingga pakar domain dapat menangani penambahan kelas dokumen baru tanpa intervensi dari DBA atau programmer. (Catatan: sudah sadar kita hidup di luar Aturan Kesepuluh Greenspun )
- Integritas penulisan sukses sebelumnya adalah persyaratan utama proyek. Data akan menjadi bisnis yang kritis. Semantik penuh ACID tentang menulis dapat dikorbankan asalkan hal-hal yang berhasil ditulis tetap berhasil.
- Dokumen-dokumen itu sendiri kompleks. Dokumen prototipe dalam kasus khusus kami akan membutuhkan penyimpanan 150+ bagian data yang berbeda per instance dokumen. Kasus patologis bisa menjadi urutan besarnya lebih buruk, tetapi jelas bukan dua.
- Satu kelas dokumen adalah target bergerak subjek untuk pembaruan pada suatu titik waktu.
- Kami menyukai barang gratis yang kami dapatkan dari Django ketika kami mengaitkannya ke database relasional. Kami ingin menyimpan barang gratis tanpa harus melompat mundur dua versi Django untuk menggunakan garpu Django-nonrel. Dumping ORM sepenuhnya lebih baik daripada menurunkan ke 1.3.
Pada dasarnya, ini adalah campuran data relasional (hal-hal aplikasi web khas Anda seperti pengguna, grup, dll., Serta dokumen metadata yang kami perlukan untuk dapat mengiris dan memotong dengan pertanyaan kompleks secara realtime) dan mendokumentasikan data (mis. ratusan bidang yang kami tidak tertarik untuk bergabung atau bertanya dengan - satu-satunya kasus penggunaan kami untuk data akan untuk menunjukkan dokumen tunggal ke mana ia dimasukkan).
Saya ingin melakukan pemeriksaan kewarasan (jika Anda memeriksa riwayat posting saya, saya cukup eksplisit tentang fakta bahwa saya bukan DBA) pada metode pilihan saya serta menghitung semua opsi yang saya temui untuk penyelesaian orang lain. masalah serupa secara luas yang melibatkan data relasional dan non-relasional.
Solusi yang Diusulkan:
1. Satu tabel per kelas dokumen
Setiap kelas dokumen mendapatkan tabelnya sendiri, dengan kolom untuk semua metadata dan data.
Keuntungan:
- Model data SQL standar sedang dimainkan.
- Data relasional ditangani dengan cara terbaik. Kami akan mendenormalisasi nanti jika perlu.
- Antarmuka bawaan Django admin nyaman dengan mengintrospeksi tabel-tabel ini dan ORM dapat hidup bahagia dengan 100% data di luar kotak.
Kekurangan:
- Mimpi buruk pemeliharaan. Lusinan (ratusan?) Tabel dengan (puluhan?) Ribuan kolom.
- Logika tingkat aplikasi bertanggung jawab untuk memutuskan dengan tepat ke tabel mana harus ditulis. Menjadikan nama tabel sebagai parameter untuk kueri berbau.
- Pada dasarnya semua perubahan logika bisnis akan membutuhkan perubahan skema.
- Kasus patologis mungkin memerlukan striping data untuk formulir tunggal di beberapa tabel (lihat: Berapa jumlah maksimum kolom dalam tabel PostgreSQL? ).
- Kita mungkin perlu mencari DBA yang nyata, jujur kepada Tuhan yang pasti akan membenci hidup kita.
2. pemodelan EAV
Hanya ada tabel bidang. Pemodelan Entity-Attribute-Value sudah dipahami dengan baik. Saya sudah memasukkannya untuk kelengkapan. Saya tidak berpikir ada proyek baru yang dimulai pada 2013 akan pergi dengan pendekatan EAV sengaja.
Keuntungan:
- Mudah dimodelkan.
Kekurangan:
- Lebih sulit untuk dicari.
- Lapisan DB tidak lagi memiliki representasi lurus ke depan untuk apa yang merupakan satu objek tingkat aplikasi.
- Kami akan kehilangan pemeriksaan kendala tingkat DB.
- Jumlah baris di satu meja akan tumbuh 100-1000 kali lebih cepat. Kemungkinan titik sakit di masa depan, kinerja-bijaksana.
- Pengindeksan terbatas mungkin.
- Skema DB tidak masuk akal sejauh menyangkut ORM. Baterai termasuk hal-hal aplikasi web dipertahankan tetapi model data khusus akan membutuhkan permintaan khusus.
3. Gunakan bidang PostgreSQL hstore atau json
Salah satu dari jenis bidang ini akan melakukan trik untuk menyimpan data schemaless dalam konteks DB relasional. Satu-satunya alasan saya tidak langsung beralih ke solusi ini adalah itu relatif baru (diperkenalkan pada versi 8.4 jadi bukan yang baru), saya memiliki nol paparan sebelumnya untuk itu dan saya curiga. Menurut saya itu salah karena alasan yang persis sama. Saya merasa tidak nyaman dengan memasukkan semua data saya yang bagus dan mudah dinormalisasi ke dalam bahasa Mongo - walaupun Mongo dapat menangani referensi antar dokumen.
Keuntungan:
- Kami mendapatkan manfaat dari Django ORM dan manajemen sesi dan autor bawaan.
- Semuanya tetap dalam satu backend yang sebelumnya kita gunakan pada proyek lain berhasil.
Kekurangan:
- Tidak ada pengalaman dengan ini, secara pribadi.
- Itu tidak terlihat seperti fitur yang sangat digunakan. Sepertinya mereka direkomendasikan sedikit kepada orang-orang yang mencari solusi NOSQL tapi saya tidak melihat banyak bukti bahwa mereka sedang dipilih. Ini membuat saya berpikir saya pasti kehilangan sesuatu.
- Semua nilai yang disimpan adalah string. Kehilangan pemeriksaan kendala tingkat DB.
- Data di hstore tidak akan pernah ditampilkan kepada pengguna kecuali mereka secara khusus melihat dokumen, tetapi metadata yang disimpan dalam kolom yang lebih standar adalah. Kami akan mengalahkan metadata itu dan saya khawatir hstores yang agak besar yang akan kami buat mungkin akan datang dengan kelemahan kinerja.
4. Pergi penuh berorientasi dokumen
Buat semua dokumen hal-hal (dalam pengertian MongoDB). Buat satu koleksi jenis Document
dan panggil satu hari. Bawa semua data periferal (termasuk data pada akun pengguna, grup, dll) ke dalam mongo juga. Solusi ini jelas lebih baik daripada pemodelan EAV tetapi rasanya salah bagi saya karena alasan yang sama # 3 merasa salah - mereka berdua merasa seperti menggunakan palu sebagai obeng juga.
Keuntungan:
- Tidak perlu memodelkan data di muka. Memiliki satu koleksi dengan dokumen jenis
Document
dan menyebutnya sehari. - Dikenal karakteristik penskalaan yang baik, koleksi harus tumbuh untuk mencakup jutaan atau bahkan milyaran dokumen.
- Format JSON (BSON) intuitif untuk pengembang.
- Seperti yang saya pahami (yang hanya samar-samar pada saat ini), dengan menjadi paranoid berkenaan dengan tingkat kepedulian menulis, bahkan sebuah instance dapat memberikan keamanan data yang cukup kuat jika terjadi apa saja dan semuanya hingga crash hard drive.
Kekurangan:
- ORM berada di luar jendela untuk bagasi Django. Gratis yang pergi keluar jendela dengan itu: kerangka kerja auth, kerangka sesi, antarmuka admin, pasti banyak hal lainnya.
- Harus menggunakan kemampuan referensi mongo (yang membutuhkan beberapa kueri) atau mendenormalkan data. Kami tidak hanya kehilangan gratis yang kami dapatkan dari Django, kami juga kehilangan gratis seperti BERGABUNG yang kami terima begitu saja di PostgreSQL.
- Keamanan data. Ketika seseorang membaca tentang MongoDB, sepertinya selalu ada setidaknya satu orang yang merujuk pada bagaimana hal itu akan dan kehilangan data Anda. Mereka tidak pernah mengutip kejadian tertentu dan itu semua mungkin hanya omong kosong atau hanya terkait dengan api default lama dan lupa menulis-keprihatinan tetapi masih membuat saya khawatir. Kami tentu saja akan menggunakan strategi cadangan yang cukup paranoid dalam hal apapun (jika data rusak secara diam-diam itu bisa jadi tidak penting tentu saja ..).
5. PostgreSQL dan MongoDB
Data relasional masuk dalam database relasional dan data dokumen masuk ke database berorientasi dokumen. The documents
tabel pada database relasional berisi semua data yang kita mungkin perlu indeks atau slice dan dadu pada serta MongoDB ObjectId yang kita akan gunakan ketika kita perlu permintaan untuk nilai yang sebenarnya dari kolom di dokumen. Kami tidak akan dapat menggunakan ORM atau admin internal untuk nilai-nilai dokumen itu sendiri, tetapi itu bukan kerugian besar karena seluruh aplikasi pada dasarnya adalah antarmuka admin untuk dokumen dan kami mungkin harus sesuaikan bagian tertentu dari ORM ke tingkat yang tidak dapat diterima untuk membuatnya berfungsi seperti yang kita butuhkan.
Keuntungan:
- Setiap backend hanya melakukan apa yang baik.
- Referensi antara model dipertahankan tanpa memerlukan beberapa pertanyaan.
- Kami bisa menjaga baterai yang diberikan Django kepada kami sejauh menyangkut pengguna, sesi, dll.
- Hanya perlu satu
documents
tabel tidak peduli berapa banyak kelas dokumen yang berbeda dibuat. - Data dokumen yang lebih jarang ditanyakan sangat dipisahkan dari metadata yang jauh lebih sering ditanyakan.
Kekurangan:
- Mengambil data dokumen akan membutuhkan 2 kueri berurutan, pertama melawan SQL DB dan kemudian melawan MongoDB (meskipun ini tidak lebih buruk daripada jika data yang sama telah disimpan dalam bahasa Mongo dan tidak didenormalkan)
- Menulis tidak lagi menjadi atom. Tulisan terhadap satu dokumen Mongo dijamin atomik dan PG jelas dapat membuat jaminan atomisitas tetapi memastikan atomisitas penulisan di keduanya akan membutuhkan logika aplikasi, tidak diragukan lagi dengan penalti kinerja dan kompleksitas.
- Dua backends = dua bahasa permintaan = dua program yang berbeda dengan persyaratan admin yang berbeda = dua database berlomba-lomba mencari memori.
JSON
tipe data. Jangan takut menggunakan fitur baru di Postgres - tim Postgres tidak merilis fitur yang tidak stabil. Dan 9,2 bukankah itu benar-benar baru). Plus, Anda dapat menggunakan fitur JSON baru di 9.3 begitu ada. Jika Anda selalu sepenuhnya memproses dokumen dalam kode aplikasi Anda (daripada menggunakan SQL), Anda juga bisa menyimpan JSON dalamtext
kolom biasa .