C基础 mariadb处理的简单实例
引言
MariaDB 是一款灰常不错开源数据库. 这里直接用它来解决业务问题.
业务需求:
现在数据库中表示按照天分表的. 突然我们需要按照月来处理数据.
例如输入一个玩家id, 查找这个玩家这个月内看了一件事几次. 我们先搭建一个环境.
操作系统:
Linux version 4.4.0-22-generic (buildd@lgw01-41) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2) ) #40-Ubuntu SMP Thu May 12 22:03:46 UTC 2016
首先安装 MariaDB数据库
sudo apt-get install mariadb-server sudo apt-get install mariadb-client sudo apt-get install libmariadb2 sudo apt-get install libmariadb-client-lgpl-dev sudo apt-get install libreoffice-mysql-connector
后面是C访问 MariaDB驱动. 这里扯一点, 目前关于MariaDB不懂问题, 搜不见直接当成mysql开始搜.
MariaDB安装成功后默认是开启的, 看下面图描述
后面搭建测试环境 首先 看 oss_musicelves.sql
-- MySQL dump 10.10 -- -- Host: localhost Database: oss_log -- ------------------------------------------------------ -- Server version 5.5.24-tmysql-1.4 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `oss_musicelves` -- DROP TABLE IF EXISTS `oss_musicelves`; CREATE TABLE `oss_musicelves` ( `record_id` bigint(20) NOT NULL AUTO_INCREMENT, `account_id` bigint(20) NOT NULL, `server_id` int(11) NOT NULL, `char_id` bigint(20) NOT NULL, `char_sex` int(11) NOT NULL, `type_id` int(11) NOT NULL, `timeStamp` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `ptype` int(11) NOT NULL, `specifytype` int(11) NOT NULL, `childtype` int(11) NOT NULL, PRIMARY KEY (`record_id`), KEY `idx_specifytype` (`specifytype`) ) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=latin1; -- -- Dumping data for table `oss_musicelves` -- /*!40000 ALTER TABLE `oss_musicelves` DISABLE KEYS */; LOCK TABLES `oss_musicelves` WRITE; INSERT INTO `oss_musicelves` VALUES (1,411948833,84869352,27899597414400801,0,1812,'2016-05-31 14:27:41',0,1,1),(2,1344702709,90964200,30422720614402293,0,1812,'2016-05-31 14:58:26',0,1,1),(3,706409913,90964200,30422720614401465,1,1812,'2016-05-31 14:58:27',0,1,2),(4,706409913,392964857,30422720614401465,1,1812,'2016-05-31 14:58:59',0,2,4),(5,1344702709,392964857,30422720614402293,0,1812,'2016-05-31 14:58:59',0,2,4),(6,706409913,90964200,30422720614401465,1,1812,'2016-05-31 15:04:52',0,1,2),(7,706409913,392964857,30422720614401465,1,1812,'2016-05-31 15:05:54',0,2,4),(8,1344702709,392964857,30422720614402293,0,1812,'2016-05-31 15:05:54',0,2,4),(9,1344702709,90964200,30422720614402293,0,1812,'2016-05-31 15:10:29',0,1,1),(10,706409913,90964200,30422720614401465,1,1812,'2016-05-31 15:10:32',0,1,2),(11,1344702709,392964857,30422720614402293,0,1812,'2016-05-31 15:10:54',0,2,4),(12,3145910262,90964200,29520779366416374,1,1812,'2016-05-31 15:30:00',0,1,1),(13,1372825842,90964200,30173879500803314,1,1812,'2016-05-31 15:30:01',0,1,2),(14,3145910262,392964857,29520779366416374,1,1812,'2016-05-31 15:30:04',0,2,4),(15,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 15:30:04',0,2,4),(16,3145910262,392964857,29520779366416374,1,1812,'2016-05-31 15:34:24',0,2,4),(17,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 15:34:24',0,2,4),(18,706409913,90964200,30422720614401465,1,1812,'2016-05-31 15:40:14',0,1,1),(19,1344702709,90964200,30422720614402293,0,1812,'2016-05-31 15:40:16',0,1,2),(20,3145910262,392964857,29520779366416374,1,1812,'2016-05-31 15:42:19',0,2,4),(21,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 15:42:19',0,2,4),(22,1027763684,90964200,30175730790400484,0,1812,'2016-05-31 16:56:33',1,1,1),(23,1372825842,90964200,30173879500803314,1,1812,'2016-05-31 16:56:50',0,1,2),(24,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 16:57:37',0,2,3),(25,1027763684,392964857,30175730790400484,0,1812,'2016-05-31 16:57:37',1,2,3),(26,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 17:04:33',0,2,3),(27,1027763684,392964857,30175730790400484,0,1812,'2016-05-31 17:04:33',1,2,3),(28,1027763684,90964200,30175730790400484,0,1812,'2016-05-31 17:14:15',1,1,2),(29,1372825842,392964857,30173879500803314,1,1812,'2016-05-31 17:14:50',0,2,3),(30,1027763684,392964857,30175730790400484,0,1812,'2016-05-31 17:14:50',1,2,3),(31,751699770,90964200,30175199027201850,1,1812,'2016-05-31 18:14:59',1,1,1); UNLOCK TABLES; /*!40000 ALTER TABLE `oss_musicelves` ENABLE KEYS */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
这个 oss_musicelves.sql 文件主要功能是创建 oss_musicelves数据库, 并填充数据.
还有一个 搭建环境 的 脚本 mariadb_test.sql 和上一个sql文件放在同一个目录下
# 创建一个测试数据库 create database oss_log; # 进入oss_log 数据库 use oss_log; # 创建 oss_musicelves 数据库, 并导入数据 source oss_musicelves.sql; # 批量创建表和数据 create table 2016_6_1_oss_musicelves select * from oss_musicelves; create table 2016_6_2_oss_musicelves select * from oss_musicelves; create table 2016_6_3_oss_musicelves select * from oss_musicelves; create table 2016_6_4_oss_musicelves select * from oss_musicelves; create table 2016_6_5_oss_musicelves select * from oss_musicelves; create table 2016_6_9_oss_musicelves select * from oss_musicelves; create table 2016_6_10_oss_musicelves select * from oss_musicelves; create table 2016_6_12_oss_musicelves select * from oss_musicelves; # 查询表是否创建成功 show tables; # 这里处理 拿到的数据 select distinct table_name from information_schema.columns where table_name like '2016_6_%_oss_musicelves';
直接放在 MariaDB控制台中直接刷进去. 搭建的具体环境如下
到这里环境基本搭建好了. MariaDB入门等等, 完全可以当做mysql 学习温故一遍.
前言
上面问题就是 原本 是 select * from oss_musicelves; 就可以解决的问题.
这里 需要 输入年和月 外加一些特殊条件 . select * from %_%_%_oss_musicelves; 解决. 单纯用sql脚本也可以解决.非常复杂.用的不熟.
这里首先通过 shell 脚本处理
touch getmouths.sh chmod +x getmouths.sh vi getmouths.sh
具体的脚本 内容 如下
#!/bin/sh #得到输入的玩家ptid if [ $# -lt 1 ] then echo "uage: $0 [ptid]" exit -1 fi ptid=$1 mouth=$(date +%m | sed s'/^0//') #第一个参数是月份 if [ $# -ge 2 ] then mouth=$2 fi #第二个参数是年 year=$(date +%Y) if [ $# -ge 3 ] then year=$3 fi #得到查询的随机表名 tbname="\"${year}_${mouth}_%_oss_musicelves\"" #这里得到mysql 中所有合法表名 rm -rf __tmp touch __tmp #开始查询数据库了, 需要以root权限启动这个脚本 mysql -e "select distinct table_name from information_schema.columns where table_name like $tbname" | awk 'NR>1' | while read name do mysql -e "select count(*) from oss_log.$name where specifytype = 1 and char_id = $ptid" | awk 'NR>1' | while read cut do echo "$name : $cut" echo $cut >> __tmp break done done #统计表里面的数据 sum=$(cat __tmp | awk '{s+=$1} END {print s}') rm -rf __tmp # 最后输出统计结果 echo "$year-$mouth sum: $sum"
使用脚本 截图
通过shell可以完成 我们的需求. Linux上shell真好用. window的bat不好用.
正文
第一部分 : 让C调用MariaDB跑通
先看 测试Demo mariadb_demo.c
#include <stdio.h> #include <stdlib.h> #include <mysql.h> /* * 第一个 mariadb程序 */ int main(int argc, char *argv[]) { // 创建数据连接对象 MYSQL *con = mysql_init(NULL); if (con == NULL) { fprintf(stderr, "%s\n", mysql_error(con)); exit(EXIT_FAILURE); } if (!mysql_real_connect(con, "localhost", "root", "", NULL, 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(EXIT_FAILURE); } if (mysql_query(con, "show databases;")) { fprintf(stderr, "%s\n", mysql_error(con)); mysql_close(con); exit(EXIT_FAILURE); } puts("mariadb is connect and run succesed!"); mysql_close(con); return 0; }
具体的编译 命令
su root gcc -Wall -ggdb2 -I/usr/include/mariadb -o mariadb_demo.out mariadb_demo.c -lmysqlclient ./mariadb_demo.out
运行结果 如下
到这里基本C 调用 MariaDB 基本流程跑通了. 但是很不爽. 只能通过root用户使用.
那我们改变这里不爽. 进入第二部分. 扩展资料 c in mariadb http://stackoverflow.com/questions/17265471/using-mariadb-in-c
第二部分 : 通过普通用户完成业务需求.
先创建普通用户 csz, 密码是 1413222, 并并且给其 select 读权限
su root mysql drop user csz; create user 'csz'@'%' identified by '13142222'; grant select on *.* to 'csz'@'%'; # 立即刷新 flush privileges;
后面登录试试
mysql -ucsz -p1314222 -h127.0.0.1
主要是mariadb默认关闭远程访问. 后面我们开启安全访问模式试试
su root/etc/init.d/mysql stopmysqld_safe --skip-grant-tables
后面再开启一个会话 . 重新输入 mysql -ucsz -p1314222 -h127.0.0.1 , 解决可以了
#目标拼接 串内容 select sum(c) from ( select count(*) as c from 2016_6_1_oss_musicelves where specifytype=1 and char_id = 30422720614402293 union all select count(*) from 2016_6_2_oss_musicelves where specifytype=1 and char_id = 30422720614402293 union all select count(*) from 2016_6_3_oss_musicelves where specifytype=1 and char_id = 30422720614402293 union all select count(*) from 2016_6_4_oss_musicelves where specifytype=1 and char_id = 30422720614402293 union all select count(*) from 2016_6_5_oss_musicelves where specifytype=1 and char_id = 30422720614402293 union all select count(*) from 2016_6_9_oss_musicelves where specifytype=1 and char_id = 30422720614402293 union all select count(*) from 2016_6_10_oss_musicelves where specifytype=1 and char_id = 30422720614402293 union all select count(*) from 2016_6_12_oss_musicelves where specifytype=1 and char_id = 30422720614402293 ) as t;
具体看 getmouths.c 文件 内容
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <mysql.h> #define _INT_BUF (4098) // 得到查询数据表内容 #define _STR_SQLTABLES \ "select distinct table_name from information_schema.columns where table_name like '%d_%d_%%_oss_musicelves'" #define _STR_SQLSELECT \ "select count(*) as c from %s where specifytype=1 and char_id = %lld" // 基础的mariadb 错误关闭函数 static inline void _err_mariadb(MYSQL *con) { fprintf(stderr, "_err_mariadb error: %s\n", mysql_error(con)); mysql_close(con); exit(EXIT_FAILURE); } /* * 处理 oss_musicelves 一个月的所有表. */ int main(int argc, char* argv[]) { long long ptid; time_t rt = time(NULL); struct tm *pt = localtime(&rt); int year = pt->tm_year + 1900; int mouth = pt->tm_mon + 1; // 先简单检测输入 if(argc <= 1) { fprintf(stderr, "%s [ptid] [mouth] [year]\n", argv[0]); exit(EXIT_FAILURE); } // 先得到 ptid 数据 ptid = atoll(argv[1]); // 得到当前月份 if(argc >= 3) mouth = atoi(argv[2]); // 得到当前年份 if(argc >= 4) year = atoi(argv[3]); // 简单检测结果是否合法 if(ptid < 0 || mouth <=0 || mouth>12 || year<1900) { fprintf(stderr, "%s %lld %d %d is error!\n", argv[0], ptid, mouth, year); exit(EXIT_FAILURE); } // 输出结果 printf("%s %lld %d %d start run!\n", argv[0], ptid, mouth, year); // 开始用mysql 访问我们需要访问的数据结果了 MYSQL *con = mysql_init(NULL); if(con == NULL) { fprintf(stderr, "mysql_init error: %s\n", mysql_error(con)); exit(EXIT_FAILURE); } if(!mysql_real_connect(con, "127.0.0.1", "csz", "1314222", "oss_log", 0, NULL, 0)) _err_mariadb(con); char sqls[_INT_BUF]; int sqlen = 0; sprintf(sqls, _STR_SQLTABLES, year, mouth); if(mysql_query(con, sqls)) _err_mariadb(con); // 开始得到结果 MYSQL_RES *ret = mysql_store_result(con); if(NULL == ret) _err_mariadb(con); MYSQL_ROW row; int i = 0, nr = 0; while(!!(row = mysql_fetch_row(ret))) { if(i == 0) { sqlen = sprintf(sqls, "select sum(c) from (\n" _STR_SQLSELECT, row[0], ptid); i = 1; continue; } // 后面正常拼接 nr = sprintf(sqls + sqlen, "\nunion all\n" _STR_SQLSELECT, row[0], ptid); if((sqlen += nr) >= _INT_BUF) { fprintf(stderr, "sprintf while %d too length.\n", sqlen); goto __return_free; } } if(i == 0) { printf("sum %lld %d/%d: 0\n", ptid, year, mouth); goto __return_free; } // 这里处理有的数据 nr = sprintf(sqls + sqlen, "\n) as t;"); if((sqlen += nr) >= _INT_BUF) { fprintf(stderr, "sprintf end %d too length.\n", sqlen); goto __return_free; } // 内存用完了就直接释放 mysql_free_result(ret); ret = NULL; printf("sql : \n\t%s\n", sqls); // 开始输出统计结果 if(mysql_query(con, sqls)) _err_mariadb(con); if((ret = mysql_store_result(con))==NULL) _err_mariadb(con); //得到结果直接返回 if(!!(row=mysql_fetch_row(ret))) printf("sum %lld %d/%d: %s\n", ptid, year, mouth, row[0]); else puts("select is empty!"); __return_free: // 释放用过的内存 mysql_free_result(ret); // 关闭打开的 数据库访问对象 mysql_close(con); return 0; }
编译命令
gcc -Wall -ggdb2 -I/usr/include/mariadb -o getmouths.out getmouths.c -lmysqlclient
最终运行结果是
如果想详细了解关于mariadb c驱动的api使用, 可以参照老外写的很好理解.
mysqlc demo http://zetcode.com/db/mysqlc/
到这里就结束了, 关于C 访问数据库能力也基本打通了.
后记
错误是难免, 欢迎学习进步~~~ 未来什么都不确定, 可以确定是没有未来, 只有现在还在装逼 .
以上这篇C基础 mariadb处理的简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要介绍了Windows批量搜索并复制/剪切文件的批处理程序实例,需要的朋友可以参考下...2020-06-30
BAT批处理判断服务是否正常运行的方法(批处理命令综合应用)
批处理就是对某对象进行批量的处理,通常被认为是一种简化的脚本语言,它应用于DOS和Windows系统中。这篇文章主要介绍了BAT批处理判断服务是否正常运行(批处理命令综合应用),需要的朋友可以参考下...2020-06-30- file_get_contents的超时处理话说,从PHP5开始,file_get_content已经支持context了(手册上写着:5.0.0 Added the context support. ),也就是说,从5.0开始,file_get_contents其实也可以POST数据。今天说的这篇是讲超时的,确实在...2013-10-04
- 这篇文章主要介绍了C#多线程中的异常处理操作,涉及C#多线程及异常的捕获、处理等相关操作技巧,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了postgresql 中的时间处理小技巧(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
- 这篇文章主要介绍了Python同时处理多个异常的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-29
C#异常处理中try和catch语句及finally语句的用法示例
这篇文章主要介绍了C#异常处理中try和catch语句及finally语句的用法示例,finally语句的使用涉及到了C#的垃圾回收特性,需要的朋友可以参考下...2020-06-25- 这篇文章主要介绍了python如何用moviepy对视频进行简单的处理,帮助大家更好的利用python处理视频,感兴趣的朋友可以了解下...2021-03-11
- 这篇文章介绍了C#异常处理,有需要的朋友可以参考一下...2020-06-25
- 这篇文章主要给大家介绍了关于sql server日志处理不当造成的隐患的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用sql server具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-07-11
- JS与HTML之间的交互通过事件实现。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用监听器(或处理程序)来预定事件,以便事件发生时执行相应的代码。本文将介绍JS事件相关的基础知识。...2017-04-03
- Spring MVC是Spring系列框架中使用频率最高的部分。不管是Spring Boot还是传统的Spring项目,只要是Web项目都会使用到Spring MVC部分。因此程序员一定要熟练掌握MVC部分。本篇博客简要分析Spring MVC处理一个请求的流程。...2021-02-06
- 这篇文章主要介绍了go语言中的Carbon库时间处理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-05
- C++ 提供了异常机制,让我们能够捕获运行时错误,本文就详细的介绍了C++异常处理入门,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-09
C#事务处理(Execute Transaction)实例解析
这篇文章主要介绍了C#事务处理(Execute Transaction)实例解析,对于理解和学习事务处理有一定的帮助,需要的朋友可以参考下...2020-06-25- 本文章来给各同学总结了一些常用的图像处理函数,包括有缩放、剪裁、缩放、翻转、旋转、透明、锐化功能,大家可参考参考。 注意事项:如果要使用php gd处理我们需要...2016-11-25
Python编程OpenCV和Numpy图像处理库实现图片去水印
这篇文章主要介绍了Python编程中如何实现图片去水印本文采用了OpenCV和Numpy的图像处理的方法来实现,文中附含详细示例代码,有需要的朋友可以借鉴参考下...2021-09-26javascript表单处理具体实现代码(表单、链接、按钮)
这篇文章主要介绍了javascript表单处理具体实现代码,包括各种表单、链接、按钮控件介绍,感兴趣的朋友可以参考一下...2016-05-09- C++中处理异常的过程是这样的:在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信息,把它传递给上一级的函数来解决,上一级解决不了,再传给其上一级,由其上一级处理...2020-04-25
- 本文介绍一下在C#中执行批处理文件(*.bat)的方法。...2020-06-25