天生我才必有用

MySQL 数据库的备份 (命令行方式)

分类: 数据库    作者:Ray    2008年06月25日

对于一个成功的网站来说,可能程序的可用性是一个比较重要的环节,但网站更核心的内容和灵魂还是隐藏在UI后面的数据。

现在大多数网站都采用LAMP(Linux + Apache + MySQL + PHP),原因就是它在使用成本上的价廉物美,所以今天我们来介绍一下如何对MySQL数据进行备份.

方法非常的简单,使用mysqldump命令即可:

mysqldump --default-character-set=utf8 -uusername -ppassword -hhostname db_name > db_name-$(date +%F).sql

为了支持多国语言(当然包括中文),现在越来越多的数据库使用utf8作为它的默认编码,所以在例子中使用utf8作为数据默认编码,否则不指定会造成汇出的数据乱码。

同时请替换红字表示的一些设定值:

  • username : 数据库的用户名。
  • password: 数据库的秘密。
  • hostname: 如果数据库和代码不是同一台服务器时。(这种情况非常常见,特别是大型网站和一些虚拟空间)
  • db_name: 数据库的名称。
  • $(date +%F): 使用shell变量来为备份的文件加上日期,这样就避免了每天备份时,覆盖了昨天的备份数据。

最后把此命令保存为shell脚本,加入到crontab中,让系统可以按你的要求备份数据。

标签:

MySQL (Can’t connect to) (10061)

分类: 数据库    作者:Ray    2008年02月29日

今天在Debian 4.0的服务器上安装了MySQL的服务,安装非常的简单,服务器也已经运行起来。但现在却碰到了一个,就是从其他客户端连接(即非localhost),却死活连不上,同时返回一个错误Can't connect to MySQL server on 'server‘ (10061)。
查了半天的原因未过,猜想是不是由于mysql服务的配置问题。就好奇的去看了一下my.cnf,原来原因真的是配置的问题,只需修改#bind-address = 127.0.0.1,把注释去除,原来无法连接的问题就解决了。

标签:

MySQL中的数据汇总

分类: 数据库    作者:Ray    2007年12月10日

在各类应用中,数据汇总是经常会使用到的功能,对每天、每周、每月的数据汇总后产出报表。实现的方法当然很多,也并不是非常困难,但如何有效的利用数据库,让其来帮你分类统计这些数据,还是具有一定的技巧性。

1.使用高级语言汇总:

这种方法可能是最方便,也是最简单的方法。通过使用查询数据对满足条件的数据进行查询,接着使用其他高级语言,如:PHP、C#、Java对符合条件的数据进行汇总。

$today = getdate();
if ($date_range == "week") {
    $start_date = mktime(0 , 0 , 0, $today['mon'],
                $today['mday'] - $today['wday'] , $today['year']);
    $end_date	= strtotime("+1 week" , $start_date);
}
else if ($date_range == "month") {
    $start_date = mktime(0 , 0 , 0, $today['mon'], 1 , $today['year']);
    $end_date	= strtotime("+1 month" , $start_date);
}
else if ($date_range == "year") {
    $start_date = mktime(0 , 0 , 0, 1 , 1, $today['year']);
    $end_date	= strtotime("+1 year" , $start_date);
}
$end_date = strtotime("-1 second" , $end_date);

while($date < $end_date) {
    $min_date = $date;
    if ($date_interval == "day")
        $max_date = strtotime("1 day" , $min_date);
    elseif ($date_interval == "week")
        $max_date = strtotime("1 week" , $min_date);
    elseif ($date_interval == "month")
	$max_date = strtotime("1 month" , $min_date);
    elseif ($date_interval == "year")
	$max_date = strtotime("1 year" , $min_date);
    $date = $max_date;
    $max_date = strtotime("-1 sec" , $max_date);
    $sql = sprintf("SELECT id , total FROM orders WHERE  order_date >= '%s'
        AND order_date <= '%s'" , date("Y-m-d H:i:s",$min_date ),
        date("Y-m-d H:i:s" ,$max_date));
    ....
    $orders = $db->query($sql);
    ....
    $total_falcon = 0;
    $total_sales  = 0;
    for ($next = 0 ; $next < count($orders) ; $next ++){
	$total_sales += $order['total'];
        $sum_order  += $total_order;
    }
    $sum_falcon += $total_falcon;
    $sum_sales  += $total_sales;
}

以上所举的例子,不容质疑主要问题就是效率,完全没有使用数据库的sum,count函数。同时带来的问题就是代码过于累赘繁琐。

2.使用SQL语句

$today = getdate();
if ($this->date_range == "week") {
    $this->start_date = mktime(0 , 0 , 0, $today['mon'],
         $today['mday'] - $today['wday'] , $today['year']);
    $this->end_date	  = strtotime("+1 week" , $this->start_date);
}
else if ($this->date_range == "month") {
    $this->start_date = mktime(0 , 0 , 0, $today['mon'],
          1 , $today['year']);
    $this->end_date	  = strtotime("+1 month" , $this->start_date);
}
else if ($this->date_range == "year") {
    $this->start_date = mktime(0 , 0 , 0, 1 , 1, $today['year']);
    $this->end_date	  = strtotime("+1 year" , $this->start_date);
}
$this->end_date = strtotime("-1 second" , $this->end_date);

switch($this->date_interval){
    case "year":
	$this->group = "%Y";
	break;
    case "month":
	$this->group = "%m-%Y";
	break;
    case "week":
	$this->group = "Week %v - %Y";
	break;
    case "day":
    default:
	$this->group = "%m-%d-%Y";
	break;
}

$query  = "SELECT COUNT(o.id) as total_order ,";
if ($interval){
    $query  .= " DATE_FORMAT(o.order_data , '{$this->group}') as report_date , ";
}
$query .= " SUM(o.total) as total_sale, ";
$query .= " SUM(o.quantity) as total_quantity ";
$query .= " FROM orders AS o ";
$query .= sprintf(" WHERE o.order_date >= '%s' AND o.order_date <= '%s' " ,
     date("Y-m-d H:i:s" , $this->start_date) , date("Y-m-d H:i:s" , $this->end_date));
$query .= " GROUP BY report_date";
$query .= " ORDER BY report_date";
$db->query($query);

从以上的例子中可以看出,我们完全避免了使用for循序来对数据进行各种累加,取而代之的是充分的使用了sum或total等SQL函数来对数据进行累加,由于这些函数是数据库内置函数,只需增加一下栏位的索引,产出的结果会比使用方法1快几个数量级,同时也节省了第一种情况的频繁访问数据库的开销。通过使用DATE_FORMAT函数和Group语句,实现了对数据的分类检索,完全可以使用非常简单的几种日期格式化实现原来高级语言无法实现或者实现会非常繁琐的分类检索。

BTW:慎用英文字母的格式化,不要以为这样可以加少日期显示上的一些问题,因为Order会按字母顺序排列,这样一月(January)就会排序在二月(Feburary)后面。

MySql server has gone away

分类: 数据库    作者:Ray    2007年12月2日

是否曾遇见过 “MySql serverhas gone away”,一句让人其实非常琢磨不透的错误信息。

对这个问题请先别怀疑自己的代码是否有问题,其实可能只不过是一个小小的设置问题。

我所碰到的情况就是,当你有大数据(数据大小大于1M)保存到longblob栏位时,会出现这个问题。

起初也查了很久,是不是自己的代码出错,但使用的是PHP,不会向哪类编译型语言有数据越界的可能,百思不得其解。最终看了下mysql.ini,发现max_allowed_packet=1M,是不是这个默认设定值造成了此问题,把此设定值修改成max_allowed_packet=16M,问题真的解决了。

因此碰到此问题请先检查自己的设定值是否有问题。

补充一句,不同版本的Mysql,此问题的错误信息可能会不同。

标签: