c 控制mysql数据导出_C 语言编写 MySQL 数据库文档导出工具

本文档介绍了作者在面临缺少数据库文档的情况下,如何利用C语言自制一个工具来导出数据库的表信息和字段信息。作者首先通过查询INFORMATION_SCHEMA表格获取数据库表和字段详情,然后使用C语言编写程序,实现了连接MySQL数据库、解析命令行参数、获取表信息和字段信息的功能。程序还包含了帮助文档和参数解析模块,确保用户能轻松使用。最终,作者分享了源码供读者下载和使用。
摘要由CSDN通过智能技术生成

前几天接手到一个其它项目的数据库,需要将数据库的数据转到我们库中,这个数据库还挺大的,几百个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即可编译项目了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值