每当跨月的时候也是系统出问题最多的时候,没有表和字段缺失是两个最常见的错误。

为了解决这个问题,研究了一下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 没啥说的。

直接上核心代码:

///
///扫描并创建表
///
privatevoidAnalyseAndCreatTables()
{
intscantime = 5;
while(true)
{
try
{
ShowBusiness.ShowMsg("获取数据库信息");
// 获取数据库信息
BGetDataBseNamegetdatabaseinfo = newBGetDataBseName();
getdatabaseinfo.Execute();
List databases = getdatabaseinfo.DataBases;
if(databases != null)
{
foreach(varitemDatabase indatabases)
{
this.HandSpiltByMonth(itemDatabase);
}
}
}
catch(Exceptionex)
{
}
finally
{
Thread.Sleep(scantime * 1000 * 60);
}
}
}
///
///处理按月分表
///
///数据库名
privatevoidHandSpiltByMonth(stringdatabaseName)
{
ShowBusiness.ShowMsg(string.Format("处理【{0}】数据库 按月分表", databaseName));
#region按月分表
stringnowtablePostfix = string.Format("{0}{1}", DateTime.Now.Year.ToString().Substring(2, 2), DateTime.Now.Month.ToString().PadLeft(2, '0'));
stringnexttablePostfix = 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));
// 获取该数据库中按月分表的当前月的表
DGetTablesFromDatabasegetNowDatatables = newDGetTablesFromDatabase(databaseName, nowtablePostfix);
getNowDatatables.Execute();
List nowtablse = getNowDatatables.TablesList;
ShowBusiness.ShowMsg(string.Format("处理【{0}】数据库当月的表:{1}", databaseName, string.Join(",", nowtablse.ToArray())));
// 获取该数据库中按月分表的下月的表
DGetTablesFromDatabasegetNextDatatables = newDGetTablesFromDatabase(databaseName, nexttablePostfix);
getNextDatatables.Execute();
List nextDatatables = getNextDatatables.TablesList;
ShowBusiness.ShowMsg(string.Format("处理【{0}】数据库下月的表:{1}", databaseName, string.Join(",", nextDatatables.ToArray())));
// 对比当前月表和下月表,如果下月表中没有,则新建
if(nowtablse != null)
{
foreach(varnowitem innowtablse)
{
ShowBusiness.ShowMsg(string.Format("处理【{0}】数据库对比当前月表和下月表", databaseName));
///基础数据库名
stringnowbeforstr = nowitem.Substring(0, nowitem.IndexOf(nowtablePostfix));
// 是否已经创建
boolisCreated = false;
if(nextDatatables != null&& nextDatatables.Count > 0)
{
foreach(varnextitem innextDatatables)
{
// 基础数据库名
stringnextbeforstr = nowitem.Substring(0, nextitem.IndexOf(nexttablePostfix));
if(nowbeforstr == nextbeforstr)
{
isCreated = true;
ShowBusiness.ShowMsg(string.Format("处理【{0}】数据库 表{1}已经创建", databaseName, nextitem));
}
}
}
if(!isCreated)
{
stringcreatTableName = nowitem.Replace(nowtablePostfix, nexttablePostfix);
ShowBusiness.ShowMsg(string.Format("处理【{0}】数据库 创建表{1}", databaseName, creatTableName));
DCreatTableFromDatabasecreatTableFromDatabase = newDCreatTableFromDatabase(databaseName, nowitem, creatTableName);
creatTableFromDatabase.Execute();
intresults = creatTableFromDatabase.Result;
}
}
}
#endregion
}

第一次发博客,先发上去看看。