連鎖創建分店數據庫方法

  連鎖軟件中,數據庫結構不外兩種,一種是所有數據都放同一個數據庫,包括總部,另一種是總部獨立數據庫,每個分店一個數據庫,而我常用的就是獨立的數據庫。

  這兩種方法各有優勢,數據放同一個數據庫,各分店之間數據進行交互時會非常方便,有統計之類的,也是直接在數據庫上操作,沒那麼多麻煩,不好的地方就是,數據一多,不便於維護,也得去考慮分頁等問題。而第二個方法就是剛上和第一個的好壞相反,但是我覺得分開的話數據會非常清晰,維護方便,當然這只是針對我們軟件數據庫之間交互不多的情況,可能有的數據庫之間交互數據比較頻繁,就是用第一個方法,沒有什麼維護問題,也會選擇第一,各有好壞,看各人使用。


  獨立數據庫就得處理創建分店時怎麼創建數據庫的問題,因爲軟件是一直在更新的,也就是數據庫也是一直更新,所以創建分店數據庫,也必須是靈活的。

  (Mssql)最早用的的方法:會在總部放一個數據庫的備份文件(Bak),每次更新就是覆蓋Bak文件,而創建數據庫的思路,1.把model數據庫備份成model.bak,2.把bak文件還原到model中,3.直接用create database 語句就可以建一個分店數據庫了,4.用model.bak還原回model數據庫,【注意:創建數據庫時,都會以model數據庫模版來創建,這裏正是利用這個】

  這個方法是可以實現創建分店,但是比較笨,每次更新都要在更新文件里加個數據庫bak文件,而且數據庫都一直在增大,雖然是空數據庫,只有表結構等這些東西,但也得8M+,這在更新時帶來很多麻煩,於是後面又想到一個方法,在原有基礎上改進。

  (Mssql)改進的方法:1.在安裝軟件時,會在mssql server上創建一個模版數據庫,這個模版數據庫也可以看作一個分店的數據庫,軟件更新時,會更新這個數據庫,更新完會備份這個模版數據庫,覆蓋總部中的Bak文件,後面創建分店時怎麼創建數據庫的還是沒變,和上面一樣。這裏改進的主要就是數據庫模版問題,這樣做的話,就不用每次更新帶上數據庫文件了。

  最初的軟件就一直使用這個方法到現在。

  最近有一套新軟件,在數據庫的設計上又是遇到這問題,我總覺得改進過的方法也不是很方便,於是又想到下面的改進方法。

1.保持使用模版數據庫,模版數據庫隨分店的更新一同更新,Bak文件使用不上了,作廢。2.在創建分店時,先創建一個空的數據庫,然後通過程序讀取模版數據庫的所有結構到新數據庫上執行,簡單點說就是通過程序來複制模版數據庫的所有結構。

這樣就不用再使用Bak那樣的笨重文件了,而且數據庫可以獨立一個服務器,老方法是數據庫和軟件必須同一個服務器,因爲要依賴放在總部裏的Bak文件,而現在數據庫和軟件就可以脫離,模版數據庫保護最新,分店創建新數據庫複製模版數據庫的結構,問題都解決 了。

隨帶說一下Mysql,因爲我們軟件是兼容多種數據庫的,Mysql也是其中,前期mysql和mssql的思路是一樣的,都是通過更新數據庫文件,用數據庫備份文件來創建新數據庫,後面Mysql也改成這種最優的方法:1.軟件安裝完,自動創建一個模版數據庫,2.創建新分店時,會把數據庫備份成sql文件,再在程序中修改sql文件中的數據庫名稱,3.執行sql文件。這裏mysql和mssql不一樣的地方就是,mssql的複製表結構,必須一個一個去模版數據讀出來再在新數據庫上執行,而mysql的備份就是導出數據庫的所有結構,我們只需要修改一個數據庫名稱爲新的數據庫執行。

下面附上C#裏複製數據庫的方法:

public void InitialData(string ModelDataBaseName, string DataBaseName)
        {
            #region 處理表和表數據
            string strSql_GetUserTable = string.Format("select * from {0}.dbo.GetUserTable order by id,columnsort ", ModelDataBaseName);
            DataTable dt_GetUserTable = dbHelper.ExecuteQuery(CommandType.Text, strSql_GetUserTable, null).Tables[0];
            if (dt_GetUserTable.Rows.Count > 0)
            { 
                //id,tablename,columnsort,columnname,tablekey,columndatatype,columndatalen1
                //columndatalen2,columndatafloat,allowisnull,defaultdata
                string tableName = "";
                StringBuilder strCreateTableSql = new StringBuilder();
                StringBuilder strKeySql = new StringBuilder();
                StringBuilder strInsertData = new StringBuilder();

                foreach (DataRow dr in dt_GetUserTable.Rows)
                {
                    if (dr["tablename"].ToString() != tableName)
                    {
                        if (!string.IsNullOrEmpty(strCreateTableSql.ToString()))
                        {                           
                            if (strKeySql.Length > 0)
                            {
                                strKeySql.Remove(strKeySql.Length - 1, 1);
                                strCreateTableSql.AppendFormat(" PRIMARY KEY CLUSTERED ( {0} )) ON [PRIMARY] ", strKeySql.ToString());
                                strKeySql.Remove(strKeySql.Length - 1, 1);

                            }
                            else
                            {
                                if (strCreateTableSql.ToString().EndsWith(","))
                                strCreateTableSql.Remove(strCreateTableSql.Length - 1, 1);
                                strCreateTableSql.Append(" )");
                            }
                            dbHelper.ExecuteNonQuery(DataBaseName, strCreateTableSql.ToString(), null);
                            dbHelper.ExecuteNonQuery(CommandType.Text, string.Format(" insert into {0}.dbo.{1} select * from {2}.dbo.{1} ", DataBaseName, tableName, ModelDataBaseName), null);
                        }
                        tableName = dr["tablename"].ToString();
                        strCreateTableSql.Clear(); strCreateTableSql = new StringBuilder();
                        strKeySql.Clear(); strKeySql = new StringBuilder();
                        strCreateTableSql.AppendFormat(" create table {0} (", tableName);
                    }
                    strCreateTableSql.Append(dbHelper.GetDataType(dr["columnname"].ToString(),dr["columndatatype"].ToString(), dbHelper.GetInt(dr["columndatalen2"].ToString()),
                        dbHelper.GetInt(dr["columndatafloat"].ToString()), dr["allowisnull"].ToString(), dr["tablekey"].ToString(),ref strKeySql));
                }
                if (!string.IsNullOrEmpty(strCreateTableSql.ToString()))
                {
                    if (strKeySql.Length > 0)
                    {
                        strKeySql.Remove(strKeySql.Length - 1, 1);
                        strCreateTableSql.AppendFormat(" PRIMARY KEY CLUSTERED ( {0} )) ON [PRIMARY] ", strKeySql.ToString());
                        strKeySql.Remove(strKeySql.Length - 1, 1);
                    }
                    else
                    {
                        if (strCreateTableSql.ToString().EndsWith(","))
                            strCreateTableSql.Remove(strCreateTableSql.Length - 1, 1);
                        strCreateTableSql.Append(" )");
                    }
                    dbHelper.ExecuteNonQuery(DataBaseName, strCreateTableSql.ToString(), null);
                    dbHelper.ExecuteNonQuery(CommandType.Text, string.Format(" insert into {0}.dbo.{1} select * from {2}.dbo.{1} ", DataBaseName, tableName, ModelDataBaseName), null);
                }
            }
            #endregion

            #region 存儲過程、視圖、函數、觸發器
            StringBuilder strSql = new StringBuilder();
            strSql.AppendFormat("  select name,type,definition from {0}.dbo.GetUserPV  ",ModelDataBaseName);
            DataTable dt_GetUserPV = dbHelper.ExecuteQuery(CommandType.Text, strSql.ToString(), null).Tables[0];
            if (dt_GetUserPV.Rows.Count > 0)
            {
                StringBuilder strTest = new StringBuilder();
                foreach (DataRow dr in dt_GetUserPV.Rows)
                {
                    dbHelper.ExecuteNonQuery(DataBaseName, string.Format("{0}", dr["definition"].ToString()), null);
                }
                
            }
            #endregion
        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章