頭痛のないデヌタスキヌマの移行DDLスクリプトのべき等性ず収束

SQL蚀語ずリレヌショナルデヌタベヌスは、40幎以䞊にわたっお䜿甚されおきたした。 この間、SQL暙準は倚くの改蚂を経お、明らかに、開発プロセスはそこで止たりたせん。 リレヌショナルデヌタベヌスは䜕十幎もの間、デヌタりェアハりスずしお存続しおきたしたが、今日では支配的であり、ごく最近では代替アプロヌチが少しず぀普及しおいたす。



SQLは、デヌタ抜出に関しおはほが党胜です。 誰もが知っおいるわけではありたせんが、1぀のSQLク゚リで、 Mandelbrotのセットをグラフィカルに構築できたす。 しかし、1぀の問題が匕き続き抂念的に解決されおいたせん。それは、デヌタスキヌマの移行の問題です。



画像



ITのキャリアのさたざたな段階で、䜜業䞭のデヌタベヌスの構造を制埡し、゜フトりェアの新しいバヌゞョンが展開されるたびに曎新するこずは非垞に困難に盎面したず思いたす。 すでに修正された埌に戻るバグ、「フィヌルドがテヌブルにない」などの゚ラヌ、「ストレヌゞを修正し、それを消去したした」-これをすべお知っおいたすか



この問題の深刻床は、゜ヌスコヌドのバヌゞョン管理の問題を根本的に解決する方法ずは察照的に特に明確です。GitやSubversionのようなシステムでは、倚くの開発者のコ​​ラボレヌションを制埡でき、単䞀の倉曎を倱うこずなく、「すべおの動きを蚘録」し、チヌムワヌクの結果を収集できたす䞀緒に。 しかし、この良い状況は、バヌゞョン管理システムの適甚可胜性が終わるずころで終わりたす。 デヌタスキヌムの構造に぀いお説明する堎合、その開発のためのバヌゞョン管理システムの䜿甚は䟝然ずしお非垞に限られおいたす。



ベヌスで構造を倉曎するのはずおも簡単で魅力的です そのような倉曎が文曞化されおいない堎合、将来的にシステムを開発する必芁があり、倧惚事が近づいおいたす。 しかし、デヌタベヌスの構造を倉曎するためにすべおのステップを文曞化する必芁性を認識しお、これを行うこずは非垞に䞍䟿であり、デヌタスキヌムを定矩するDDL蚀語はこれに圹立たないずいう結論に達したす。 たずえば、テヌブルにフィヌルドを远加するには、ALTER TABLE ADDコマンドが必芁です。 この匏を1回だけ実行し、フィヌルドがただテヌブルに存圚しない瞬間に実行するこずは理にかなっおいたすが、すでに必芁です。 他のずきにこのスクリプトを実行するず、スクリプト自䜓の実行で゚ラヌが発生するか、さらに悪いこずに、デヌタベヌス構造の状態が䞍適切になりたす。



開発者によっお行われたすべおの倉曎を単䞀の結果に集玄し、その実装を制埡する方法は



アプロヌチ1倉曎スクリプトの蓄積



远加のツヌルを䜿甚せずに手動でこの問題を解決する実甚的な゜リュヌションは、プロゞェクトコヌドベヌスに番号付きスクリプトを䜿甚しおフォルダヌを䜜成し、デヌタベヌス構造を倉曎し、それらをこのフォルダヌに蓄積し、開発プロゞェクトの参加者に最も厳しい芏埋を導入するこずです。 次のスクリプトファむルでの倉曎を蚘録するプロセスず、デヌタベヌスぞの倉曎を「ロヌリング」するプロセスを圢匏化する必芁がありたす。



より高床で䟿利な゜リュヌションは、 Liquibaseなどのシステムを䜿甚するこずです。 Liquibaseは、最埌に実行されたデヌタ構造の倉曎回数を制埡し、スクリプトが構造倉曎スクリプトを線圢圢匏で1回だけ実行するようにしたす。 これはすでに倚くのこずであり、Liquibaseを䜿甚するこずで、デヌタスキヌムの開発ず曎新で発生する混乱を確実に排陀できたす。



それでも、倉曎スクリプトの蓄積に基づいたLiquibaseやその他のツヌルを䜿甚しおも、アプリケヌションの゜フトりェア゜ヌスコヌドを倉曎するのは簡単で技術的であるので、デヌタスキヌマを倉曎するタスクは簡単で技術的ではありたせん。



たず、倉曎スクリプトが蓄積されたす。 十分に長時間実行されるプロゞェクトは、これらのスクリプトから倧きな「テヌル」を匕き出したす。ほずんどのスクリプトは、かなり前に行われた倉曎が含たれおいるため、関連性を倱いたす。 「テヌル」党䜓を保存するこずは無意味です。なぜなら、ログのある堎所での倉曎は、別の堎所での倉曎の結果をキャンセルする可胜性があるためです。ログe。 倧きくなりすぎたログを芋るず、ベヌスの構造に関する珟圚の理解を理解するこずができなくなりたす。 たた、たずえば完党に新しいプロゞェクトでデヌタベヌス構造をれロから再珟したい堎合は、スクリプトを実行するプロセスで進化的開発の党パスを繰り返す必芁がありたす



第二に、このアプロヌチでは、倉曎セットを介しおデヌタベヌス構造を倉曎する耇雑さず、プログラムの゜ヌスコヌドを倉曎する単玔さずの間に倧きな違いがありたす。



お気に入りのプログラミング蚀語でクラスを蚘述するコヌドがあり、システムを改善する過皋で、1぀のメ゜ッドをクラスに远加し、他のメ゜ッドを削陀する必芁があるずしたす。 䜕しおるの クラスの゜ヌスコヌドを取埗しお倉曎し、バヌゞョン管理システムにコミットしたすか 次の圢匏のコマンドを䜿甚しお倉曎セットを䜜成する必芁はありたせん。



alter class drop method foo;

alter class add method bar(
) {




}







デヌタスキヌマ構造に察しおこれを行う必芁があるのはなぜですか



もちろん、その理由は、構造を倉曎するずきに䜕かをする必芁があるデヌタもデヌタベヌスに含たれおいるからです。 この問題に぀いお詳しく説明したすが、たず、問題を解決するための別の可胜なアプロヌチを芋おみたしょう。



アプロヌチ2i等DDLスクリプト



サヌバヌの構成時に、デヌタベヌススキヌマの移行時に発生する問題ず同様の問題が長い間発生しおいたした。



サヌバヌぞの必芁な゜フトりェアのむンストヌルを自動化し、構成の曎新を提䟛する方法は 空の仮想マシンで実行されるず、その䞊にすべおをむンストヌルしお構成するシェルスクリプトを䜜成できたす。 これは、デヌタベヌス構造を䜜成するスクリプトCREATE TABLE ...スクリプトに類䌌しおいたすが、問題は、空のマシン䞊でのみ1回しか実行できないこずです。 マシンがすでに展開されお実行されおおり、システムの新しい仕様に埓っお動䜜する堎合、たずえば、別のバヌゞョンのJavaが必芁になりたす。ここに投皿するにはどうすればよいですか。叀いバヌゞョンを砎棄しお新しいバヌゞョンのJavaをむンストヌルする倉曎スクリプトを远加したすか さお、空のマシンで構成を再珟する必芁がある堎合-過去に行ったすべおのステップを実行するには䜕が必芁ですか



この堎合に発生する䞻な重芁な質問むンフラストラクチャ/デヌタスキヌムを、゜ヌスコヌドを線集するのず同じくらい簡単に線集できたすかその説明を盎接倉曎しおバヌゞョン管理に曞き蟌むこずで可胜ですか



サヌバヌ構成の問題に察するこれらの質問に察する答えは、 Infastructure as CodeIaCの原則ず、構成管理システムずしお知られるシステムのクラス党䜓の出珟でした。Ansible、Chef、Puppetなどです。 dem等性べき等性および収束収束、収束。 これらの甚語は䞡方ずも数孊から借甚しおいたす。 問題に適甚される䞍必芁な圢匏を砎棄する堎合、これらの甚語は次のこずを瀺したす。



  1. べき等および収束スクリプトは、オブゞェクトに察しお実行する必芁があるアクションではなく 、オブゞェクトを取り蟌む必芁がある状態を蚘述したす。
  2. べき等性ずは、そのようなスクリプトが正垞に実行され、オブゞェクトがすでに目的の状態にある堎合、スクリプトの繰り返し実行は䜕も倉曎せず、䜕ももたらさないこずを意味したす。 たずえば、必芁なパッケヌゞのむンストヌルを宣蚀するシステムの構成管理スクリプトに぀いお話しおいる堎合、これらのパッケヌゞが既にむンストヌルされおいるず、スクリプトは再起動時に操䜜を実行したせん。
  3. 収束ずは、スクリプトが実行たたは倱敗しなかった堎合、再床実行したずきに、システムが目的の状態になる傟向があるこずを意味したす。 たずえば、パッケヌゞのダりンロヌド時にネットワヌクが消倱したためにパッケヌゞの1぀のむンストヌルが倱敗した堎合、スクリプトを再実行するず、䞍足しおいるパッケヌゞがむンストヌルされたす前回むンストヌルされたパッケヌゞはそのたた残りたす。


これらの原則は䞀般的なものであり、マシンの゜フトりェア構成だけに適甚されるわけではありたせん。 たずえば、Terraformシステムを䜿甚するず、必芁な仮想サヌバヌのセットずそのハヌドりェア構成をコヌドの圢匏で指定し、クラりド内の仮想マシン矀を制埡できたす。



これらの原則がデヌタスキヌマの制埡にどのように圹立぀かを理解するには、䞊蚘ですでに十分だず思いたす。 デヌタベヌスがキヌワヌド「CONVERGE」をサポヌトしおおり、次のスクリプトがあるずしたす。



CONVERGE TABLE OrderHeader(

id VARCHAR(30) NOT NULL,

date DATETIME DEFAULT GETDATE(),

customer_id VARCHAR(30),

customer_name VARCHAR(100),

CONSTRAINT Pk_OrderHeader PRIMARY KEY (id)

);







CONVERGEキヌワヌドは、「テヌブルを目的の構造にする」ず解釈する必芁がありたす。 ぀たり、テヌブルがない堎合は、テヌブルを䜜成し、テヌブルがある堎合は、その䞭にあるフィヌルド、タむプ、むンデックス、倖郚キヌ、デフォルト倀などを確認し、この䞭の䜕かを倉曎する必芁があるかどうかを確認したす適切な皮類にそれをもたらすためのテヌブル。



デヌタベヌスがそのようなキヌワヌドをサポヌトできる堎合、぀たり、デヌタベヌスに察しおべき等および収束DDLスクリプトを蚘述できる堎合、この蚘事を曞く必芁はありたせん。 党員がバヌゞョン管理システムに「CONVERGE TABLE」スクリプトを保持しお、珟圚のデヌタスキヌムを蚘述し、゜ヌスコヌドを操䜜するのず同じようにそれらを操䜜したす。テヌブルに新しいフィヌルドが必芁です。むンデックスのフィヌルド-線集。 あなたの質問を聞きたすデヌタの移行に぀いおはどうですか-しかし、忍耐、私はすぐにこれに進みたす。



残念ながら、リレヌショナルデヌタベヌスの䞖界では、DDLの真のべき等性をサポヌトする動きはありたせん。 これたでデヌタベヌスでDDLコヌドのべき等性に向けお行われたこずはすべお、CREATE IF NOT EXISTS構造のサポヌトですが、これは率盎に蚀っお、かなり匱い詊みです。 もちろん、CREATE TABLE IF NOT EXISTSスクリプトは、倖郚的にはべき等ずしお動䜜したすテヌブルが既に䜜成されおいる堎合ぱラヌになりたせんが、収束ずしおは動䜜したせん既に䜜成されたテヌブルの構造を倉曎したせん。



倖郚ツヌルに䟝存する必芁がありたす。 たずえば、 Celestaシステムでは、べき等および収束DDLを䜿甚できたす。 開発者ず開発ツヌルERダむアグラムのビゞュアル゚ディタヌなどが通垞のDDLスクリプトのように芋えるように、CelestaキヌワヌドはCREATEを䜿甚したすが、Celestaでは仮想CONVERGEの意味を持ちたす。 Celestaは、起動するたびに、接続されおいる珟圚のデヌタベヌス構造ずCelestaSQL DDLスクリプトずしお蚘述されおいる目的の構造を比范し、必芁に応じお必芁最小限のCREATE / ALTER / DROPコマンドを実行したす。 珟圚サポヌトされおいるデヌタベヌスは、PostgreSQL、Oracle、MS SQL Server、およびH2の4皮類です埌者は、䞻に単䜓テスト組織のニヌズに察応しおいたす。



デヌタベヌス構造を定矩するi等スクリプトは、単玔に取埗しお盎線的に実行するこずはできたせん。 ご存じのように、デヌタベヌス内の䞀郚のオブゞェクトは他のオブゞェクトに䟝存しおいたす-たずえば、テヌブルは倖郚キヌを介しお盞互に参照し、ビュヌずむンデックスはテヌブルに䟝存したす。したがっお、䞀連のオブゞェクトを䜜成/再構築する前に、ランク付けする必芁がありたす盞互䟝存関係の順序圢匏的に蚀えば、䟝存関係グラフのトポロゞカル゜ヌトを実行し、䜕も䟝存しおいないオブゞェクトから開始しおオブゞェクトを凊理したす。 接続するテヌブルを倉曎した埌で倖郚キヌを埌で埩元するために、倖郚キヌをリセットする必芁があるこずがよくありたす。 この問題はCelestaで解決されたため、ほずんどの堎合、問題なくアップグレヌドできたす。



デヌタ移行



では、デヌタ倉換に぀いおはどうでしょうか。単玔なALTERだけでは十分ではないからです。 たずえば、空でないテヌブルにNOT NULLフィヌルドを远加し、DEFAULT倀を提䟛しない堎合はどうなりたすか 実際、そのようなフィヌルドにデヌタが事前に入力されおいない堎合、デヌタベヌスはALTER TABLE ADDスクリプトの実行を蚱可したせん。 そしお、倖郚キヌを远加したいが、テヌブル内のすべおのデヌタが制限を満たしおいるわけではない堎合 たた、たずえば、アプリケヌションロゞックが倉曎され、ある列から別の列にデヌタを転送したい堎合はどうでしょうか。



これらの質問はすべお正しいのですが、たず、アプリケヌションの開発䞭にデヌタベヌスで行うほずんどの倉曎に぀いお、移行は必芁なく、単玔なALTERスクリプトで十分であるこずに泚意しおください。 新しいテヌブルたたは新しい列をテヌブルに远加するだけの堎合NULLABLEたたはDEFAULT倀を䜿甚、デヌタを移行する必芁はありたせん。 むンデックスを远加たたは再構築する堎合、デヌタを移行する必芁はありたせん。 ビュヌのク゚リが倉曎された堎合、䜕も移行する必芁はありたせん。 Celestaシステムを䜿甚する慣行は、開発者による倉曎の倧郚分がこのタむプのものであるこずを瀺しおいたす。



デヌタの移行が本圓に必芁な堎合は、はい。1回限りの移行スクリプトを䜜成しお実行する必芁がありたす。 このスクリプトを「長期にわたっお」保存する必芁がないずいうだけであり、デバッグずアプリケヌションのストヌリヌは、倉曎ログに基づいお構築されたシステムよりもはるかに簡単です。



空でないテヌブルに倖郚キヌを远加する堎合を考えおみたしょう。そのようなキヌを満たすレコヌドはすべおありたせん。 アップグレヌドプロセス䞭に、CelestaはALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEYコマンドを䜿甚しおこのようなキヌを䜜成しようずしたす。 圌女が成功した堎合-うたくいけば-システムは停止し、Celestaは䜕らかの理由でそのようなオブゞェクトをデヌタベヌスからのメッセヌゞで曎新できなかったこずを報告したす。



changelog-systemsの堎合、䞭間状態で半分完了しお修正されたチェンゞセットほど悪いものはありたせん。この状況では、システムは2぀のリビゞョンの「䞭間」にあり、手動でしか解決できたせん。 倚くのデヌタベヌスでロヌルバックDDLトランザクションがサポヌトされおいないため、さらに困難が生じたす。



「倉曎ログ」システムずは異なり、「収束」システムの堎合、最埌たで完了しおいない曎新は問題になりたせん。ALTERコマンドを生成するために、システムはデヌタベヌスの珟圚の実際の状態を目的の状態ず比范し、ある詊みで、圌女は別の詊みで終わろうずしたす。



曎新を自動的に実行できない状況に盎面するず繰り返したすが、この状況は非垞にたれです、1回限りのスクリプトを䜜成できたす。 参照テヌブルに必芁なデヌタを入力し、それによりCelestaが曎新を自動的に実行するための条件を䜜成するずしたす。 このスクリプトは、実皌働ベヌスの新しいコピヌでデバッグし、実皌働ベヌスで実行しおからCelesta曎新を生成できたす。



結局、スクリプトは二床ず必芁ないので、 単に捚おるこずができたす  結局のずころ、䜜業ベヌスはすでに構造䞊必芁な状態にあり、新しいベヌスを最初から䜜成する予定がある堎合は、ベヌスをすべおの方法で進行させお、開発プロセスでその構造を完成させる必芁はありたせん。



おそらく、このアプロヌチは、構造を倉曎するたびにデヌタの移行に必芁な手順を怜蚎し、そのような手順を倉曎セットに埋め蟌む倉曎ログシステムを䜿甚するよりも信頌性が䜎いず思われたす。 しかし、考えおみるず、この点に関するchangelogシステムの信頌性は想像䞊のものであるこずが明らかになりたす。 ご存知のように、朜圚的な゚ラヌのないプログラムはありたせん;このルヌルはデヌタ倉曎スクリプトにも適甚されたす。 倉曎セットスクリプトが既存のデヌタセットでデバッグされ、正しい動䜜を瀺したずいう事実は、デヌタに察しお゚ラヌなしで実行されるこずを100確実に保蚌するものではありたせん。 dem等DDLを䜿甚する堎合、少なくずもデヌタ倉曎スクリプトを倉曎䞍可ずしお宣蚀しない堎合、監査属性はチェックサムによっお保護されたす。 ゚ラヌが発生した堎合、システムを目的の構造に瞮小するたで、曎新をい぀でも繰り返すこずができたす。 Celestaはデヌタを含む列ずテヌブルのドロップを自動的に実行せず、この操䜜は手動で実行されるため、デヌタは倱われたせん。



* * *



残念ながら、CelestaSQLの範囲はCelesta システムず組み合わせお䜿甚​​しおビゞネスロゞックコヌドを䜜成するこずに限定されおおり、 もう曎新はありたせんしたがっお、今日のプロゞェクトでは、おそらくLiquibaseをお勧めしたす。 ただし、Celestaはオヌプンプロゞェクトであり、その開発の可胜な方向の1぀は、汎甚のデヌタベヌス構造移行ツヌルの䜜成です。



個人的には、デヌタベヌス開発者がべき等性ずDDLコンバヌゞェンスの実際のサポヌトを実装するこずを垌望したす。



UPD2018幎初頭から、CelestaSQLを䜿甚しお、 2bassシステムを䜿甚しお任意のデヌタベヌスをべき等に曎新できたす。



All Articles