mysql应用_mysql应用

1.  简述

2.  安装及应用

在解压目录下编辑my.ini配置文件:

[client]

# 设置mysql客户端默认字符集

default-character-set=utf8

[mysqld]

# 设置3306端口

port= 3306# 设置mysql的安装目录

basedir=D:\\mysql-8.0.17-winx64

# 设置 mysql数据库的数据的存放目录,MySQL8+不需要以下配置,系统自己生成即可,否则有可能报错

# datadir=D:\\web\\sqldata

# 允许最大连接数

max_connections=20# 服务端使用的字符集默认为8比特编码的latin1字符集

character-set-server=utf8

# 创建新表时将使用的默认存储引擎

default-storage-engine=INNODB

初始化数据库

初始化数据库:

mysqld--initialize --console

执行完成后,会输出 root 用户的初始默认密码,如:

...2018-04-20T02:35:05.464644Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: APWCY5ws&hjQ

...

APWCY5ws&hjQ 就是初始密码,后续登录需要用到,你也可以在登陆后修改密码。

输入以下安装命令:

mysqldinstall启动输入以下命令即可:

net start mysql

启动数据库

mysqld --console

关闭数据库

mysqladmin -u root shutdown

登录数据库

mysql -h 主机名 -u 用户名 -p

修改密码

mysqld --defaults-file="../my.ini" --skip-grant-tables --shared-memory --console

update mysql.user set authentication_string="" where user="root";

flush privileges;

ALTER USER USER() IDENTIFIED BY 'wang';

允许远程访问

use mysql;

update user set host = '%' where user = 'root';

备份恢复数据

a、导出整个数据库(包括数据库中的数据)

mysqldump-u username -p dbname >dbname.sql

b、导出数据库结构(不含数据)

mysqldump-u username -p -d dbname >dbname.sql

c、导出数据库中的某张数据表(包含数据)

mysqldump-u username -p dbname tablename >tablename.sql

d、导出数据库中的某张数据表的表结构(不含数据)

mysqldump-u username -p -d dbname tablename >tablename.sql

mysql-u -p < /opt/mytest_bak.sql #库必须存在,空库也可

shell命令

show databases;

use database_name;

show tables;

show columns from table;

show index from table;

show table status from database; 显示数据库中所有表的信息

show table status form database_name like "user%";  表名以user开头的表的信息

sql语句

create database dbtest;

create table tabletest (id int not NULL auto_increment, inserttime DATE, PRIMARY KEY(id)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into tabletest (inserttime) values ('2019-9-3 13:00:30');

delete from elec_data where id<12340;

alter table tabletest change inserttime insert_time DATETIME;

alter table tabletest ADD ui1 INT, ADD ui2 INT;

3.  C API

C++库依赖boost库,比较复杂,一般直接使用C客户端在C/C++应用中。

3.1    版本说明

Connector/C is a client library that implements the C API for client/server communication.

MySQL C API有两个版本:libmysqlclient和libmysqld。两个版本有相同接口。

libmysqlclient用于网络通信连接。

libmysqld是嵌入式版本库,用于程序本身包含MySQL server的应用。

在windows下,网络版静态库为mysqlclient.lib,动态库是libmysql.dll,动态导入静态库为libmysql.lib。嵌入式版本,相应的库名为:mysqlserver.lib,libmysqld.dll,和libmysqld.lib.

两种方式获取C API头文件和库:

1) MySQL Server distribution,包含libmysqlclient和libmysqld。

2) Connector/C distribution,仅仅包含libmysqlclient。下载地址https://downloads.mysql.com/archives/c-c/。

3.2 C API调用流程

1) 调用mysql_library_init()初始化MySQL客户端库。

2) 调用mysql_init()初始化一个连接句柄(handler),通过mysql_real_connect()连接serve。

3) 调用SQL语句并处理结果。

4) 调用mysql_close()关闭连接。

5) 调用mysql_library_end()结束MySQL client库的使用。

使用注意点如下:

1) mysql_library_init()和mysql_library_end()提供隐藏的内存管理,对于embedded server相关应用还包含启动和停止server的调用。在非多线程环境下,mysql_library_init()可以省略,因为mysql_init()会动态调用它。

2) 一旦连接成功,mysql_real_connect()会设置reconnect flag为0。reconnect为1表示会重新连接server,当因为连接断开而执行statement失败时。可通过调用mysql_options()设置MYSQL_OPT_RECONNECT选项来控制reconnect行为。

3) 可通过mysql_query()或mysql_real_query()发送SQL语句到server。mysql_query()需要string以null终止。若要发送二进制数据可使用mysql_real_query()。

4) 有两种方法处理结果集。一种方式是调用mysql_store_result(),获取所有的行数据(all the rows),需要内存大;第二种方式是调用mysql_use_result()初始化一行一行获取数据,此函数仅仅初始化获取空间,实际没有得到任何行数据。最后调用mysql_free_result()释放内存。

5) 两种方式都可通过mysql_fetch_row()提取行数据,通过mysql_fetch_lengths()获取每行数据的size;通过重复调用mysql_fetch_field()获取一行内的列数据,或者调用mysql_fetch_field_direct()通过field number直接获取列数据,或者调用mysql_fetch_fields()一次性获取所有列数据。

6) 通过调用mysql_errno()和mysql_error()获取错误码或错误信息。

7) The API makes it possible for clients to respond appropriately to statements (retrieving rows only as necessary) without knowing whether the statement is a SELECT. You can do this by calling mysql_store_result() after each mysql_query() (or mysql_real_query()). If the result set call succeeds, the statement was a SELECT and you can read the rows. If the result set call fails, call mysql_field_count() to determine whether a result was actually to be expected. If mysql_field_count() returns zero, the statement returned no data (indicating that it was an INSERT, UPDATE, DELETE, and so forth), and was not expected to return rows. If mysql_field_count() is nonzero, the statement should have returned rows, but did not. This indicates that the statement was a SELECT that failed. See the description for mysql_field_count() for an example of how this can be done.

3.3 C API使用说明

1. 返回值。函数通常返回一个指针或一个整数。 Unless specified otherwise, functions returning a pointer return a non-NULL value to indicate success or a NULL value to indicate an error, and functions returning an integer return zero to indicate success or nonzero to indicate an error. Note that “nonzero” means just that. Unless the function description says otherwise, do not test against a value other than zero.

2. 在失败的函数调用后紧跟mysql_errno()或mysql_error()可以返回错误code或错误信息。如调用mysql_real_connect()报错,mysql_error()打印如下信息:

Authentication plugin 'caching_sha2_password' cannot be loaded: 找不到指定的模块。

mysql server从5.7版本开始,默认采用caching_sha2_password验证方式。若要改为原来的mysql_native_password方式,需在mysql shell中执行如下命令:

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root_pw';

3.4 C API两套函数调用

Mysql提供两套C API,一种通用SQL语句查询,另一种为预处理调用(prepared statements)。

预处理调用将SQL语句强制一分为二,第一部分为相同的命令和结构部分,第二部分为SQL的参数部分(如查询条件等)。用于执行相同SQL语句(只是查询或处理条件不同),执行效率更高。参考:MySql 的预处理(简书),MySQL之Prepared Statements(博文)

MySQL服务器-客户端协议提供prepared statements(预处理)调用,使用由mysql_stmt_init()返回的MYSQL_STMT句柄。Prepared execution is an efficient way to execute a statement more than once. The statement is first parsed to prepare it for execution. Then it is executed one or more times at a later time, using the statement handler returned by the initialization function.

Prepared execution执行速度快,使用二进制传输效率高,但有局限,需要实际测试,可参考:C API Prepared Statements。

3.5 示例

#include #include#include#include#include"mysql.h"

#pragma comment(lib,"../lib/libmysql.lib")

#define REPEAT_READ_MAX 5 //重读数据次数

#define MYSQL_SERVER_IP_LOCAL "127.0.0.1" //mysql服务器地址

#define MYSQL_SERVER_IP MYSQL_SERVER_IP_LOCAL

#define MYSQL_SERVER_PORT 3306 //mysql server port

#define MYSQL_USER "root" //mysql user

#define MYSQL_PASSWD "wang" //mysql password

#define MYSQL_DB "fenghua" //mysql database

using namespacestd;char SQL_INSERT_T[] = "insert into tabletest (id, insert_time) values (%ld, \'%s\');";char SQL_INSERT_TT[] = "insert into tabletest (insert_time) values (\'%s\');";char SQL_SELECT_LAST_2_T[] = "select * from tabletest order by insert_time DESC limit 2";char SQL_T[1024] = { '\0'};char stime[32];

unsignedint ID_T = 0;int myInsertData(MYSQL* mysql, char*sql)

{if (!mysql || !sql) {return 1;

}int ret = 0;if ((ret = mysql_query(mysql, sql)) != 0)

{//cout << "Insert error " << ret << endl;

return 1;

}return 0;

}int mySelectData(MYSQL* mysql, char* sql, unsigned intnum)

{if (!mysql || !sql) {return 1;

}//char rg = '\n';//行分割//char cg = '\t';//字段分割

unsigned long long rowcount = 0;

unsignedint fieldcount = 0, cur_row = 0;

MYSQL_RES* result =NULL;

MYSQL_FIELD* field = NULL; //字段

MYSQL_ROW row = NULL; //记录

if (mysql_query(mysql, sql) != 0) {

cout<< "Select query error!" <

}

result=mysql_store_result(mysql);if (result ==NULL) {

cout<< "Select result error!" <

}

rowcount= mysql_num_rows(result); //获取记录数

fieldcount = mysql_num_fields(result); //获取字段数

if (num == 0) {

num= (unsigned int)rowcount;

}

cout<< "Now the count of records:" << rowcount <

{for (unsigned int i = 0; i < fieldcount; i++)

{if(row[i]) {

cout<

}

cout<< '\t';

}

cout<

}

mysql_free_result(result);return 0;

}void getDatetime(char* str, unsigned intsize)

{

time_t rawtime;structtm timeinfo;

time(&rawtime);

localtime_s(&timeinfo, &rawtime);

strftime(str, size,"%Y-%m-%d %H:%M:%S", &timeinfo);//cout << str << endl;

}int main(int argc, char*argv[])

{int ii = 0;int repeat_count = 0;

ERROR_CODE ecode;

mysql_library_init(0, NULL, NULL);

MYSQL mysql;while (1) {

repeat_count= 0;

mysql_init(&mysql);//连接mysql服务器

while (1) {

cout<< "Set charset ......";if (0 == mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8"))//设置字符集

{

cout<< "OK !" <

}else{

cout<< "Failed !" <

Sleep(10);continue;

}char user[32] = "root";char pw[32] = "wang";char dbb[32] = "fenghua";

cout<< "Connect to mysql server" << MYSQL_SERVER_IP << "......" <

{

cout<< "Can't connect mysql" << ii <

Sleep(1000);

}else{

cout<< "Welcome to mysql !" <

}

}while(repeat_count

{

{

cout<< "Post data to mysql ......" <

getDatetime(stime,sizeof(stime));//sprintf_s(SQL_T, SQL_INSERT_T, ID_T++, stime);//insert fields

sprintf_s(SQL_T, SQL_INSERT_TT, stime); //insert fields

cout << SQL_T <

cout<< "Insert error!\n" <

repeat_count++;

Sleep(1000);continue;

}else{

repeat_count= 0;

}

sprintf_s(SQL_T, SQL_SELECT_LAST_2_T);if (mySelectData(&mysql, SQL_T, 0)) {

cout<< "\t Select error!" <

}

}

Sleep(5000);

}

}

mysql_close(&mysql);

}

mysql_server_end();

mysql_library_end();return 0;

}

注:当table的id设置为auto_increment时,可不插入id,id会自增加。

if ((0 == mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8")) &&\

(0 == mysql_options(&mysql, MYSQL_OPT_READ_TIMEOUT, &ttimeout)) &&\

(0 == mysql_options(&mysql, MYSQL_OPT_WRITE_TIMEOUT, &ttimeout)))

上述代码用于设置读写超时。

4.  C++ API

MySql Connector/C++8是一个用于连接MySQL服务器的C++应用程序。Connector/C++8可用于访问实现文档存储的 MySQL服务器,或者使用SQL查询以传统方式访问。它支持使用XDevAPI开发C ++应用程序,或使用XDevAPI for C开发纯C应用程序,同时Connector/C++8还支持与之前使用Connector/C++1.1中基于JDBC的旧API开发的C++应用程序一起编译及开发(即:向后兼容)。但是,Connector/C++8的首选开发环境是使用XDevAPI或XDevAPI for C。

注意:connecotr/C++8是基于X plugin的X protocol进行通信,所以在使用connector/C++8时先确认MySql服务器端以加载mysqlx插件,对于使用基于JDBC的旧API的Connector/C++应用程序,不需要也不支持X插件。 此外,X Protocol使用的默认端口为33060,如果是使用之前的JDBC4.0进行开发则使用3306端口,监听的IP默认为任意可用IP。

MySql Connector/C++8支持的应用程序编程接口:

l  X DevAPI

l  X DevAPI for C

l  基于JDBC 4.0的API

支持X DevAPI 和 X DevAPI for C 的 MySql服务器版本 为 Mysql5.7.12及更高版本。

在mysql客户端中输入,查看以加载的插件信息

mysql> show plugins;

如果没有mysqlx,则使用以下命令加载插件(mysqlx)

mysql> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so';

5. 高可用

MySQL主从复制是什么?    MySQL主从复制

主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave)。因为复制是异步进行的,所以从服务器不需要一直连接着主服务器,从服务器甚至可以通过拨号断断续续地连接主服务器。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上的某个表。

实现方式:

1)配置多数据源;

2)使用mysql的proxy中间件代理工具;

第一种方式中,数据库和Application是有一定侵入性的,即我们的数据库更换时,application中的配置文件是需要手动修改的。而第二种方式中,我们可选择mysql proxy固定连接一个数据库,即使数据库地址更换也无需更换项目中的数据库连接配置。

同样,在开始配置实现MySQL读写分离之前,我们会遇到一个选型问题,那就是在诸多的MySQL的proxy中间件工具中,如mysql-proxy、atlas、cobar、mycat、tddl、tinnydbrouter和mysql router等,我们该如何取舍呢?所以在择工具实现前,我们先对以上的proxy中间件做一个简单的优劣介绍,以便我们根据不同的场景选择。

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值