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处理的简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 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 M

  • 从vue基础开始创建一个简单的增删改查的实例代码(推荐)

    1.安装vue-cli    cnpm install vue-cli -g  --执行全局安装 2.创建一个webpack的基础项目:命令:vue init webpack myproject; 以下是项目的目录结构及说明 build是webpack配置 build.js       // 生产环境构建代码 check-versions.js // 检查node&npm等版本 utils.js          // 构建配置公用工具 vue-loader.conf.js // vue加载器

  • 用Java程序判断是否是闰年的简单实例

    我们知道,(1)如果是整百的年份,能被400整除的,是闰年:(2)如果不是整百的年份,能被4整除的,也是闰年.每400年,有97个闰年.鉴于此,程序可以作以下设计: 第一步,判断年份是否被400整除,能的话,就是闰年.比如1600.2000.2400年是闰年. 第二步,在第一步不成立的基础上,判断年份能否被100整除,如果是,则不是闰年.比如1900.2100.2200年不是闰年. 第三步,在第二步不成立的基础上,判断年份能否被4整除,如果是,则是闰年.比如1996.2004.2008年是闰年.

  • JAVA 注解详解及简单实例

    JAVA 注解详解及简单实例 何为注解 注解(Annotation)又称为元数据,在JDK1.5后引入,它的作用是: 生成文档  这是注解的原始用途,可以通过注解生成JavaDoc文档 跟踪代码的依赖性  可以通过注解替代配置文件,简化项目的配置.现有的许多框架都采用这个功能减少自己的配置. 编译检查  在编译时进行格式检查,例如@Override 基础注解 Java目前内置了三种标准注解,以及四种元注解.四种元注解负责创建其他的注解. 三种标准注解 @Override,表示当前的方法覆盖超类中

  • Android 中自定义ContentProvider与ContentObserver的使用简单实例

    Android 中自定义ContentProvider与ContentObserver的使用简单实例 示例说明: 该示例中一共包含两个工程.其中一个工程完成了自定义ContentProvider,另外一个工程用于测试该自定义ContentProvider且在该工程中使用了ContentObserver监听自定义ContentProvider的数据变化 以下代码为工程TestContentProvider ContentProviderTest如下: package cn.testcontentp

  • 使用JavaScript实现弹出层效果的简单实例

    声明 阅读本文需要有一定的HTML.CSS和JavaScript基础 设计 实现弹出层效果的思路非常简单:将待显示的内容先隐藏,在触发某种条件后(如点击按钮),将原本隐藏的内容显示出来. 实现 <!DOCTYPE html> <html> <head> <title>Window对象</title> <meta charset="utf-8"> </head> <body> <a hr

  • 使用jquery获取url及url参数的简单实例

    使用jquery获取url以及使用jquery获取url参数是我们经常要用到的操作 1.jquery获取url很简单,代码如下: window.location.href; 其实只是用到了javascript的基础的window对象,并没有用jquery的知识. 2.jquery获取url参数比较复杂,要用到正则表达式,所以学好javascript正则式多么重要的事情 首先看看单纯的通过javascript是如何来获取url中的某个参数: //获取url中的参数 function getUrlP

  • Python实现冒泡,插入,选择排序简单实例

    本文所述的Python实现冒泡,插入,选择排序简单实例比较适合Python初学者从基础开始学习数据结构和算法,示例简单易懂,具体代码如下: # -*- coding: cp936 -*- #python插入排序 def insertSort(a): for i in range(len(a)-1): #print a,i for j in range(i+1,len(a)): if a[i]>a[j]: temp = a[i] a[i] = a[j] a[j] = temp return a #

  • java 使用HttpURLConnection发送数据简单实例

    java 使用HttpURLConnection发送数据简单实例 每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络.请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响.如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字.JAVA使用HttpURLCon

  • jax-ws handler 的详解及简单实例

     jax-ws handler 的详解及简单实例 aop技术一般用于某个对象的函数调用的日志,认证等. webservice是远程的函数调用,也需要类似的aop方法,举例jax-ws的webservice,handler就相当于aop. 举一例jax-ws handler例子 先写个webservice import javax.jws.HandlerChain; import javax.jws.WebMethod; import javax.jws.WebService; @WebServi

随机推荐