web-dev-qa-db-ja.com

データベースをgit(バージョン管理)の下に置くにはどうすればよいですか?

私はWebアプリをやっていますが、いくつかの主要な変更のためにブランチを作成する必要があります、つまり、これらの変更にはデータベーススキーマの変更が必要なので、データベース全体もgitの下に置きたいと思います。

それ、どうやったら出来るの? gitリポジトリの下に保持できる特定のフォルダーはありますか?どれを知るのですか?適切なフォルダーを配置していることを確認するにはどうすればよいですか?

これらの変更には後方互換性がないため、確認する必要があります。私は台無しにする余裕はありません。

私の場合のデータベースはPostgreSQLです

編集:

誰かがバックアップを取り、バックアップファイルをデータベースではなくバージョン管理下に置くことを提案しました。正直に言うと、それを飲み込むのは本当に難しいと思います。

より良い方法が必要です。

更新:

OK、それで良い方法はありませんが、私はまだ完全に納得していませんので、質問を少し変更します:

データベース全体をバージョン管理下に置きたいのですが、実際のデータベースをダンプではなくバージョン管理下に置くために、どのデータベースエンジンを使用できますか?

Sqliteはgitフレンドリーですか?

これは開発環境にすぎないため、必要なデータベースを選択できます。

編集2:

私が本当に望んでいるのは、開発履歴を追跡するのではなく、「新しい根本的な変更」ブランチから「現在の安定ブランチ」に切り替えて、たとえば現在のバグ/問題などを修正できるようにすることです安定したブランチ。そのため、ブランチを切り替えると、データベースは自動的に現在のブランチと互換性を持ちます。実際のデータについてはあまり気にしません。

249
hasen

データベースダンプを取得し、代わりにバージョン管理します。この方法では、フラットテキストファイルです。

個人的には、データダンプとスキーマダンプの両方を保持することをお勧めします。このようにdiffを使用すると、リビジョンごとにスキーマで何が変更されたかを簡単に確認できます。

大きな変更を行う場合は、ブランチを作成していると言ったので、新しいスキーマを変更し、古いスキーマを変更しないセカンダリデータベースが必要です。

127
X-Istence

データベースのリファクタリングとコードの変更を維持するための優れたテクニックについては、リファクタリングデータベース( http://databaserefactoring.com/ )をご覧ください。

あなたは間違った質問をしていると言って十分です。データベースをgitに配置する代わりに、スキーマの変更を簡単に移行/ロールバックできるように、変更を小さな検証可能な手順に分解する必要があります。

完全な回復可能性が必要な場合は、postgres WALログのアーカイブを検討し、PITR(ポイントインタイムリカバリ)を使用してトランザクションを特定の良好な状態に再生/転送する必要があります。

48
Paul Lindner

私は本当に簡単な解決策を考え始めています、なぜ私はそれを前に考えなかったのか分からない!!

  • データベースを複製します(スキーマとデータの両方)。
  • New-major-changesのブランチで、新しい複製データベースを使用するようにプロジェクト構成を変更するだけです。

このようにして、データベーススキーマの変更を気にせずにブランチを切り替えることができます。

編集:

複製とは、別の名前(my_db_2など)で別のデータベースを作成することを意味します。ダンプなどを行わない。

26
hasen

LiquiBase のようなものを使用します。これにより、Liquibaseファイルのリビジョン管理を維持できます。本番のみの変更をタグ付けし、本番または開発(または任意のスキーム)のいずれかのためにlbに最新のDBを保持させることができます。

19
zie

Doctrineの下に、この目的のためだけに構築されたMigrationsという素晴らしいプロジェクトがあります。

まだアルファ状態であり、php用に構築されています。

http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/index.html

6
Hakan Deryal

同様のニーズに直面しましたが、データベースバージョン管理システムに関する私の研究は次のようなものです。

  1. Sqitch-Perlベースのオープンソース。 PostgreSQLを含むすべての主要なデータベースで利用可能 https://github.com/sqitchers/sqitch
  2. Mahout-PostgreSQLのみ。オープンソースのデータベーススキーマバージョン管理。 https://github.com/cbbrowne/mahout
  3. Liquibase-別のオープンソースDBバージョン管理ソフトウェア。 Daticalの無料版。 http://www.liquibase.org/index.html
  4. Datical-Liquibaseの商用バージョン- https://www.datical.com/
  5. BoxFuseによるフライウェイ-商用sw。 https://flywaydb.org/
  6. 別のオープンソースプロジェクト https://gitlab.com/depesz/Versioning 著者はここにガイドを提供します: https://www.depesz.com/2010/08/22/versioning/
  7. Red Gate Change Automation-SQL Serverのみ。 https://www.red-gate.com/products/sql-development/sql-change-automation/

RedGate SQLソース管理をご覧ください。

http://www.red-gate.com/products/sql-development/sql-source-control/

このツールは、Gitを使用してデータベースをソース管理下に置くことができるSQL Server Management Studioスナップインです。

ユーザーあたり495ドルという少し高価ですが、28日間の無料試用版があります。

注RedGateとは一切関係ありません。

3
CShark

DBベースのディレクトリ構造に近いものが「ファイル」を保存し、それを管理するためにgitが必要になるという同様の問題を抱えているため、この質問に出くわしました。レプリケーションを使用してクラウド全体に分散されているため、アクセスポイントはMySQL経由になります。

上記の回答の要点は、データベースで何かを管理するためにGitを使用するという、問題を解決する別の解決策を同様に示唆しているようです。

Gitは、本質的にはデルタ(差分)のデータベースを格納するシステムであり、コンテキストを再現するために再構築できます。 gitの通常の使用法では、コンテキストはファイルシステムであり、それらのデルタはそのファイルシステム内のdiffであると想定していますが、実際にはすべてのgitはデルタの階層データベースです(ほとんどの場合、各デルタは少なくとも1つのコミットであるため、両親、ツリーに配置)。

理論的には、デルタを生成できる限り、gitはそれを保存できます。問題は通常、gitがデルタを生成しているコンテキストがファイルシステムであると想定していることです。同様に、git階層内のポイントをチェックアウトすると、ファイルシステムが生成されます。

データベースで変更を管理したい場合は、2つの個別の問題があり、それらに個別に対処します(私があなただった場合)。 1つ目はスキーマ、2つ目はデータです(ただし、あなたの質問では、データは心配するものではありません)。私が過去に抱えていた問題は、Dev and Prodデータベースでした。そこでは、Devがスキーマに増分変更を加えることができ、それらの変更はCVSで文書化され、いくつかの「静的な」テーブル。そのために、Cruiseという3番目のデータベースを作成しました。このデータベースには、静的データのみが含まれていました。 DevとCruiseのスキーマをいつでも比較でき、これらの2つのファイルの差分を取得し、ALTERステートメントを含むSQLファイルを生成して適用するスクリプトがありました。同様に、新しいデータは、INSERTコマンドを含むSQLファイルに抽出できます。フィールドとテーブルのみが追加され、削除されない限り、プロセスはデルタを適用するSQLステートメントの生成を自動化できます。

Gitがデルタを生成するメカニズムはdiffであり、1つ以上のデルタをファイルに結合するメカニズムはmergeと呼ばれます。異なるコンテキストからの差分とマージの方法を考え出すことができれば、gitは動作するはずですが、既に説明したように、それを行うツールを好むかもしれません。それを解決するための私の最初の考えはこれです https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#External-Merge-and-Diff-Tools which details gitの内部diffおよびマージツールを置き換える方法。問題に対するより良い解決策を考え出すので、この回答を更新しますが、私の場合は、DBベースのファイルストアが変更される可能性がある限り、データの変更を管理するだけでよいと考えています。正確にあなたが必要とするものではないかもしれません。

3
sibaz

同様のことを行い、データベースの変更をバージョン管理システムに追加します。

Vladimir Khorikov "データベースのバージョン管理のベストプラクティス" からのこの投稿のアイデアに従います。要約すると、

  • スキーマと参照データの両方をソース管理システムに保存します。
  • すべての変更に対して、変更を含む個別のSQLスクリプトを作成します

それが役立つ場合に!

3
Ciges

私はあなたが求めていることを行うsqliteのツールをリリースしました。 sqliteプロジェクトツール「sqldiff」、UUIDを主キーとして活用するカスタムdiffドライバーを使用し、sqlite ROWIDを省略します。まだアルファ版なので、フィードバックを歓迎します。

Postgresとmysqlは、バイナリデータが複数のファイルに保持され、スナップショットを作成できたとしても有効ではない可能性があるため、扱いにくいです。

https://github.com/cannadayr/git-sqlite

2
cannadayr

アトミック性なしではできません。また、pg_dumpまたはスナップショットファイルシステムを使用せずにアトミック性を取得することはできません。

私のpostgresインスタンスはzfs上にあり、時々スナップショットを撮ります。ほぼ瞬時に一貫性があります。

2
Dustin

あなたが望むのは、精神的には、おそらく Post Facto のようなもので、データベースのバージョンをデータベースに保存します。これを確認してください プレゼンテーション

このプロジェクトは明らかにどこにも行ったことはないので、おそらくすぐには役に立たないでしょうが、興味深いコンセプトです。これを適切に行うのは非常に難しいのではないかと心配しています。なぜなら、バージョン1でさえ、人々が作業を信頼するためにすべての詳細を正しく取得する必要があるからです。

2

X-Istenceは順調に進んでいると思いますが、この戦略にはさらにいくつかの改善点があります。まず、次を使用します。

$pg_dump --schema ... 

テーブル、シーケンスなどをダンプし、このファイルをバージョン管理下に置きます。これを使用して、ブランチ間の互換性の変更を分離します。

次に、フォームのように、アプリケーションが動作する(おそらくユーザーデータなどをスキップする必要がある)ための構成requiredを含むテーブルセットのデータダンプを実行しますデフォルトおよびその他のデータ、ユーザーが変更できないデータ。これを選択的に行うには、次を使用します。

$pg_dump --table=.. <or> --exclude-table=..

完全なデータダンプを実行するときにデータベースが100Mb +に達すると、リポジトリが非常に不格好になる可能性があるため、これは良い考えです。より良いアイデアは、アプリをテストするために必要な最小限のデータセットをバックアップすることです。ただし、デフォルトのデータが非常に大きい場合、これでも問題が発生する可能性があります。

リポジトリに完全バックアップを絶対に配置する必要がある場合は、ソースツリー外のブランチで行うことを検討してください。ただし、一致するsvn revを参照する外部バックアップシステムがこれに最適です。

また、(少なくともスキーマの場合)リビジョンの目的でバイナリ形式のテキスト形式のダンプを使用することをお勧めします。チェックインする前に、これらをいつでも圧縮してスペースを節約できます。

最後に、 postgresバックアップドキュメント をまだ見ていない場合はご覧ください。ダンプではなく「データベース」のバックアップについてコメントしている方法から、ファイルシステムベースのバックアップを考えているのではないかと思うようになります(警告についてはセクション 23.2 を参照してください)。

1
Dana the Sane

それは私がそれをする方法です:

DBタイプについては自由に選択できるので、たとえば火の鳥。

実際のブランチに適合するスキーマを持つテンプレートDBを作成し、リポジトリに保存します。

アプリケーションをプログラムで実行するときにテンプレートDBのコピーを作成し、それを別の場所に保存して、そのコピーを操作します。

これにより、データなしでDBスキーマをバージョン管理下に置くことができます。スキーマを変更する場合は、テンプレートDBを変更するだけです

1
RomCoo

neXtep をお勧めします。データベースを管理するバージョンについては、インストール方法と発生したエラーを説明する適切なドキュメントとフォーラムが用意されています。 postgreSQL 9.1および9.3でテストしましたが、9.1で動作するようになりましたが、9.3では動作しないようです。

1
Jerry M Sunny

この質問にはほとんど回答がありますが、X-IstenceとDana the Saneの回答を小さな提案で補完したいと思います。

毎日など、ある程度の粒度でリビジョン管理が必要な場合は、テーブルとスキーマの両方のテキストダンプを rdiff-backup のようなツールで結合して、増分バックアップを実行できます。利点は、毎日のバックアップのスナップショットを保存する代わりに、前日の差分を保存するだけです。

これにより、リビジョン管理の利点が得られ、スペースを無駄にしません。

いずれにせよ、非常に頻繁に変更される大きなフラットファイルにgitを直接使用することは、良い解決策ではありません。データベースが大きくなりすぎると、gitでファイルの管理に問題が発生し始めます。

1
unode

データベースの各レベルの変更 gitバージョン管理下での保存は、各コミットでentireデータベースをプッシュし、各プルでrestoringデータベース全体をプッシュするようなものです。データベースに重大な変更が発生しやすく、それらを失う余裕がない場合は、pre_commitおよびpost_mergeフックを更新するだけです。私は私のプロジェクトの1つで同じことをしました、そしてあなたは指示を見つけることができます ここ

1
AkiShankar

以前は、標準のLAMP構成でソーシャルWebサイトを実行していました。ライブサーバー、テストサーバー、開発サーバー、およびローカル開発者マシンがありました。すべてはGITを使用して管理されました。

各マシンには、PHPファイルだけでなく、MySQLサービス、およびユーザーがアップロードする画像を含むフォルダーがありました。 Liveサーバーは100K(!)のリカレントユーザーに成長し、ダンプは約2GB(!)、Imageフォルダーは50GB(!)でした。私が去る頃には、サーバーはそのCPU、Ram、そして何よりも同時ネット接続制限の限界に達していました(サーバーを最大限に活用するために独自のバージョンのネットワークカードドライバーをコンパイルしました)。 GITに2GBのデータと50GBの画像を配置することはできませんでした(Webサイトで想定するべきではありません)。

これらすべてをGITで簡単に管理するには、これらのフォルダーパスを.gitignoreに挿入して、バイナリフォルダー(画像を含むフォルダー)を無視します。また、Apache documentrootパスの外側にSQLというフォルダーがありました。そのSQLフォルダーに、開発者からのSQLファイルを増分番号(001.florianm.sql、001.johns.sql、002.florianm.sqlなど)に入れます。これらのSQLファイルもGITによって管理されていました。最初のsqlファイルには、実際には大量のDBスキーマが含まれます。 GITにはユーザーデータ(ユーザーテーブルのレコードやコメントテーブルなど)を追加しませんが、構成やトポロジなどのサイト固有のデータなどのデータは、SQLファイルで(したがってGITによって)維持されます。主に、SQLスキーマとデータに関してGITが何を管理し、何を管理しないのかを決定する開発者(コードを最もよく知っている)。

リリースに到達すると、管理者は開発サーバーにログインし、ライブブランチをすべての開発者および開発マシン上の必要なブランチと更新ブランチにマージし、テストサーバーにプッシュします。テストサーバーで、彼はライブサーバーの更新プロセスがまだ有効であるかどうかを確認し、Apacheのすべてのトラフィックをプレースホルダーサイトに向け、DBダンプを作成し、作業ディレクトリを 'live'から 'updateに向けます'、すべての新しいsqlファイルをmysqlで実行し、トラフィックを正しいサイトに再ポイントします。テストサーバーを確認した後、すべての関係者が同意すると、管理者はテストサーバーからライブサーバーに同じことを行いました。その後、運用サーバー上のライブブランチをすべてのサーバーのマスターブランチにマージし、すべてのライブブランチをリベースしました。開発者は自分のブランチをリベースする責任がありましたが、彼らは一般的に何をしているかを知っています。

テストサーバーに問題があった場合、例えばマージの競合が多すぎるため、コードが元に戻され(作業ブランチが「ライブ」に戻される)、SQLファイルは実行されませんでした。 SQLファイルが実行された瞬間、これはその時点では不可逆的なアクションと見なされていました。 SQLファイルが適切に機能していなかった場合は、Dumpを使用してDBが復元されました(そして、開発者は、十分にテストされていないSQLファイルを提供したことを伝えました)。

現在、同等のファイル名を持つsql-upフォルダーとsql-downフォルダーの両方を維持しています。開発者は、両方のアップグレードsqlファイルを同等にダウングレードできることをテストする必要があります。これは最終的にbashスクリプトで実行できますが、人間の目でアップグレードプロセスを監視し続けるのは良い考えです。

それは素晴らしいものではありませんが、管理可能です。これにより、実際の、実用的な、比較的可用性の高いサイトへの洞察が得られることを願っています。それは少し時代遅れになりますが、まだ続いています。

1
Florian Mertens

私の個人的なプロジェクトでは、データベース全体をDropboxに保存してから、MAMP、WAMPワークフローをポイントして、そこからすぐに使用しています。しかし、それは開発者のためだけです!ライブサイトはそのオフコースのために独自のサーバーを使用しています! :)

1
Marko

2019年8月26日更新:

Netlify CMS はGitHubで実行しています。実装例は、実装方法に関するすべての情報とともにここにあります netlify-cms-backend-github

0
Tuna

データベース全体をバージョン管理下に置きたいのですが、実際のデータベースをダンプではなくバージョン管理下に置くために、どのデータベースエンジンを使用できますか?

これはデータベースエンジンに依存しません。 Microsoft SQL Serverには、多くのバージョン管理プログラムがあります。 gitで問題を解決できるとは思いませんが、pgsql固有のスキーマバージョン管理システムを使用する必要があります。そのようなものが存在するかどうかはわかりません...

0
inf3rno

これが私のプロジェクトでやろうとしていることです:

  • データとスキーマ、およびデフォルトのデータを分離します。

データベース構成は、バージョン管理下にない構成ファイル(.gitignore)に保存されます

データベースのデフォルト(新しいプロジェクトのセットアップ用)は、バージョン管理下の単純なSQLファイルです。

データベーススキーマの場合、バージョン管理下でデータベーススキーマダンプを作成します。

最も一般的な方法は、SQLステートメントを含む更新スクリプト(ALTER Table ..またはUPDATE)を使用することです。また、現在のバージョンのスキーマを保存するデータベース内の場所が必要です)

他の大きなオープンソースデータベースプロジェクト(piwik、またはお気に入りのcmsシステム)を見てください。それらはすべてupdatescripts(1.sql、2.sql、3.sh、4.php.5.sql)を使用しています

しかし、これは非常に時間のかかる作業であるため、updatescriptsを作成およびテストする必要があり、バージョンを比較して必要なすべてのupdate scriptを実行する共通のupdatescriptを実行する必要があります。

したがって、理論的には(そして私が探しているもの)、各変更後にデータベーススキーマをダンプすることができます(手動で、コンジョブ、gitフック(おそらくコミット前))(そして非常に特別な場合にのみupdatescriptsを作成します)

その後、一般的なupdatescriptで(特別な場合は通常のupdatescriptsを実行して)スキーマ(ダンプと現在のデータベース)を比較し、必要なALTERステートメントを自動的に生成します。既にこれを実行できるツールがいくつかありますが、まだ良いツールは見つかりませんでした。

0
key_

IBatis Migrations( manualshort tutorial video )のようなツールを使用して、変更をバージョン管理できるようにしますデータベース自体ではなく、プロジェクトのライフサイクル全体でデータベースを作成します。

これにより、個々の変更を異なる環境に選択的に適用したり、どの環境にどの変更が含まれているかの変更ログを保持したり、変更AからNを適用するスクリプトを作成したり、変更をロールバックしたりできます。

0
matt b

私はしばらくの間、Postgres(または一般にSQLデータベース)に同じ機能を探していましたが、適切な(単純で直感的な)ツールが十分に見つかりませんでした。これはおそらく、データの格納方法のバイナリの性質によるものです。 Klonio 理想的に聞こえますが、死んでいます。 Noms DB 面白そう(そして生きている)。 Irmin (Git-propertiesを使用したOCamlベース)もご覧ください。

これはPostgresで動作するという点で質問には答えませんが、 Flur.ee データベースを確認してください。任意の時点からデータを照会できる「タイムトラベル」機能があります。 「分岐」モデルで動作するはずです。

このデータベースは、ブロックチェーンを目的として最近開発されました。ブロックチェーンの性質により、データは増分で記録する必要があります。これはまさにgitの仕組みです。 2019年第2四半期のオープンソースリリースを対象としています です。

各Flureeデータベースはブロックチェーンであるため、実行されたすべてのトランザクションの履歴全体を保存します。これは、ブロックチェーンが情報が不変で安全であることを保証する方法の一部です

0
Tails