Saya sedang melakukan aplikasi web, dan saya perlu membuat cabang untuk beberapa perubahan besar, masalahnya, perubahan ini memerlukan perubahan pada skema database, jadi saya ingin meletakkan seluruh database di bawah git juga.
Bagaimana aku melakukan itu? apakah ada folder tertentu yang bisa saya simpan di bawah repositori git? Bagaimana saya tahu yang mana? Bagaimana saya bisa yakin bahwa saya meletakkan folder yang benar?
Saya harus yakin, karena perubahan ini tidak kompatibel mundur; Saya tidak mampu mengacau.
Basis data dalam kasus saya adalah PostgreSQL
Edit:
Seseorang menyarankan untuk mengambil cadangan dan meletakkan file cadangan di bawah kontrol versi daripada database. Sejujurnya, saya menemukan itu sangat sulit untuk ditelan.
Harus ada cara yang lebih baik.
Memperbarui:
OK, jadi tidak ada cara yang lebih baik, tapi saya masih belum cukup yakin, jadi saya akan sedikit mengubah pertanyaan:
Saya ingin meletakkan seluruh basis data di bawah kontrol versi, mesin basis data apa yang dapat saya gunakan sehingga saya dapat menempatkan basis data yang sebenarnya di bawah kontrol versi daripada dump-nya?
Apakah sqlite ramah-git?
Karena ini hanya lingkungan pengembangan, saya dapat memilih database apa pun yang saya inginkan.
Sunting2:
Apa yang saya inginkan sebenarnya bukan untuk melacak sejarah perkembangan saya, tetapi untuk dapat beralih dari cabang "perubahan radikal baru" saya ke "cabang stabil saat ini" dan dapat misalnya memperbaiki beberapa bug / masalah, dll, dengan arus cabang stabil. Sehingga ketika saya beralih cabang, database secara otomatis menjadi kompatibel dengan cabang saya saat ini. Saya tidak terlalu peduli dengan data aktual.
bup
Jawaban:
Ambil dump database, dan kontrol versi sebagai gantinya. Dengan cara ini, ini adalah file teks datar.
Secara pribadi saya menyarankan Anda menyimpan dump data, dan dump skema. Dengan menggunakan diff ini menjadi cukup mudah untuk melihat apa yang berubah dalam skema dari revisi ke revisi.
Jika Anda membuat perubahan besar, Anda harus memiliki database sekunder tempat Anda membuat perubahan skema baru dan tidak menyentuh yang lama karena seperti yang Anda katakan Anda sedang membuat cabang.
sumber
Lihat Refactoring Databases ( http://databaserefactoring.com/ ) untuk sekelompok teknik yang baik untuk menjaga database Anda bersama-sama dengan perubahan kode.
Cukuplah untuk mengatakan bahwa Anda mengajukan pertanyaan yang salah. Alih-alih menempatkan database Anda ke git, Anda harus mendekomposisi perubahan Anda menjadi langkah-langkah kecil yang dapat diverifikasi sehingga Anda dapat melakukan migrasi / kembalikan perubahan skema dengan mudah.
Jika Anda ingin memiliki pemulihan penuh, Anda harus mempertimbangkan untuk mengarsipkan log WAL postgres Anda dan menggunakan PITR (titik pemulihan waktu) untuk memutar kembali / meneruskan transaksi ke kondisi baik tertentu yang diketahui.
sumber
Saya mulai memikirkan solusi yang sangat sederhana, tidak tahu mengapa saya tidak memikirkannya sebelumnya !!
Dengan cara ini saya bisa berganti cabang tanpa khawatir tentang perubahan skema database.
EDIT:
Dengan duplikat, maksud saya membuat database lain dengan nama yang berbeda (seperti
my_db_2
); tidak melakukan dump atau semacamnya.sumber
Gunakan sesuatu seperti LiquiBase ini memungkinkan Anda tetap mengontrol revisi file Liquibase Anda. Anda dapat menandai perubahan hanya untuk produksi, dan biarkan DB memperbarui informasi untuk produksi atau pengembangan, (atau skema apa pun yang Anda inginkan).
sumber
Menghadapi kebutuhan serupa dan inilah yang diajukan penelitian saya tentang sistem kontrol versi database:
sumber
ChronicDB
juga:ChronicDB provides dynamic database upgrades with zero database downtime and inconsistencies.
crunchbase.com/organization/chronicdb#section-overview Seorang pria bernama Kristis Makris adalah salah satu pendiri, mungkin dikenal dengan SCMBug: mkgnu.net/scmbugAda proyek besar yang disebut Migrasi di bawah Ajaran yang dibangun hanya untuk tujuan ini.
Masih dalam kondisi alfa dan dibangun untuk php.
http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/index.html
sumber
Saya telah menemukan pertanyaan ini, karena saya punya masalah serupa, di mana sesuatu mendekati struktur Direktori berbasis DB, menyimpan 'file', dan saya perlu git untuk mengelolanya. Ini didistribusikan, melintasi cloud, menggunakan replikasi, maka jalur aksesnya akan melalui MySQL.
Inti dari jawaban di atas, tampaknya juga menyarankan solusi alternatif untuk masalah yang ditanyakan, jenis apa yang melenceng, menggunakan Git untuk mengelola sesuatu dalam Database, jadi saya akan mencoba menjawab pertanyaan itu.
Git adalah sebuah sistem, yang pada dasarnya menyimpan database delta (perbedaan), yang dapat disusun kembali, untuk mereproduksi konteks. Penggunaan normal dari git mengasumsikan bahwa konteks adalah sistem file, dan delta-delta itu berbeda dalam sistem file itu, tetapi sebenarnya semua git, adalah database hirarki dari delta (hierarkis, karena dalam kebanyakan kasus setiap delta adalah komit dengan setidaknya 1 orang tua, diatur dalam pohon).
Selama Anda dapat menghasilkan delta, secara teori, git dapat menyimpannya. Masalahnya biasanya git mengharapkan konteks, di mana ia menghasilkan delta menjadi sistem file, dan juga, ketika Anda checkout titik dalam hierarki git, ia mengharapkan untuk menghasilkan sistem file.
Jika Anda ingin mengelola perubahan, dalam database, Anda memiliki 2 masalah tersendiri, dan saya akan mengatasinya secara terpisah (jika saya adalah Anda). Yang pertama adalah skema, yang kedua adalah data (meskipun dalam pertanyaan Anda, Anda menyatakan data bukan sesuatu yang Anda khawatirkan). Masalah yang saya miliki di masa lalu, adalah basis data Dev dan Prod, di mana Dev dapat melakukan perubahan tambahan pada skema, dan perubahan itu harus didokumentasikan dalam CVS, dan dipacu untuk hidup, bersama dengan penambahan ke salah satu dari beberapa 'statis' meja. Kami melakukan itu dengan memiliki database ke-3, yang disebut Cruise, yang hanya berisi data statis. Pada titik mana pun skema dari Dev dan Cruise dapat dibandingkan, dan kami memiliki skrip untuk mengambil perbedaan dari 2 file tersebut dan menghasilkan file SQL yang berisi pernyataan ALTER, untuk menerapkannya. Demikian pula data baru, bisa disaring ke file SQL yang berisi perintah INSERT. Selama bidang dan tabel hanya ditambahkan, dan tidak pernah dihapus, proses tersebut dapat secara otomatis menghasilkan pernyataan SQL untuk menerapkan delta.
Mekanisme yang digunakan git untuk menghasilkan delta adalah
diff
dan mekanisme yang digunakannya untuk menggabungkan 1 delta atau lebih dengan sebuah file, disebutmerge
. Jika Anda dapat menemukan metode untuk membedakan dan menggabungkan dari konteks yang berbeda, git harus berfungsi, tetapi seperti yang telah dibahas, Anda mungkin lebih suka alat yang melakukannya untuk Anda. Pikiran pertama saya untuk memecahkan itu adalah https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#External-Merge-and-Diff-Tools yang merinci cara mengganti diff internal git dan alat gabung. Saya akan memperbarui jawaban ini, karena saya menemukan solusi yang lebih baik untuk masalah ini, tetapi dalam kasus saya, saya berharap hanya harus mengelola perubahan data, sejauh-sejauh-sebagai filestore berbasis DB dapat berubah, jadi solusi saya mungkin tidak persis apa yang Anda butuhkan.sumber
Lihatlah RedGate SQL Source Control.
http://www.red-gate.com/products/sql-development/sql-source-control/
Alat ini adalah snap-in SQL Server Management Studio yang akan memungkinkan Anda untuk menempatkan database Anda di bawah Kontrol Sumber dengan Git.
Agak mahal di $ 495 per pengguna, tetapi ada uji coba gratis 28 hari tersedia.
CATATAN Saya tidak berafiliasi dengan RedGate dengan cara apa pun.
sumber
Saya ingin membuat sesuatu yang serupa, tambahkan perubahan database saya ke sistem kontrol versi saya.
Saya akan mengikuti ide-ide dalam posting ini dari Vladimir Khorikov "Database best practices terbaik" . Singkatnya saya akan
Seandainya itu membantu!
sumber
Saya telah mencari fitur yang sama untuk Postgres (atau database SQL secara umum) untuk sementara waktu, tetapi saya tidak menemukan alat yang cocok (sederhana dan intuitif). Ini mungkin karena sifat biner dari bagaimana data disimpan. Klonio terdengar ideal tetapi terlihat mati. Noms DB terlihat menarik (
dan hidup). Lihat juga Irmin (berbasis OCaml dengan properti Git).Meskipun ini tidak menjawab pertanyaan karena ini akan berfungsi dengan Postgres, periksa database Flur.ee. Ini memiliki fitur "perjalanan waktu" yang memungkinkan Anda untuk menanyakan data dari titik waktu yang sewenang-wenang. Saya kira itu harus bisa bekerja dengan model "percabangan".
Database ini baru-baru ini dikembangkan untuk tujuan blockchain. Karena sifat blockchains, data perlu direkam secara bertahap, seperti itulah git bekerja. Mereka menargetkan rilis sumber terbuka pada Q2 2019 .
Pembaruan : Lihat juga basis data Crux , yang dapat menanyakan dimensi waktu sisipan, yang dapat Anda lihat sebagai 'versi'. Crux tampaknya merupakan implementasi open-source dari Datomic yang sangat dinilai.
sumber
Anda tidak dapat melakukannya tanpa atomicity, dan Anda tidak bisa mendapatkan atomicity tanpa menggunakan pg_dump atau filesystem snapshotting.
Contoh postgres saya ada di zfs, yang saya snapshot sesekali. Ini kira-kira instan dan konsisten.
sumber
Apa yang Anda inginkan, dalam semangat, mungkin adalah sesuatu seperti Post Facto , yang menyimpan versi database dalam database. Periksa presentasi ini .
Proyek ini tampaknya tidak pernah benar-benar pergi ke mana pun, jadi mungkin tidak akan segera membantu Anda, tetapi ini konsep yang menarik. Saya takut melakukan ini dengan benar akan sangat sulit, karena bahkan versi 1 harus mendapatkan semua detail dengan benar agar orang mempercayai pekerjaan mereka.
sumber
Saya telah merilis alat untuk sqlite yang melakukan apa yang Anda minta. Ia menggunakan driver kustom berbeda yang memanfaatkan alat proyek sqlite 'sqldiff', UUID sebagai kunci utama, dan meninggalkan rowid sqlite. Itu masih dalam alpha sehingga umpan balik sangat dihargai.
Postgres dan mysql lebih rumit, karena data biner disimpan dalam banyak file dan bahkan mungkin tidak valid jika Anda dapat memotretnya.
https://github.com/cannadayr/git-sqlite
sumber
Saya pikir X-Istence berada di jalur yang benar, tetapi ada beberapa perbaikan lagi yang dapat Anda lakukan untuk strategi ini. Pertama, gunakan:
untuk membuang tabel, urutan, dll dan menempatkan file ini di bawah kontrol versi. Anda akan menggunakan ini untuk memisahkan perubahan kompatibilitas antara cabang Anda.
Selanjutnya, lakukan dump data untuk set tabel yang berisi konfigurasi yang diperlukan untuk aplikasi Anda untuk beroperasi (mungkin harus melewati data pengguna, dll), seperti formulir default dan data lainnya data yang dapat dimodifikasi pengguna. Anda dapat melakukan ini secara selektif dengan menggunakan:
Ini adalah ide yang bagus karena repo bisa menjadi sangat kikuk ketika database Anda mencapai 100 MB + ketika melakukan dump data lengkap. Ide yang lebih baik adalah mencadangkan set data yang lebih minimal yang Anda perlukan untuk menguji aplikasi Anda. Jika data default Anda sangat besar, ini mungkin masih menyebabkan masalah.
Jika Anda benar-benar perlu untuk membuat cadangan penuh di repo, pertimbangkan untuk melakukannya di cabang di luar pohon sumber Anda. Sistem cadangan eksternal dengan beberapa referensi ke svn rev yang cocok mungkin yang terbaik untuk ini.
Juga, saya sarankan menggunakan format teks kesedihan atas biner untuk tujuan revisi (setidaknya untuk skema) karena ini lebih mudah untuk diff. Anda selalu dapat mengompres ini untuk menghemat ruang sebelum check-in.
Terakhir, lihat dokumentasi cadangan postgres jika Anda belum melakukannya. Cara Anda mengomentari mencadangkan 'database' daripada dump membuat saya bertanya-tanya apakah Anda berpikir tentang backup berbasis sistem file (lihat bagian 23.2 untuk peringatan).
sumber
Pertanyaan ini cukup banyak dijawab tetapi saya ingin melengkapi jawaban X-Istence dan Dana the Sane dengan saran kecil.
Jika Anda memerlukan kontrol revisi dengan beberapa tingkat granularitas, katakan setiap hari, Anda bisa memasangkan dump teks dari kedua tabel dan skema dengan alat seperti rdiff-backup yang melakukan backup tambahan. Keuntungannya adalah bahwa alih-alih menyimpan snapshot dari cadangan harian, Anda hanya menyimpan perbedaan dari hari sebelumnya.
Dengan ini, Anda memiliki keuntungan dari kontrol revisi dan Anda tidak membuang terlalu banyak ruang.
Dalam kasus apa pun, menggunakan git secara langsung pada file flat besar yang sering berubah bukanlah solusi yang baik. Jika database Anda menjadi terlalu besar, git akan mulai mengalami beberapa masalah dalam mengelola file.
sumber
Inilah yang saya coba lakukan dalam proyek saya:
Konfigurasi basis data disimpan dalam file konfigurasi yang tidak di bawah kontrol versi (.gitignore)
Default basis data (untuk menyiapkan Proyek baru) adalah file SQL sederhana di bawah kontrol versi.
Untuk skema database, buat dump skema database di bawah kontrol versi.
Cara paling umum adalah memiliki skrip pembaruan yang berisi Pernyataan SQL, (Tabel ALTER .. atau PEMBARUAN). Anda juga perlu memiliki tempat di basis data tempat Anda menyimpan versi skema Anda saat ini)
Lihatlah proyek database open source besar lainnya (piwik, atau sistem cms favorit Anda), semuanya menggunakan skrip pembaruan (1.sql, 2.sql, 3.sh, 4.php.5.sql)
Tapi ini pekerjaan yang sangat intensif, Anda harus membuat, dan menguji skrip pembaruan dan Anda harus menjalankan skrip pembaruan umum yang membandingkan versi dan menjalankan semua skrip pembaruan yang diperlukan.
Jadi secara teoritis (dan itulah yang saya cari), Anda dapat membuang skema database setelah setiap perubahan (secara manual, conjob, git hooks (mungkin sebelum komit)) (dan hanya dalam beberapa kasus yang sangat khusus membuat skrip pembaruan)
Setelah itu di skrip pembaruan umum Anda (jalankan skrip pembaruan normal, untuk kasus khusus) dan kemudian bandingkan skema (dump dan database saat ini) dan kemudian secara otomatis menghasilkan Pernyataan ALTER yang perlu. Ada beberapa alat yang bisa melakukan ini, tetapi belum menemukan yang bagus.
sumber
Saya akan merekomendasikan neXtep untuk versi mengendalikan basis data. Ia memiliki seperangkat dokumentasi dan forum yang menjelaskan cara menginstal dan kesalahan yang ditemui. Saya telah mengujinya untuk postgreSQL 9.1 dan 9.3, saya bisa membuatnya bekerja untuk 9.1 tetapi untuk 9.3 sepertinya tidak berfungsi.
sumber
Apa yang saya lakukan dalam proyek pribadi saya adalah, saya menyimpan seluruh database saya ke dropbox dan kemudian menunjuk MAMP, alur kerja WAMP untuk menggunakannya langsung dari sana .. Dengan begitu database selalu up-to-date di mana pun saya perlu melakukan pengembangan. Tapi itu hanya untuk dev! Situs langsung menggunakan server sendiri untuk itu tentunya! :)
sumber
Menyimpan setiap tingkat perubahan basis data di bawah kontrol versi git seperti mendorong seluruh basis data Anda dengan setiap komit dan mengembalikan seluruh basis data Anda dengan setiap tarikan. Jika database Anda begitu rentan terhadap perubahan penting dan Anda tidak mampu untuk kehilangan mereka, Anda hanya dapat memperbarui Anda pre_commit dan post_merge kait. Saya melakukan hal yang sama dengan salah satu proyek saya dan Anda dapat menemukan arahannya di sini .
sumber
Begitulah cara saya melakukannya:
Karena Anda memiliki pilihan bebas tentang jenis DB, gunakan DB berbasis file seperti misalnya firebird.
Buat DB templat yang memiliki skema yang sesuai dengan cabang Anda yang sebenarnya dan simpan di repositori Anda.
Saat menjalankan aplikasi Anda secara terprogram membuat salinan DB templat Anda, simpan di tempat lain dan hanya bekerja dengan salinan itu.
Dengan cara ini Anda dapat menempatkan skema DB Anda di bawah kontrol versi tanpa data. Dan jika Anda mengubah skema Anda, Anda hanya perlu mengubah DB template
sumber
Kami biasa menjalankan situs web sosial, dengan konfigurasi LAMP standar. Kami memiliki server Langsung, server Uji, dan server Pengembangan, serta mesin pengembang lokal. Semua dikelola menggunakan GIT.
Di setiap mesin, kami memiliki file PHP, tetapi juga layanan MySQL, dan folder dengan Gambar yang akan diunggah pengguna. Server Live tumbuh memiliki beberapa pengguna berulang 100K (!), Dumpnya sekitar 2GB (!), Folder Gambar sekitar 50GB (!). Pada saat saya pergi, server kami telah mencapai batas CPU, Ram, dan yang paling penting, batas koneksi internet bersamaan (Kami bahkan menyusun versi driver kartu jaringan kami sendiri untuk memaksimalkan server 'lol'). Kami tidak bisa ( dan Anda tidak boleh berasumsi dengan situs web Anda ) memasukkan 2GB data dan 50GB gambar di GIT.
Untuk mengelola semua ini di bawah GIT dengan mudah, kami akan mengabaikan folder biner (folder yang berisi Gambar) dengan memasukkan jalur folder ini ke .gitignore. Kami juga memiliki folder bernama SQL di luar jalur documentroot Apache. Dalam folder SQL itu, kita akan meletakkan file SQL kita dari pengembang dalam penomoran tambahan (001.florianm.sql, 001.johns.sql, 002.florianm.sql, dll). File SQL ini dikelola oleh GIT juga. File sql pertama memang akan berisi sekumpulan besar skema DB. Kami tidak menambahkan data pengguna di GIT (mis. Catatan tabel pengguna, atau tabel komentar), tetapi data seperti konfigurasi atau topologi atau data spesifik situs lainnya, disimpan dalam file sql (dan karenanya oleh GIT). Sebagian besar pengembang (yang tahu kode terbaik) yang menentukan apa dan apa yang tidak dikelola oleh GIT berkaitan dengan skema SQL dan data.
Ketika sampai pada rilis, administrator login ke server dev, menggabungkan cabang langsung dengan semua pengembang dan membutuhkan cabang pada mesin dev ke cabang pembaruan, dan mendorongnya ke server uji. Di server pengujian, ia memeriksa apakah proses pembaruan untuk server Live masih valid, dan secara berurutan, mengarahkan semua lalu lintas di Apache ke situs placeholder, membuat dump DB, mengarahkan direktori kerja dari pembaruan 'langsung' ke ' ', mengeksekusi semua file sql baru ke mysql, dan mengembalikan lalu lintas kembali ke situs yang benar. Ketika semua pemangku kepentingan setuju setelah meninjau server uji, Administrator melakukan hal yang sama dari server Uji ke server Langsung. Setelah itu, ia menggabungkan cabang langsung di server produksi, ke cabang master di semua server, dan mengubah semua cabang langsung.
Jika ada masalah di server pengujian, mis. penggabungan memiliki terlalu banyak konflik, kemudian kodenya dikembalikan (menunjuk cabang kerja kembali ke 'live') dan file sql tidak pernah dieksekusi. Saat file sql dieksekusi, ini dianggap sebagai tindakan yang tidak dapat dibalik pada saat itu. Jika file SQL tidak berfungsi dengan baik, maka DB dikembalikan menggunakan Dump (dan pengembang mengatakan, untuk menyediakan file SQL yang tidak teruji).
Hari ini, kami memelihara folder sql-up dan sql-down, dengan nama file yang setara, di mana para pengembang harus menguji bahwa kedua file sql yang diupgrade, dapat diturunkan peringkatnya. Ini pada akhirnya bisa dieksekusi dengan skrip bash, tapi itu ide yang bagus jika mata manusia terus memantau proses peningkatan.
Ini tidak bagus, tetapi bisa dikelola. Semoga ini memberi wawasan tentang situs kehidupan nyata, praktis, dan ketersediaan relatif tinggi. Mungkin agak ketinggalan jaman, tapi tetap diikuti.
sumber
Gunakan alat seperti iBatis Migrations ( manual , video tutorial singkat ) yang memungkinkan Anda mengontrol perubahan yang Anda buat pada basis data sepanjang siklus proyek, alih-alih dari database itu sendiri.
Hal ini memungkinkan Anda untuk secara selektif menerapkan perubahan individual ke lingkungan yang berbeda, menyimpan changelog di mana perubahan berada di lingkungan mana, membuat skrip untuk menerapkan perubahan A hingga N, perubahan rollback, dll.
sumber
Ini bukan mesin database yang tergantung. Dengan Microsoft SQL Server ada banyak program pengendali versi. Saya tidak berpikir masalah itu dapat diselesaikan dengan git, Anda harus menggunakan sistem kontrol versi skema khusus pgsql. Saya tidak tahu apakah hal seperti itu ada atau tidak ...
sumber
Pembaruan 26 Agustus 2019:
Netlify CMS melakukannya dengan GitHub, contoh implementasi dapat ditemukan di sini dengan semua informasi tentang bagaimana mereka menerapkannya netlify-cms-backend-github
sumber