【強烈推薦】數據庫遷移利器:Migrator.Net


簡介

很郁悶,寫了一天的遇到LiveWriter錯誤,可惡啊

幾年前在做項目中第一次接觸到了Migrator.Net,就深深被吸引住了,至此以后在新的大項目中,我都會使用Migrator.Net來創建或者更新數據庫架構。曾經在項目中也發現了小bug並提交給了作者,當時還是有點小激動啊。幾年過去了,Migrator.Net雖然已經遷移到了github上,但作者好像從3年前就不再更新了,不過這不影響我對它的喜愛,一如既往的使用着它,它的出現讓我對數據庫這塊徹底的放開,不用手動去創建表,不用手動的去創建索引,一切就這么簡單。

目前Migrator.Net原生代碼支持:MsSql,Oracle,PostgreSql,Sqlite,MySql。當然您也可以繼承其幾個抽象類,完成對其他數據庫的支持。使用 Migrator.Net,您可以不用關注使用的是什么類型數據庫,數據庫之間的遷移也很方便,我們只要關注的是我需要哪些表,哪些字段,哪些索引,哪些關聯。

您是否碰到過在項目成熟后,新來的CTO要改變數據庫類型,或者重新獨立數據庫,又或者數據的越來越大,更新更好的數據庫呢?這時候作為碼農的我們是最頭大的時候,因為我可能是在中途接手的項目,也有可能是幾年前設計的數據庫,鬼知道要做些什么工作啊!為了吃飯,不得不重新研究數據庫,不更改數據庫類型還好,導出腳本即可,遇到更改數據庫類型,天吶~~~有了Migrator.Net,以后您就不需要再有這個擔心了,交給他來吧!

准備工作

目前Migrator.Net已經更新至0.9.1版本,您可以通過NuGet管理器下載其相關Dll到您的項目中。最好您也下載其源代碼:https://github.com/migratordotnet/Migrator.NET

為了幫助VS2012以前版本的朋友,我打包一下所需的工具及dll,點擊下載

下載源代碼后,我們看一下他有3個主項目

image

Migrator.Framework 我們編寫數據庫結構時所需要用到的框架

Migrator.Providers 提供了對各個數據庫的支持

Migrator 這個就是最終運行升級、回滾操作的類庫。

准備工作做好,我們來看下如何創建新表

創建新表

我這次還是用上一篇FluentNhibernate中的數據表,直接看代碼,很好理解的:

[Migration(1)]
    public class _001_AddTable_Store : Migration
    {
        public override void Down()
        {
            Database.RemoveTable("Store");
        }

        public override void Up()
        {
            Database.AddTable("Store",
                new Column("Id", DbType.Int32, ColumnProperty.PrimaryKeyWithIdentity),
                new Column("Name", DbType.String, 100, ColumnProperty.NotNull));
        }
    }

我們所有需要Migrator.Net控制的,都需要繼承Migration抽象類,實現Down和Up方法,還需要在類特性中使用MigrationAttribute指定版本號。Migrator.Net在運行時,會根據指定的版本號進行升級或者回滾操作。

Migration.Up:版本升級時所需的操作

Migration.Down:版本回滾時所需的操作

Database.AddTable:創建新表

Column:列表類,通過指定列名、類型、長度、列屬性創建新列

ColumnProperty:列屬性

[Flags]
    public enum ColumnProperty
    {
        None = 0,
        Null = 1,
        NotNull = 2,
        Identity = 4,
        Unique = 8,
        Indexed = 16,
        Unsigned = 32,
        ForeignKey = 33,
        PrimaryKey = 98,
        PrimaryKeyWithIdentity = 102,
    }

對應的都是數據庫中列的一些屬性,大家應該可以看懂吧

Database.RemoveTable:刪除某個表

Up和Down一般都是一一對應的,增加個表,刪除個表,增加約束,刪除約束等等。

小貼士:建議大家版本號一定要遞增,所以在版本類中,我們可以使用“版本號_操作_表名”來命名文件,比如:001_AddTable_Store.cs

接下來我們再創建一個Employee表:

[Migration(2)]
    public class _002_AddTable_Employee : Migration
    {
        private const string tablename = "Employee";

        public override void Up()
        {
            Database.AddTable(tablename, 
                new Column("Id", DbType.Int32, ColumnProperty.PrimaryKeyWithIdentity),
                new Column("LastName", DbType.String, 50, ColumnProperty.NotNull),
                new Column("FirstName", DbType.String,50, ColumnProperty.NotNull),
                new Column("Store_Id", DbType.Int32, ColumnProperty.NotNull));

            Database.AddForeignKey("FK_Employee_Store",
                "Employee", "Store_Id",
                "Store", "Id");
        }

        public override void Down()
        {
            Database.RemoveForeignKey(tablename, "FK_Employee_Store");
            Database.RemoveTable(tablename);
        }
    }

在這個版本中,我們使用了Database.AddForeignKey使Employee表與Store表有了關聯。除了之前介紹的AddTable和RemoveTable之外,還有以下常用方法:

ITransformationProvider.AddForeignKey 添加關系

ITransformationProvider.RemoveForeignKey 移除關系

ITransformationProvider.AddCheckConstraint 添加約束

ITransformationProvider.AddUniqueConstraint 添加唯一約束

ITransformationProvider.RemoveConstraint 移除約束

ITransformationProvider.AddPrimaryKey 添加主鍵

ITransformationProvider.AddColumn 添加列

ITransformationProvider.RemoveColumn 移除列

在刪除某個表時,請先清除其約束、關系,否則無法刪除。

ok,基本了解后,我們來運行一下

運行

你可以自己寫個運行程序,使用Migrator類庫中的方法,也可以使用作者已經寫好的一個控制台程序進行版本控制。項目所在位置:

image

使用以下命令運行數據遷移:

Migrator.Console.exe SqlServer2005 "Data Source=.;Initial Catalog=MigratorDemo;Integrated Security=SSPI" DataBaseDemo.dll -version 2

藍色:數據庫類型,對應的是Migrator.Providers.Dialect的子類

紅色:數據庫連接字符串

橙色:程序集文件名

綠色:版本號,如果忽略將會更新到最新版本,通過-version可以升級和回滾操作。

小貼士:為了項目方便,我把命令寫在了bat文件里,方便升級和回滾,您可以點擊下載我的工具包

在運行前,我們需要用SqlServer Management Studio連接到數據庫,創建一個新的數據庫:MigratorDemo

運行以上命令,如果一切順利,您將看到如下界面:

image

我們看下Migrator.Net在數據庫中創建了什么?

image image

除了我們創建的2個表之外,另外還有一個SchemaInfo表,其中記錄了所有的版本信息,請不要手動操作該表。

更新Table

很多時候,我們會不斷的更新我們的Table,使其適應我們不斷變更的項目。以往我們在更新表格的時候,都會去數據庫進行操作,為了我們的應用環境,我們都會寫成腳本再去更新,現在有了Migrator.Net我們只需要創建一個升級版本,讓它幫我們去更新table,就算遇到錯誤,因為使用了事務控制,在升級中出現問題也會及時回滾。

接下來我們為Employee表格添加年齡字段:

[Migration(3)]
    public class _003_AddColumn_Employee : Migration
    {
        private const string tablename = "Employee";

        public override void Up()
        {
            Database.AddColumn(tablename, 
                new Column("Age", DbType.Byte, ColumnProperty.NotNull, 0));
        }

        public override void Down()
        {
            
        }
    }

通過AddColumn添加表,這里注意下,在Down方法中,我並未對應使用RemoveColumn,是因為在項目中,我添加表和添加表字段中間會發生多次數據庫操作,在添加字段后,也會對數據庫進行多次操作,所以為了數據庫數據不遺失,我這里的Down操作沒有添加任何動作,這樣只當RemoveTable的時候才會刪除這個表的所有數據。當然這個也要按照你的實際情況來,不能一概而就的。

紅色0是這個字段的默認值,因為有時候添加字段的時候,這個表已經產生數據,而字段又是非可空類型,這時候您必須添加默認值,否則運行會失敗。

運行下,我們看下數據庫是否相應進行了改變:

image image

我們看到Employee表已經成功添加了Age字段,SchemaInfo表也相應的添加了版本號3

回滾

有時候我們在開發項目時,會經常對數據庫進行改動,但改動后又會感覺不好,再去回滾,在以前我們都會去數據庫進行操作,現在我們只要用回滾操作就可以了,我們只需要指定需要回滾到的版本號即可,我們試着回滾到version 1

Migrator.Console.exe SqlServer2005 "Data Source=.;Initial Catalog=MigratorDemo;Integrated Security=SSPI" DataBaseDemo.dll –vsersion 1

運行以上命令,然后查看下數據庫的改變:

image image

看到了吧,利用Migrator.Net,一切都是如此簡單。

有了Migrator.Net是否不需要DBA了?

答案肯定是否定的。Migrator.Net只是方便了我們的數據庫遷移工作,並不能代替DBA的工作,DBA還需要進行很多數據庫相關的工作,這是Migrator.Net無法代替的。

在項目中,我建議DBA先行設計數據庫架構,再通過碼農進行代碼編寫,雙方相互合作。

Migrator.Net給我們帶來了什么?

給我們帶來了什么?這個話題不太好說,至少對於我來說,我不需要關心數據庫遷移產生的問題,我只需要關注我的項目開發這塊了,利用Migrator.Net再配合ORM工具,我都不用去關心數據庫類型不同產生的問題了。

今天給大家帶來這個工具,雖說已經是個老工具了,但用起來還是杠杠滴,現在通過Nuget你搜索Migrator會搜出很多,但基本原理都差不多。Migrator.Net也開放了很多接口,我們可以通過自己編寫代碼讓其適應我們的項目,比如數據庫表創建后添加一些靜態數據等。

大家應該用過一些開源項目,通過web安裝方式安裝數據庫、配置文件等,一般都是運行編寫好的Sql語句,有了Migrator.Net,通過其一些接口方法,我們同樣可以利用Web方式運行操作。

寫在最后

Migrator.Net雖說是個好工具,但是否使用還得看您的項目,如果項目已經開始到一半或者接近尾聲,那使用他也未必可以為您帶來好處,但如果項目人員流動性比較大的話,還是建議您寫一個遷移類庫,以免造成新人對適應環境所造成的時間損失。

原本清明前寫好的,因為自己的不小心,只得重新來過,呵呵。希望這篇教程能給您帶來幫助。

最近看了2則新聞,相信大家都應該知道:

7歲捐腎救母男孩離世 媽媽眼含熱淚接受手術

看到這則新聞,真的很痛心,我剛當父親不久,寶寶的發燒都會時時牽動我的心。這個男孩救母的行為真心打動了我。孩子的媽媽也不容易,真的無法想想這個媽媽在接受手術時是個什么樣的心情。希望這個媽媽為她的孩子繼續活着!

11歲女孩獨自照顧82歲奶奶3個妹妹和2個患病叔伯

小女孩真懂事,這是世界太多的不公平,但她還能笑着面對。我們的紅x會,福利機構統統馬航,作為一個普通的IT屌絲,希望通過自己的綿薄之力贊助其學業。但是新聞上沒有公布任何其信息,所以希望在此通過大家幫我尋找下,目前的信息為:張雪群 瀘州市納溪區合面鎮馬橋村

如果有小女孩消息的,請直接聯系我,QQ:785418


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM