SQL预处理语句(Prepared Statements)

许多成熟的数据库都支持预处理语句(Prepared Statements)的概念。它们是什么东西?你可以把它们想成是一种编译过的要执行的SQL语句模板,可以使用不同的变量参数定制它。预处理语句具有两个主要的优点:

查询只需要被解析(或准备)一次,但可以使用相同或不同的参数执行多次。当查询准备好(Prepared)之后,数据库就会分析,编译并优化它要执行查询的计划。对于复杂查询来说,如果你要重复执行许多次有不同参数的但结构相同的查询,这个过程会占用大量的时间,使得你的应用变慢。通过使用一个预处理语句你就可以避免重复分析、编译、优化的环节。简单来说,预处理语句使用更少的资源,执行速度也就更快。

传给预处理语句的参数不需要使用引号,底层驱动会为你处理这个。如果你的应用独占地使用预处理语句,你就可以确信没有SQL注入会发生。(然而,如果你仍然在用基于不受信任的输入来构建查询的其他部分,这仍然是具有风险的)。 继续阅读SQL预处理语句(Prepared Statements)

PHP开发者常犯的10个MySQL错误

数据库是Web大多数应用开发的基础。如果你是用PHP,那么大多数据库用的是MySQL也是LAMP架构的重要部分。PHP看起来很简单,一个初学者也可以几个小时内就能开始写函数了。但是建立一个稳定、可靠的数据库确需要时间和经验。下面就是一些这样的经验,不仅仅是MYSQL,其他数据库也一样可以参考。

1.使用MyISAM而不是InnoDB
MySQL有很多的数据库引擎,单一般也就用MyISAM和InnoDB。
MyISAM 是默认使用的。但是除非你是建立一个非常简单的数据库或者只是实验性的,那么到大多数时候这个选择是错误的。MyISAM不支持外键的约束,这是保证数据 完整性的精华所在啊。另外,MyISAM会在添加或者更新数据的时候将整个表锁住,这在以后的扩展性能上会有很大的问题。
解决办法很简单:使用InnoDB。 继续阅读PHP开发者常犯的10个MySQL错误

mysqlhotcopy备份报错

错误信息:

/usr/local/mysql/bin/mysqlhotcopy -u root -p  --addtodest --noindices --flushlog -q qeedoo /tmp/bak
install_driver(mysql) failed: Can't locate DBD/mysql.pm in @INC (@INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at (eval 7) line 3.
Perhaps the DBD::mysql perl module hasn't been fully installed,
or perhaps the capitalisation of 'mysql' isn't right.
Available drivers: DBM, ExampleP, File, Proxy, Sponge.

解决办法:

# http://search.cpan.org/~capttofu/DBD-mysql-3.0008/
wget http://search.cpan.org/CPAN/authors/id/C/CA/CAPTTOFU/DBD-mysql-4.020.tar.gz
tar zxvf DBD-mysql-4.020.tar.gz
cd /tmp/DBD-mysql-4.020
perl Makefile.PL --mysql_config=/usr/local/webserver/mysql/bin/mysql_config
make
make install

最后编译安装完之后 发现还是报错:

install_driver(mysql) failed: Can't load '/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/DBD/mysql/mysql.so' for module DBD::mysql: libmysqlclient.so.16: cannot open shared object file: No such file or directory at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 230.
 at (eval 7) line 3
Compilation failed in require at (eval 7) line 3.
Perhaps a required shared library or dll isn't installed where expected
 at /usr/bin/mysqlhotcopy line 177

是因为tar安装mysql后的路径配置的有问题

vi /etc/ld.so.conf

把mysql的这个库文件路径添加进去

echo "/usr/local/webserver/mysql/lib/mysql" >> /etc/ld.so.conf
ldconfig

再执行mysqlhotcopy的时候,一切正常。

有一台服务出现如下问题:
以下问题待遇查看资料,先记下另外这个问题:

Can't locate DBI.pm in @INC (@INC contains: /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl /usr/lib/perl5/5.8.8/i386-linux-thread-multi /usr/lib/perl5/5.8.8 .) at /usr/local/mysql/bin/mysqlhotcopy line 8.
BEGIN failed--compilation aborted at /usr/local/mysql/bin/mysqlhotcopy line 8.

原因:系统没有按安装DBI组件。

定时检测mysql同步状态

笔记一下

#!/bin/sh

#check MySQL_Slave Status
#crontab time 00:10
MYSQL_USER="root"
MYSQL_PWD="123456"
MYSQL_SLAVE_LOG="/tmp/check_mysql_slave.log"
EMAIL="1351010****@139.com"

MYSQL_PORT=`netstat -na|grep "LISTEN"|grep "3306"|awk -F[:" "]+ '{print $5}'`
MYSQL_IP=`ifconfig eth0|grep "inet addr" | awk -F[:" "]+ '{print $4}'`
MYSQL_SLAVE_STATUS=$(/usr/local/webserver/mysql/bin/mysql -u root -psylc23hua -S /tmp/mysql.sock -e "show slave status\G" | grep -i "running")
IO_ENV=`echo $MYSQL_SLAVE_STATUS | grep IO | awk ' {print $2}'`
SQL_ENV=`echo $MYSQL_SLAVE_STATUS | grep SQL | awk '{print $2}'`
NOW=$(date -d today +'%Y-%m-%d %H:%M:%S')

if [ "$MYSQL_PORT" = "3306" ];then
  echo "mysql is running!"
else
  mail -s "warn!server: $MYSQL_IP mysql is down" "$EMAIL"
fi

if [ "$IO_ENV" = "Yes" -a "$SQL_ENV" = "Yes" ];then
  echo "Slave is running!"
else
  echo "[ $NOW ] Slave is not running!" >> "$MYSQL_SLAVE_LOG"
  cat "$MYSQL_SLAVE_LOG" | mail -s "WARN! ${MySQL_IP}_replicate_error" "$EMAIL"
fi

exit 0

6个有用的MySQL语句

今天给大家介绍六条比较有用的MySQL的SQL语句,可能很多人都通过PHP来实现这些功能。

1. 计算年数

你想通过生日来计算这个人有几岁了。

SELECT DATE_FORMAT(FROM_DAYS(TO_DAYS(now()) - TO_DAYS(@dateofbirth)), '%Y') + 0;

2. 两个时间的差

取得两个 datetime 值的差。假设 dt1 和 dt2 是 datetime 类型,其格式为 ‘yyyy-mm-dd hh:mm:ss’,那么它们之间所差的秒数为:

UNIX_TIMESTAMP( dt2 ) - UNIX_TIMESTAMP( dt1 )

除以60就是所差的分钟数,除以3600就是所差的小时数,再除以24就是所差的天数。

3. 显示某一列出现过N次的值

SELECT id
FROM tbl
GROUP BY id
HAVING COUNT(*) = N;

4. 计算两个日子间的工作日

所谓工作日就是除出周六周日和节假日。

SELECT COUNT(*)
FROM calendar
WHERE d BETWEEN Start AND Stop
  AND DAYOFWEEK(d) NOT IN(1,7)
  AND holiday=0;

5. 查找表中的主键

SELECT k.column_name
FROM information_schema.table_constraints t
JOIN information_schema.key_column_usage k
USING (constraint_name,table_schema,table_name)
WHERE t.constraint_type='PRIMARY KEY'
  AND t.table_schema='db'
  AND t.table_name=tbl'

6. 查看你的数库有多大

SELECT
  table_schema AS 'Db Name',
  Round( Sum( data_length + index_length ) / 1024 / 1024, 3 ) AS 'Db Size (MB)',
  Round( Sum( data_free ) / 1024 / 1024, 3 ) AS 'Free Space (MB)'
FROM information_schema.tables
GROUP BY table_schema ;

希望对你有帮助。
原文地址:http://coolshell.cn/articles/3433.html

Linux下查看nginx,apache,mysql,php的编译参数

1、nginx编译参数:
#/usr/local/nginx/sbin/nginx -V
2、apache编译参数:
# cat /usr/local/apache/build/config.nice
3、php编译参数:
# /usr/local/php/bin/php -i |grep configure
4、mysql编译参数:
# cat /usr/local/mysql/bin/mysqlbug|grep configure

MongoDB接口MongoDB::execute()测试

了解过Mongo的朋友都知道,Mongo客户端对CURD的常用方法是经过封装的,不像MySQL,所有的操作都通过mysql_query()一个入口。
其实Mongo也有提供一个基于BSON的接口MongoDB::execute()可以直接执行命令。如:
PHP代码:

$mo = new Mongo;
$ret = $db->execute("db.hdj_messages.count();");
dump($ret['retval']);
$ret = $mo->test->execute('db.hdj_messages.getName()');
var_dump($ret['retval']);
$ret = $mo->test->execute("db.hdj_messages.findOne();");
var_dump($ret['retval']);

结果:

float(2)

string(12) "hdj_messages"

array(5) {
  ["_id"] => object(MongoId)#8 (1) {
    ["$id"] => string(24) "4eb732b564a637ac607fbf41"
  }
  ["addtime"] => string(19) "2011-11-07 09:23:00"
  ["content"] => string(4) "test"
  ["title"] => string(12) "test_title_1"
  ["views"] => int(1)
}

通过测试

db.hdj_messages.insert();
db.hdj_messages.save();
db.hdj_messages.stats();
db.hdj_messages.getName();

等大部份操作都能执行成功,但还是有一部分操作是不支持的,应该说不直接支持,例如:db.hdj_messages.find()返回的不是一个数组,而是一个指针对象,所以直接这样执行是不行的。
那要怎么办才能让它正常支持呢?答案很简单,只要把find()返回的结果转换为array类型就可以,直接看代码吧:
PHP代码:

$mo = new Mongo;
$ret = $mo->test->execute('db.hdj_messages.find().toArray()');
var_dump($ret['retval']);

结果:

array(2) {
  [0] => array(5) {
    ["_id"] => object(MongoId)#8 (1) {
      ["$id"] => string(24) "4eb732b564a637ac607fbf41"
    }
    ["addtime"] => string(19) "2011-11-07 09:23:00"
    ["content"] => string(4) "test"
    ["title"] => string(12) "test_title_1"
    ["views"] => int(1)
  }
  [1] => array(4) {
    ["_id"] => object(MongoId)#9 (1) {
      ["$id"] => string(24) "4eb73c5f7de6444c0e000000"
    }
    ["title"] => string(4) "aaaa"
    ["content"] => string(3) "bbb"
    ["addtime"] => string(19) "2011-11-07 10:03:11"
  }
}

后来经测试,MongoDB::execute()与Mongo提供的API效率相差挺大的,findOne()操作效率比大概为2:1,find()效率比大概是30:1。

MySQL主从同步怪异问题之mysql_select_db必须

MySQL主从同步对大家而言,已经是熟悉到不能再熟悉了,在这就不解释太多。
环境:
主服务器M
从服务器S
数据库A中数据表a

问题详细:
通过PHP脚本对M服务器中数据库A中的数据表a进行数据CURD操作,S服务器数据没有同步更新。

$connection = mysql_connect('A_SERVER', 'A_USER', 'A_PWD');
mysql_query("INSERT INTO `A`.`a` (`a`,`b`) VALUES ('1', '2')");

通过phpMyAdmin进行同样的操作,S服务器的数据同步更新了。

INSERT INTO `A`.`a` (`a`,`b`) VALUES ('1', '2');

问题分析
两个操作对M服务器的数据都正常,这个无用质疑,但是为什么S服务器同步就会有差别呢?其实有一个区别,PHP脚本里没有mysql_select_db操作,难道真的是因为这个原因?是的,正是因为这个原因。
很多人认为在表名前面加上数据库名就可以省略mysql_select_db这步操作了,特别是在跨库操作的时候,结果导致了这样的结果。

MySQL遇到的两个问题

COUNT(DISTINCT `field`)是魔鬼,数据量稍大一些,执行此操作就会提示内存不足。
建议改用临时表加GROUP BY的方法来解决。

SELECT COUNT(*) FROM (SELECT `field` FROM `table` GROUP BY `field`) a LIMIT 1;

插入数据时MYSQL返回#1062 – Duplicate entry ‘127’ for key ‘PRIMARY’,这种问题是没有规律的,不一定什么时候就出现了,不过一般是数据量比较大的时候,比如达到6位数出现的几率就多了一点。