每當跨月的時候也是系統出問題最多的時候,沒有表和字段缺失是兩個最常見的錯誤。
為了解決這個問題,研究了一下mysql的 information_schema 表:
information_schema這張數據表保存了MySQL服務器所有數據庫的信息。如數據庫名,數據庫的表,表欄的數據類型與訪問權限等。
再簡單點,這台MySQL服務器上,到底有哪些數據庫、各個數據庫有哪些表,每張表的字段類型是什么,各個數據庫要什么權限才能訪問,等等信息都保存在information_schema表里面。
OK!事情已經變得相當簡單了。高手可以無視以下內容了。
按月分表為例:
第一步:查詢出當月以及下月滿足分表規則的表名
select table_name,table_schema from information_schema.tables where table_schema =@DatabaseName and table_type='base table' and table_name like @table_name;
當然你可以拆分為兩步來實現。
第二步:對比當月與下月表名數據和創建表。
當月有的下月沒有,這時候就應該創建一個下月的表。
如何創建?最簡單也是最保險的就是copy當月的表。
為啥不用建表語句?平時升庫的時候,你去修改過建表語句?修改過建表事件?如果你修改過那最好!
Copy當月表我們只需要表結構不需要表數據所以一條sql語句就搞定了:
CREATE TABLE 下月表 LIKE 當月表;
這樣一來,兩條語句就搞定。
好我們來聊聊代碼:
三層架構 business Dal UI 。UI 和 DAL 沒啥說的。
直接上核心代碼:
/// <summary>
/// 掃描並創建表
/// </summary>
private void AnalyseAndCreatTables()
{
int scantime = 5;
while (true)
{
try
{
ShowBusiness.ShowMsg("獲取數據庫信息");
// 獲取數據庫信息
BGetDataBseName getdatabaseinfo = new BGetDataBseName();
getdatabaseinfo.Execute();
List<string> databases = getdatabaseinfo.DataBases;
if (databases != null)
{
foreach (var itemDatabase in databases)
{
this.HandSpiltByMonth(itemDatabase);
}
}
}
catch (Exception ex)
{
}
finally
{
Thread.Sleep(scantime * 1000 * 60);
}
}
}
/// <summary>
/// 處理按月分表
/// </summary>
/// <param name="databaseName">數據庫名</param>
private void HandSpiltByMonth(string databaseName)
{
ShowBusiness.ShowMsg(string.Format("處理【{0}】數據庫 按月分表", databaseName));
#region 按月分表
string nowtablePostfix = string.Format("{0}{1}", DateTime.Now.Year.ToString().Substring(2, 2), DateTime.Now.Month.ToString().PadLeft(2, '0'));
string nexttablePostfix = string.Format("{0}{1}", DateTime.Now.AddMonths(1).Year.ToString().Substring(2, 2), DateTime.Now.AddMonths(1).Month.ToString().PadLeft(2, '0'));
ShowBusiness.ShowMsg(string.Format("處理【{0}】數據庫中按月分表的當前月的表", databaseName));
// 獲取該數據庫中按月分表的當前月的表
DGetTablesFromDatabase getNowDatatables = new DGetTablesFromDatabase(databaseName, nowtablePostfix);
getNowDatatables.Execute();
List<string> nowtablse = getNowDatatables.TablesList;
ShowBusiness.ShowMsg(string.Format("處理【{0}】數據庫當月的表:{1}", databaseName, string.Join(",", nowtablse.ToArray())));
// 獲取該數據庫中按月分表的下月的表
DGetTablesFromDatabase getNextDatatables = new DGetTablesFromDatabase(databaseName, nexttablePostfix);
getNextDatatables.Execute();
List<string> nextDatatables = getNextDatatables.TablesList;
ShowBusiness.ShowMsg(string.Format("處理【{0}】數據庫下月的表:{1}", databaseName, string.Join(",", nextDatatables.ToArray())));
// 對比當前月表和下月表,如果下月表中沒有,則新建
if (nowtablse != null)
{
foreach (var nowitem in nowtablse)
{
ShowBusiness.ShowMsg(string.Format("處理【{0}】數據庫對比當前月表和下月表", databaseName));
///基礎數據庫名
string nowbeforstr = nowitem.Substring(0, nowitem.IndexOf(nowtablePostfix));
// 是否已經創建
bool isCreated = false;
if (nextDatatables != null && nextDatatables.Count > 0)
{
foreach (var nextitem in nextDatatables)
{
// 基礎數據庫名
string nextbeforstr = nowitem.Substring(0, nextitem.IndexOf(nexttablePostfix));
if (nowbeforstr == nextbeforstr)
{
isCreated = true;
ShowBusiness.ShowMsg(string.Format("處理【{0}】數據庫 表{1}已經創建", databaseName, nextitem));
}
}
}
if (!isCreated)
{
string creatTableName = nowitem.Replace(nowtablePostfix, nexttablePostfix);
ShowBusiness.ShowMsg(string.Format("處理【{0}】數據庫 創建表{1}", databaseName, creatTableName));
DCreatTableFromDatabase creatTableFromDatabase = new DCreatTableFromDatabase(databaseName, nowitem, creatTableName);
creatTableFromDatabase.Execute();
int results = creatTableFromDatabase.Result;
}
}
}
#endregion
}
第一次發博客,先發上去看看。