您现在的位置是:主页 > news > 简单网站设计网站/西安优化外包
简单网站设计网站/西安优化外包
admin2025/5/16 2:13:00【news】
简介简单网站设计网站,西安优化外包,网站备案 代办,wordpress+教材主题前几天接手到一个其它项目的数据库,需要将数据库的数据转到我们库中,这个数据库还挺大的,几百个G的数据,表也有200多张。刚拿到数据库的时候,分析起来那叫一个辛苦,表名、字段名不规范,还没有文…
前几天接手到一个其它项目的数据库,需要将数据库的数据转到我们库中,这个数据库还挺大的,几百个G的数据,表也有200多张。刚拿到数据库的时候,分析起来那叫一个辛苦,表名、字段名不规范,还没有文档,完全不知道从哪下手。突然想起阿里云有提供数据库文档导出工具,赶紧打开看看,居然还是收费的,体验只能获取到10张表的数据,简直是杯水车薪。老大那边也不打算因为这个文档去购买这个服务。
既然人家阿里能写出这种工具,我身为一个码农没理由写不出来,那就自己折腾吧。在选择语言的时候,考虑到方便和小巧,就选定了用C语言来开发。
关键概念
刚开始折腾,完全没有方向,上谷歌去看看。在网上搜索了后,才了解到mysql中INFORMATION_SCHEMA.TABLES表存储了数据库的表信息,有了这个我们就可以获取到库的所有数据表了。有了数据表还不够,我们还要获取表中每个字段的信息,这个时候我们可以通过INFORMATION_SCHEMA.COLUMNS表来获取指定表的所有字段信息。如下:
# 获取数据库中所有的表
select table_name,TABLE_COMMENT from INFORMATION_SCHEMA.TABLES where table_schema = `db`
# 获取表中所有的字段信息
select * from information_schema.columns where table_schema = 'db' and table_name = 'tablename'
有了上面的两条SQL,基本上大家都知道怎么弄了吧。其实我最开始是用php实现的(因为赶时间,php写起来要快的多)。晚上下班后才用c语言来实现它。
准备
在C语言中访问mysql,需要引入mysql.h头文件,如果你的电脑没有这个头文件的话,你就需要安装libmysqlclient-dev包:
sudo apt-get instal libmysqlclient-dev
当然也可以自己下载源码来编译,我这里图个方便,直接用的apt安装。
安装后,你就可以在你的C代码中引入这个头文件了,在我的电脑上,mysql.h文件存在于/usr/include/mysql/文件夹中,所以我引入的路径如下:
#include
具体的路径取决于你的电脑。
C语言的实现
一个程序,必须要有个帮助文档,让刚接触这个程序的用户知道如何来操作程序,这里我们封装了一个usage()函数来告知用户的操作方法:
void usage (void)
{
printf ("Usage: mysql_doc -[h] [-H host] [-P port] [-U username] [-W passwd] [-N dbname]\n");
printf ("-h: help!\n");
printf ("-H host: mysql host \n");
printf ("-P port: mysql port same as 3306\n");
printf ("-U username: mysql user name\n");
printf ("-W passwd: mysql password\n");
printf ("-N dbname: database name\n");
}
上面的代码中,告诉了用户程序需要的参数,并且每个参数代表啥意思:
-h: 帮助文档
-H: 数据库地址
-P: 数据库的端口
-U: 数据库的用户名
-W: 数据库的密码,这里为了不和port重复,就用了W字符作为参数名
-N: 数据库的名字
有了这个一目了然的帮助文档,可以肯定即使是第一次使用这个程序的用户,也能清晰的知道如何使用程序了。
有了usage()函数后,我们需要编写参数解析模块了,这样才能准确的知道用户输入的是什么,是端口名还是用户需要获取帮助文档。在C语言中,有个很方便的命令行参数方法:getopt(), 这个方法可以很方便的设置你需要的参数,以及参数属性(是否有值、值是否可选等等)。
while ((opchar = getopt(argc, argv, "hH:P:U:W:N:")) != EOF) {
...
}
上面的代码中,getopt()函数有三个参数,前面两个是main函数的参数,后面的一个参数中,设置了参数的格式:hH:P:U:W:N:。这些字母表示参数的名字,不带冒号表示这个参数没有值,字母后面跟了一个冒号表示参数必须携带值。我们将这个语句放在while循环中,是为了能够获取到程序执行时,输入的所有参数。
我们只需要在while循环体中,来实现每个参数需要执行的操作即可:
switch (opchar) {
case 'H':
strcpy (host, optarg);
break;
case 'P':
port = optarg;
break;
case 'U':
strcpy (user, optarg);
break;
case 'W':
strcpy (pwd, optarg);
break;
case 'N':
strcpy (dbname, optarg);
break;
default:
usage();
return 0;
}
这里我们用了一个switch来将不通信息保存到指定的变量中。
现在我们已经拿到了数据库所有的配置信息,这个时候是我们连接MySQL的时候了:
MYSQL mysql;
MYSQL_RES *table_list;
MYSQL_ROW table_row;
mysql_init (&mysql);
mysql_options (&mysql, MYSQL_SET_CHARSET_NAME, "utf8");
mysql_real_connect (&mysql, host, user, pwd, dbname, port, NULL, 0);
上面是数据库的连接代码。
连接上数据库后,我们来获取数据库所有的表:
char get_table_sql[300] = "select table_name,TABLE_COMMENT from INFORMATION_SCHEMA.TABLES where table_schema = \'";
strcat (get_table_sql, dbname);
strcat (get_table_sql, "\'");
mysql_query(&mysql, get_table_sql);
table_list = mysql_store_result(&mysql);
while (table_row = mysql_fetch_row (table_list)) {
...
}
这里我们已经获取到了数据库中所有的表,用table_row[0]可以获取到表的名字,table_row[1]可以获取到表的备注信息(因为我们只查询了两个字段)。
拿到所有的表后,我们可以先将表的名字输出到文件中,然后再用表名字去获取字段的信息:
// 将这里的代码放在上一段代码循环体中
char get_column_sql[300] = "";
strcat (get_column_sql, "show full columns from ");
strcat (get_column_sql, table_row[0]);
MYSQL_RES *table_column;
MYSQL_ROW column_row;
printf ("%s\n", get_column_sql);
mysql_query (&mysql, get_column_sql);
table_column = mysql_store_result (&mysql);
fprintf (fp, "字段名 | 类型 | 编码 | 是否为空 | key | 默认值 | Extra | 描述\n");
fprintf (fp, "------ | ---- | ---- | -------- | --- | ------ | ----- | ----\n");
while (column_row = mysql_fetch_row (table_column)) {
fprintf (fp, "%s | %s | %s | %s | %s | %s | %s | %s\n", column_row[0], column_row[1]
, column_row[2], column_row[3], column_row[4]
, column_row[5], column_row[6], column_row[8]);
}
mysql_free_result (table_column);
这里我们并没有用select * from information_schema.columns where table_schema = 'db' and table_name = 'tablename'语句来获取字段详细信息,而是用的show full columns from table_name语句,其实两者可以达到一样的目标,只是后者更短点,我太懒,不想打那么多字。
还有在最后我们要释放掉table_column,以免造成内存泄漏。
到了这里,这个程序就已经完成了。
源码下载
如果你需要项目的完整可运行代码,可以在这里下载:源码下载。下载好后,直接进入代码文件夹中执行make即可编译项目了。