Mysql数据库管理
强制指定mysql的字符集
修改my.cnf
collation_server=utf8_unicode_ci
character_set_server=utf8
skip-character-set-client-handshake
高负荷请求的一些设置
set-variable = max_connections=500
set-variable = max_connect_errors=10000
set-variable = wait_timeout=300
set-variable = interactive_timeout=30
set-variable = thread_cache=40
set-variable = back_log=500
skip-locking
skip-name-resolve
使用mysqldump备份数据库
mysqldump -u root -p --default-character-set=utf8 --no-create-info {db_name} {table_name} -w"{query_sql}" > backup.sql
-u
用户名-p
密码--default-character-set=utf8
(解决乱码, 可以用status来查看你当前数据库默认的是什么字符集来确定是不是要用utf8)--no-create-info
(不要create语句, 只要insert, 用来导入数据)-w
(指定一张表里的一个符合要求的行, 其实就是where后要跟的条件语句)
数据库还原,直接使用mysql命令:
mysql -u root -p {db_name} < backup.sql
prepare statement
使用prepare statement的好处是比传统的查询方法更快一些, 尤其是做批量的insert, update的时候, 因为它会预处理你的查询语句. 具体请参阅这里.
一个使用prepare statement的例子:
con = mysql_init();
mysql_real_connect(con, ... );
stmt = mysql_stmt_init(con);
mysql_stmt_prepare(stmt, sql, sql_len);
mysql_stmt_bind_param(stmt, bind);
loop {
select(...);
mysql_stmt_execute(stmt);
}
mysql_stmt_close(stmt);
mysql_close(conn);
在mysql_stmt_bind_param()
和mysql_stmt_bind_result
有一些注意事项, 就是不明确的信息一定要说明. 比如, 当传递int
这样固定的类型时候, 不需要指定类型长度, 但传递 char *
之类时候就需要了. 另外, 如果传递 unsigned int
, 也需要特别说明它是无符号. 例如:
/* Sample1: when query */
unsigned int ip;
char phone[PHONE_SIZE];
int phone_len = strlen(phone);
MYSQL_BIND bind[2];
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_STRING;
bind[0].buffer = ☎
bind[0].buffer_length = PHONE_SIZE; /* max length */
bind[0].is_null = 0;
bind[0].length = &phone_len; /* actually length, can be omitted */
bind[1].buffer_type= MYSQL_TYPE_LONG;
bind[1].buffer= &ip;
bind[1].is_null= 0;
bind[1].length= 0;
bind[1].is_unsigned = TRUE; /* must announced */
mysql_stmt_bind_param(stmt, bind);
/* Sample2: when fetch */
char address[ADDR_SIZE];
MYSQL_BIND bine[1];
my_bool is_null[1];
unsigned long length[1];
my_bool error[1];
memset(bind, 0, sizeof(bine));
bind[0].buffer_type = MYSQL_TYPE_STRING;
bind[0].buffer = (char *)address;
bind[0].buffer_length = ADDR_SIZE;
bind[0].is_null = &is_null[0];
bind[0].length = &length[0];
bind[0].error = &error[0];
/* bind the result buffers */
mysql_stmt_bind_result(stmt, bine);
如果你在使用MYSQL++库的话,遗憾的是它目前还不支持prepare statement,虽然在wishlist里面已经很久了。这里可以推荐使用mysql自己出的一套库Connector C++,支持JDBC 3.0 API,并且支持prepare statement,不过暂时该产品还在preview阶段。
关于超时
如果两次数据库操作之间间隔的时间过长, 则中途数据库连接会超时, 解决办法是:
- 自己维护连接池, 考虑使用
stl::set
- 使用一些有连接池的库, 比如 MYSQL++
- 在my.cnf中延长
wait_timeout
-
设置MYSQL_OPT_RECONNECT, 这个选项在mysql5.0.13后默认禁用了, 有副作用.
#ifdef MYSQL_OPT_RECONNECT my_bool ifreconn=1; if(mysql_options(con,MYSQL_OPT_RECONNECT,&ifreconn)){ //since 5.0.13 //mysql_errno(con); //...do sth else } #else con->reconnect=1; #endif