Category: Programming


Ajax缓存解决办法

转载一篇文章,在做聊天室的过程中困惑我很久的一个问题.呵呵,太感谢作者了.原文如下:

项目有时要用一些Ajax的效果,因为比较简单,也就没有去用什么Ajax.net之类的东西,手写代码也就实现了。、

第二天,有人向我报告错误;说是只有第一次读取的值正常,后面的值都不正常;我调试了一下 ,确实有这样的问题,查出是因为AJAX缓存的问题:解决办法有如下几种:

1、在服务端加 header(“Cache-Control: no-cache, must-revalidate”);(如php中)

2、在ajax发送请求前加上 anyAjaxObj.setRequestHeader(“If-Modified-Since”,”0″);

3、在ajax发送请求前加上 anyAjaxObj.setRequestHeader(“Cache-Control”,”no-cache”);

4、在 Ajax 的 URL 参数后加上 “?fresh=” + Math.random(); //当然这里参数 fresh 可以任意取了

5、第五种方法和第四种类似,在 URL 参数后加上 “?timestamp=” + new Date().getTime();

6、用POST替代GET:不推荐

1、加个随机数
xmlHttp.open(“GET”, “ajax.asp?now=” + new Date().getTime(), true);

2、在要异步获取的asp页面中写一段禁止缓存的代码:
Response.Buffer =True
Response.ExpiresAbsolute =Now() – 1
Response.Expires=0
Response.CacheControl=”no-cache”

3、在ajax发送请求前加上xmlHTTP.setRequestHeader(“If-Modified-Since”,”0″);可以禁止缓存
xmlHTTP.open(“get”, URL, true);
xmlHTTP.onreadystatechange = callHTML;
xmlHTTP.setRequestHeader(“If-Modified-Since”,”0″);
xmlHTTP.send();

另一个作者写到:

AJAX的缓存是由浏览器维持的,对于发向服务器的某个url,ajax仅在第一次请求时与服务器交互信息,之后的请求中,ajax不再向服务器提交请求,而是直接从缓存中提取数据。

有些情况下,我们需要每一次都从服务器得到更新后数据。思路是让每次请求的url都不同,而又不影响正常应用:在url之后加入随机内容。
e.g.
url=url+”&”+Math.random();

Key points:
1.每次请求的url都不一样(ajax的缓存便不起作用)
2.不影响正常应用(最基本的)

—————-
方法二:(未经证实)
在JSP中禁止缓存
response.addHeader(“Cache-Control”, “no-cache”);
response.addHeader(“Expires”, “Thu, 01 Jan 1970 00:00:01 GMT”);

HTTP:
<META HTTP-EQUIV=”pragma” CONTENT=”no-cache”>
<META HTTP-EQUIV=”Cache-Control” CONTENT=”no-cache, must-revalidate”>
<META HTTP-EQUIV=”expires” CONTENT=”Wed, 26 Feb 1997 08:21:57 GMT”>
<META HTTP-EQUIV=”expires” CONTENT=”0″>

另一个作者写到:

我们都知道,ajax能 提高页面载入的速度的主要原因是通过ajax减少了重复数据的载入,真正做到按需获取,既然如此,我们在写ajax程序的时候不妨送佛送到西,在客户端再 做一次缓存,进一步提高数据载入速度。那就是在载入数据的同时将数据缓存在浏览器内存中,一旦数据被载入,只要页面未刷新,该数据就永远的缓存在内存中, 当用户再次查看该数据时,则不需要从服务器上去获取数据,极大的降低了服务器的负载和提高了用户的体验。

php 随机密码生成函数

<?php
mt_srand((double) microtime() * 1000000);
function gen_random_password($password_length = 32, $generated_password = ""){
$valid_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$chars_length = strlen($valid_characters) - 1;
for($i = $password_length; $i--; ) {
//$generated_password .= $valid_characters[mt_rand(0, $chars_length)];
$generated_password .= substr($valid_characters, (mt_rand()%(strlen($valid_characters))), 1);
}
return $generated_password;
}
?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>php 密码生成器 v 4.0</title>
<style type="text/css">
body {
font-family: Arial;
font-size: 10pt;
}
</style>
</head>
<body>
<span style="font-weight: bold; font-size: 15pt;">密码生成器v4.0 by freemouse</span><br /><br />
<?php
if (isset($_GET['password_length'])){
if(preg_match("/([0-9]{1,8})/", $_GET['password_length'])){
print("密码生成成功:<br />
<span style=\"font-weight: bold\">" . gen_random_password($_GET['password_length']) . "</span><br /><br />\n");
} else {
print("密码长度不正确!<br /><br />\n");
}
}
print <<< end
请为密码生成其指定生成密码的长度:<br /><br />
<form action="{$_SERVER['PHP_SELF']}" method="get">
<input type="text" name="password_length">
<input type="submit" value="生成">
</form>
end;
?>
</body>
</html>

与 UNIX 构建系统交互: config.m4

扩展的 config.m4 文件告诉 UNIX 构建系统哪些扩展 configure 选项是支持的,你需要哪些扩展库,以及哪些源文件要编译成它的一部分。对所有经常使用的 autoconf 宏,包括 PHP 特定的及 autoconf 内建的,请查看 Zend Engine 2 API 参考 章节。

Tip当开发 PHP 扩展时,强烈建议安装 autoconf 2.13 版,尽管用更新的版本可使用。2.13 版被认为是在 autoconf 中可用性,适用性及用户基础等方面最好的版本。使用最新版本有时会与所期望的 configure 输出在样式上有所不同。

Example #1 config.m4 文件举例

dnl $Id$
dnl config.m4 for extension example
PHP_ARG_WITH(example, for example support,
[  --with-example[=FILE]       Include example support. File is the optional path to example-config])
PHP_ARG_ENABLE(example-debug, whether to enable debugging support in example,
[  --enable-example-debug        example: Enable debugging support in example], no, no)
PHP_ARG_WITH(example-extra, for extra libraries for example,
[  --with-example-extra=DIR      example: Location of extra libraries for example], no, no)

dnl 检测扩展是否已启用
if test "$PHP_EXAMPLE" != "no"; then

  dnl 检测 example-config。首先尝试所给出的路径,然后在 $PATH 中寻找
  AC_MSG_CHECKING([for example-config])
  EXAMPLE_CONFIG="example-config"
  if test "$PHP_EXAMPLE" != "yes"; then
    EXAMPLE_PATH=$PHP_EXAMPLE
  else
    EXAMPLE_PATH=`$php_shtool path $EXAMPLE_CONFIG`
  fi

  dnl 如果找到可用的 example-config,就使用它
  if test -f "$EXAMPLE_PATH" && test -x "$EXAMPLE_PATH" && $EXAMPLE_PATH --version > /dev/null 2>&1; then
    AC_MSG_RESULT([$EXAMPLE_PATH])
    EXAMPLE_LIB_NAME=`$EXAMPLE_PATH --libname`
    EXAMPLE_INCDIRS=`$EXAMPLE_PATH --incdirs`
    EXAMPLE_LIBS=`$EXAMPLE_PATH --libs`

    dnl 检测扩展库是否工作正常
    PHP_CHECK_LIBRARY($EXAMPLE_LIB_NAME, example_critical_function,
    [
      dnl 添加所需的 include 目录
      PHP_EVAL_INCLINE($EXAMPLE_INCDIRS)
      dnl 添加所需的扩展库及扩展库所在目录
      PHP_EVAL_LIBLINE($EXAMPLE_LIBS, EXAMPLE_SHARED_LIBADD)
    ],[
      dnl 跳出
      AC_MSG_ERROR([example library not found. Check config.log for more information.])
    ],[$EXAMPLE_LIBS]
    )
  else
    dnl 没有可用的 example-config,跳出
    AC_MSG_RESULT([not found])
    AC_MSG_ERROR([Please check your example installation.])
  fi

  dnl 检测是否启用调试
  if test "$PHP_EXAMPLE_DEBUG" != "no"; then
    dnl 是,则设置 C 语言宏指令
    AC_DEFINE(USE_EXAMPLE_DEBUG,1,[Include debugging support in example])
  fi

  dnl 检测额外的支持
  if test "$PHP_EXAMPLE_EXTRA" != "no"; then
    if test "$PHP_EXAMPLE_EXTRA" == "yes"; then
      AC_MSG_ERROR([You must specify a path when using --with-example-extra])
    fi

    PHP_CHECK_LIBRARY(example-extra, example_critical_extra_function,
    [
      dnl 添加所需路径
      PHP_ADD_INCLUDE($PHP_EXAMPLE_EXTRA/include)
      PHP_ADD_LIBRARY_WITH_PATH(example-extra, $PHP_EXAMPLE_EXTRA/lib, EXAMPLE_SHARED_LIBADD)
      AC_DEFINE(HAVE_EXAMPLEEXTRALIB,1,[Whether example-extra support is present and requested])
      EXAMPLE_SOURCES="$EXAMPLE_SOURCES example_extra.c"
    ],[
      AC_MSG_ERROR([example-extra lib not found. See config.log for more information.])
    ],[-L$PHP_EXAMPLE_EXTRA/lib]
    )
  fi

  dnl 最后,将扩展及其所需文件等信息传给构建系统
  PHP_NEW_EXTENSION(example, example.c $EXAMPLE_SOURCES, $ext_shared)
  PHP_SUBST(EXAMPLE_SHARED_LIBADD)
fi

autoconf 语法简介

config.m4 文件使用 GNU autoconf 语法编写。简而言之,就是用强大的宏语言增强的 shell 脚本。注释用字符串 dnl 分隔,字符串则放在左右方括号中间(例如,[])。字符串可按需要多次嵌套引用。完整的语法参考可参见位于 » http://www.gnu.org/software/autoconf/manual/autoconf 手册。

PHP_ARG_*: 赋予用户可选项

在以上的 config.m4 例子中,两条注释后,最先见到的 3 行代码,使用了 PHP_ARG_WITH()PHP_ARG_ENABLE()。这些给 configure 提供了可选项,和在运行 ./configure –help 时显示的帮助文本。就象名称所暗示的,其两者的不同点在于是创建 –with-* 选项还是 –enable-* 选项。每个扩展应提供至少一个以上的选项以及扩展名称,以便用户可选择是否将扩展构建至 PHP 中。按惯例,PHP_ARG_WITH() 用于取得参数的选项,例如扩展所需库或程序的位置;而 PHP_ARG_ENABLE() 用于代表简单标志的选项。

Example #2 configure 输出举例

$ ./configure --help
...
  --with-example[=FILE]       Include example support. FILE is the optional path to example-config
  --enable-example-debug        example: Enable debugging support in example
  --with-example-extra=DIR      example: Location of extra libraries for example
...

$ ./configure --with-example=/some/library/path/example-config --disable-example-debug --with-example-extra=/another/library/path
...
checking for example support... yes
checking whether to enable debugging support in example... no
checking for extra libraries for example... /another/library/path
...

Note:

在调用 configure 时,不管选项在命令行中的顺序如何,都会按在 config.m4 中指定的顺序进行检测。

处理用户选择

config.m4 可给用户提供一些做什么的选择,现在就是做出选择的时候了。在上例中,三个选项在未指定时显然默认为 “no”。习惯上,最好用此值作为用于启用扩展的选项的默认值,为了扩展与 PHP 分开构建则用 phpize 覆盖此值,而要构建在 PHP 中时则不应被默认值将扩展空间弄乱。处理这三个选项的代码要复杂得多。

处理 –with-example[=FILE] 选项

首先检测是否设置了 –with-example[=FILE] 选项。如此选项未被指定,或使用否定的格式(–without-example ),或赋值为 “no” 时,它会控制整个扩展的含有物其他任何事情都不会发生。在上面的例子中所指定的值为 /some/library/path/example-config,所以第一个 test 成功了。

接下来,代码调用 AC_MSG_CHECKING(),这是一个 autoconf 宏,输出一行标准的如 “checking for …” 的信息,并检测用户假定的 example-config 是否是一个明确的路径。在这个例子中,PHP_EXAMPLE 所取到的值为 /some/library/path/example-config,现已复制到 EXAMPLE_PATH 变量中了。只有用户指定了 –with-example ,才会执行代码 $php_shtool path $EXAMPLE_CONFIG,尝试使用用户当前的 PATH 环境变量推测 example-config 的位置。无论如何,下一步都是检测所选的 EXAMPLE_PATH 是否是正常文件,是否可执行,及是否执行成功。如成功,则调用 AC_MSG_RESULT(),结束由 AC_MSG_CHECKING() 开始的输出行。否则,调用 AC_MSG_ERROR(),打印所给的信息并立即中断执行 configure

代码现在执行几次 example-config 以确定一些站点特定的配置信息。下一步调用的是 PHP_CHECK_LIBRARY(),这是 PHP 构建系统提供的一个宏,包装了 autoconfAC_CHECK_LIB() 函数。PHP_CHECK_LIBRARY() 尝试编译、链接和执行程序,在第一个参数指定的库中调用由第二个参数指定的符号,使用第五个参数给出的字符串作为额外的链接选项。如果尝试成功了,则运行第三个参数所给出的脚本。此脚本从 example-config 所提供的原始的选项字符串中取出头文件路径、库文件路径和库名称,告诉 PHP 构建系统。如果尝试失败,脚本则运行第四个参数中的脚本。此时调用 AC_MSG_ERROR() 来中断程序执行。

处理 –enable-example-debug 选项

处理 –enable-example-debug 很简单。只简单地检测其真实值。如果检测成功,则调用 AC_DEFINE() 使 C 语言宏指令 USE_EXAMPLE_DEBUG 可用于扩展的源代码。第三个参数是给 config.h 的注释字符串,通常可放心的留空。

处理 –with-example-extra=DIR 选项

对于此例子来说,由 –with-example-extra=DIR 选项所请求的假定的“额外”功能操作不会与假定的 example-config 程序共享,也没有默认的搜索路径。因此,用户需要在所需的库之前提供设置程序。有点不象现实中的扩展,在这里的设置仅仅起说明性的作用。

代码开始用已熟知的方式来检测 PHP_EXAMPLE_EXTRA 的真实值。如果所提供的为否定形式,则不会进行其他处理,用户也不会请求额外的功能。如果所提供的为未提供参数的肯定形式,则调用 AC_MSG_ERROR() 中止处理。下一步则再次调用 PHP_CHECK_LIBRARY()。这一次,因为没有提供预定义编译选项,PHP_ADD_INCLUDE()PHP_ADD_LIBRARY_WITH_PATH() 用于构建额外功能所需的头文件路径、库文件路径和库标志。也调用 AC_DEFINE() 来指示所请求的额外功能代码是可用的,设置变量来告诉以后的代码,有额外的源代码要构建。如果检测失败,则调用所熟悉的 AC_MSG_ERROR()。另一种不同的处理失败的方式是更换为调用 AC_MSG_WARNING(),例如:

AC_MSG_WARNING([example-extra lib not found. example will be built without extra functionality.])

上例中,configure 会打印一段警告信息而不是错误,且继续处理。用哪种方式处理失败留给扩展开发人员在设计时决定。

告诉构建系统要做什么

有了所需的头文件和特定的库,有了全部选项处理代码及宏定义,还有一件事要做:必须告诉构建系统去构建扩展本身和被其用到的文件。为了做这些,则要调用 PHP_NEW_EXTENSION() 宏。第一个参数是扩展的名称,和包含它的目录同名。第二个参数是做为扩展的一部分的所有源文件的列表。参见 PHP_ADD_BUILD_DIR() 以获取将在子目录中源文件添加到构建过程的相关信息。第三个参数总是 $ext_shared, 当为了 –with-example[=FILE] 而调用 PHP_ARG_WITH()时,由 configure 决定参数的值。第四个参数指定一个“SAPI 类”,仅用于专门需要 CGI 或 CLI SAPI 的扩展。其他情况下应留空。第五个参数指定了构建时要加入 CFLAGS 的标志列表。第六个参数是一个布尔值,为 “yes” 时会强迫整个扩展使用 $CXX 代替 $CC 来构建。第三个以后的所有参数都是可选的。最后,调用 PHP_SUBST() 来启用扩展的共享构建。参见 扩展相关 FAQ 以获取更多有关禁用共享方式下构建扩展的信息。

counter 扩展的 config.m4 文件

以前编写的 counter 扩展有一个比上面所述更简单的 config.m4 文件,它不使用很多构建系统的特性。对不使用外部的或绑定的库的扩展来说,这是一个比较好的操作方式。

Example #3 counter 的 config.m4 文件

dnl
$
Id$
dnl config.m4 for extension counter

PHP_ARG_ENABLE(counter, for counter support,
[  --enable-counter            Include counter support])

dnl Check whether the extension is enabled at all
if test "$PHP_COUNTER" != "no"; then
  dnl Finally, tell the build system about the extension and what files are needed
  PHP_NEW_EXTENSION(counter, counter.c counter_util.c, $ext_shared)
  PHP_SUBST(COUNTER_SHARED_LIBADD)
fi



If you try to install 5.3.6 on by patching sources you will most likely see a lot of error messages similar to the following:

$ ./configure
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
./configure: 490: 5: Bad file descriptor
./configure: 490: :: checking for pthreads_cflags: not found
./configure: 490: 6: Bad file descriptor
./configure: 490: checking for pthreads_cflags… : not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 490: ac_fn_c_try_run: not found
./configure: 492: 5: Bad file descriptor
./configure: 492: :: result: : not found
./configure: 492: 6: Bad file descriptor
./configure: 492: : Permission denied
./configure: 495: 5: Bad file descriptor
./configure: 495: :: checking for pthreads_lib: not found
./configure: 495: 6: Bad file descriptor
./configure: 495: checking for pthreads_lib… : not found
cat: confdefs.h: No such file or directory
./configure: 555: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 555: ac_fn_c_try_run: not found
cat: confdefs.h: No such file or directory
./configure: 555: ac_fn_c_try_run: not found
./configure: 557: 5: Bad file descriptor
./configure: 557: :: result: : not found
./configure: 557: 6: Bad file descriptor
./configure: 557: : Permission denied
./configure: 633: 5: Bad file descriptor
./configure: 633: :: result: : not found
./configure: 633: 6: Bad file descriptor
./configure: 633: : Permission denied
./configure: 635: 5: Bad file descriptor
./configure: 635: :: result: Configuring SAPI modules: not found
./configure: 635: 6: Bad file descriptor
./configure: 635: Configuring SAPI modules: not found
./configure: 666: 5: Bad file descriptor

See what happened when using buildconf earlier..

$ ./buildconf –force
Forcing buildconf
buildconf: checking installation…
buildconf: autoconf version 2.64 (ok)
buildconf: Your version of autoconf likely contains buggy cache code.
Running vcsclean for you.
To avoid this, install autoconf-2.13.
Can’t figure out your VCS, not cleaning.

This is not a regular warning and it cannot be neglected. You have to use autoconf-2.13. This is because the newer version of autoconf cannot process scripts which are meant for autoconf 2.13. So just install autoconf-2.13 and then do the compilation again..

sudo apt-get install autoconf2.13

Also if you have a low memory machine, then you might get error such as:

[lots of compile output]

/bin/sh /home/ibb_admin/temp/php-5.3.0/libtool –silent –preserve-dup-deps –mode=compile gcc -I/home/ibb_admin/temp/php-5.3.0/ext/fileinfo/libmagic -Iext/fileinfo/ -I/home/ibb_admin/temp/php-5.3.0/ext/fileinfo/ -DPHP_ATOM_INC -I/home/ibb_admin/temp/php-5.3.0/include -I/home/ibb_admin/temp/php-5.3.0/main -I/home/ibb_admin/temp/php-5.3.0 -I/home/ibb_admin/temp/php-5.3.0/ext/date/lib -I/home/ibb_admin/temp/php-5.3.0/ext/ereg/regex -I/usr/include/libxml2 -I/opt/include -I/opt/include/freetype2 -I/usr/include/imap -I/usr/kerberos/include -I/home/ibb_admin/temp/php-5.3.0/ext/mbstring/oniguruma -I/home/ibb_admin/temp/php-5.3.0/ext/mbstring/libmbfl -I/home/ibb_admin/temp/php-5.3.0/ext/mbstring/libmbfl/mbfl -I/opt/include/mysql -I/usr/include/mysql -I/home/ibb_admin/temp/php-5.3.0/ext/sqlite3/libsqlite -I/home/ibb_admin/temp/php-5.3.0/TSRM -I/home/ibb_admin/temp/php-5.3.0/Zend    -I/usr/include -g -O2  -c /home/ibb_admin/temp/php-5.3.0/ext/fileinfo/libmagic/apprentice.c -o ext/fileinfo/libmagic/apprentice.lo
virtual memory exhausted: Cannot allocate memory
make: *** [ext/fileinfo/libmagic/apprentice.lo] Error 1

So just upgrade the gcc compiler to its latest version and also add –disable-fileinfo to ./configure

Hence full installation procedure would be similar to:

sudo apt-get install autoconf2.13
wget http://us.php.net/get/php-5.3.6.tar.bz2/from/us.php.net/mirror
tar -xjf php-5.3.6.tar.bz2
cd php-5.3.6/
./buildconf –force
./configure –disable-fileinfo –enable-fpm –with-zlib –enable-pdo –with-pdo-mysql –enable-sockets –with-mysql –enable-calendar –with-iconv –enable-exif –enable-soap –enable-ftp –enable-wddx –with-zlib –with-bz2 –with-gettext –with-xmlrpc –enable-pcntl –enable-soap –enable-bcmath –enable-mbstring –enable-dba –with-openssl –with-mhash –with-mcrypt –with-xsl –with-curl –with-pcre-regex –with-gd –enable-gd-native-ttf –with-ldap –enable-pdo –with-pdo-mysql –with-mysql –with-sqlite –with-pdo-sqlite –enable-zip–enable-sqlite-utf8 –with-pear

Of course, your php configure options can be different.



可能有很多人遇到过标题中的这个错误。之前我们也经常遇到,一直没有认真找是什么原因。今天花了些时间google了下。原来,这个问题并不是MySQL的bug, 它本质是一个配置问题, 解决起来也不麻烦。

在Mysql客户端中, 通过 SHOW VARIABLES; 语句可以查看Mysql系统变量。这些变量中名为 wait_timeout 的变量的值过于小,就是造成这个错误的根源。这个变量的含义是:如果在该连接在 wait_timeout 时间内没有进行任何查询(idle时间超时), 服务器将自动关闭这个连接。

如果你的脚本在执行了一个查询之后,接着是另外一个很耗时的没有任何数据库查询的操作(超过了wait_timeout设置的值,单位是秒), 之后你再进行数据库操作,就一定会遇到标题所示的错误。

我的解决方案是,在必要的地方,数据库连接之后,立刻执行一句’SET SESSION wait_timeout=65535″。

Pasted from <http://hi.baidu.com/nan_feiyan/blog/item/ea34e81e7aadc90f4034172a.html>

Problem:

Get following prompt in command line while run a php application,

“zend_mm_heap corrupted”

Solution:

A.while do complie for php, use the –enable-debug option

B. Before run a php application, set following environment, USE_ZEND_ALLOC=0, however, it seems this only works for PHP CLI mode, doesn’t work for Apache Module, such as in php.ini or httpd.conf. There is an lucky scenarios for nginx, he fix the problem via: set the environment in bash_profile, and then restart the php-fpm

Note:

zend_mm means Zend Memory Manager

右缩进:tab

左缩进:shift+tab

   在 php 命令行中有两个参数 $argc 和 $argv 分别代表 参数的个数 和 全部参数组成的数组。

<?php

# testvar.php
var_dump ($argc);
var_dump ($argv)
?>
 

php testvar.php 3gcomet

int(2)    //这个表示有两个参数,下面的是列出全部参数,注意参数包括文件名 testvar.php
array(2) {
  [0]=>
  string(5) “testvar.php”
  [1]=>
  string(7) “3gcomet”
}

了解 NoSQL 的必读资料

NoSQL 是非关系型数据存储的广义定义。它打破了长久以来关系型数据库与 ACID 理论大一统的局面。NoSQL 数据存储不需要固定的表结构,通常也不存在连接 操作。在大数据存取上具备关系型数据库无法比拟的性能优势。该术语在 2009 年初得到了广泛认同。
     当今的应用体系结构需要数据存储在横向伸缩性 上能够满足需求。而 NoSQL 存储就是为了实现这个需求。Google 的 BigTable 与 Amazon 的 Dynamo 是非常成功的商业 NoSQL 实现。一些开源的 NoSQL 体系,如Facebook 的 Cassandra , Apache 的 HBase ,也得到了广泛认同。
     如果您刚接触 NoSQL,那有必要学习一些背景知识。下列资料是国外一前沿技术分析师 认为非常有价值的 NoSQL 相关必读资料:
Amazon Dynamo 论文 。几乎所有懂 NoSQL 的人都阅读过它。
Google 的 Bigtable 论文 。 也许您已经耳熟能详。
Werner Vogels 的 “Eventually Consistent” (发布于 ACM Queue )。如果您对“最终一致性 ”不是非常清晰,请阅读这篇文章。
Brewer 的 CAP 理论 (可伸缩性的基础)在这里 可以找到非常好的诠释。也可以看看 2000 7 月 PODC 上 Brewer的原始幻灯片 。
在 2009 年 6 月在 SFO 的 NoSQL 见面会的幻灯片 。这些资料可以用经典的、关键的、将影响巨大的、值得纪念的来形容。
SQL Databases Don’t Scale 是一篇简短、基础、直切问题的文章。除非您是一位在伸缩性问题 上身经百战的数据库管理员,否则,这篇文章讲述的内容对于您可能是非常关键的。
Jonathan Ellis 的文章 NoSQL Ecosystem 以表格的方式对当今主流的分布式数据库 做了比较。类似的比较还有 Quick Reference to Alternative data storages 。Ellis 的文章除了表格对比外对于想了解 NoSQL 生态的人来说是非常值得一读的,该文章内涵丰富,短小精悍;而 Quick Reference to Alternative data storages 主要是表格,这些表格对比的内容又比 Ellis 的完整。
相关国外资源
    http://nosql-databases.org —— 该站点的标语是:“非关系型世界的终结向导!”,该站点非常确信自己是:“在互联网上拥有 NoSQL 相关链接最多的网站。”总之,该网站值得关注。
     另外,作为 NoSQL 极客(geeks),请 follow @nosqlupdate 。另外,请 follow @al3xandru (MyNoSQL blog 与 NoSQL Week in Review 的创建者)。NoSQL Week in Review 比较新,希望能保持正常更新,因为它确实很棒!
     当然,您还可以看看 Ricky Ho 最近的博文,他总结了一些分布式数据存储技术关键点。他的博文中有两篇非常值得一看的文章:Query Processing for NoSQL Databases ,还有 NoSQL Design Patterns 。

相关国内资源
Tim[后端技术] :分布式 Key Value Store 漫谈
CSDN 新闻频道 :豆瓣开源 Key Value 存储系统 BeansDB
robbin的自言自语 :NoSQL数据库探讨之一
J道 BanQ :CAP 原理和 BASE 思想

来源:NoSQL Required Reading ,Wikipedia – NoSQL
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/DL88250/archive/2010/01/14/5191092.aspx

为mysql数据库建立索引

就象许多的PHP开发者一样,在刚开始建立动态网站的时候,我都是使用相对简单 的数据结构。PHP在连接数据库方面的确实是十分方便(译者注:有些人认为PHP在连接不同数据库时没有一个统一的接口,不太方便,其实这可以通过一些扩 展库来做到这一点),你无需看大量的设计文档就可以建立和使用数据库,这也是PHP获得成功的主要原因之一。

前些时候,一位颇高级 的程序员居然问我什么叫做索引,令我感到十分的惊奇,我想这绝不会是沧海一粟,因为有成千上万的开发者(可能大部分是使用MySQL的)都没有受过有关数 据库的正规培训,尽管他们都为客户做过一些开发,但却对如何为数据库建立适当的索引所知较少,因此我起了写一篇相关文章的念头。

最普通的情况,是为出现在where子句的字段建一个索引。为方便讲述,我们先建立一个如下的表。

Code代码如下:
CREATE TABLE mytable (
id serial primary key,
category_id int not null default 0,
user_id int not null default 0,
adddate int not null default 0
);

很简单吧,不过对于要说明这个问题,已经足够了。如果你在查询时常用类似以下的语句:

SELECT * FROM mytable WHERE category_id=1;

最直接的应对之道,是为category_id建立一个简单的索引:

CREATE INDEX mytable_categoryid
ON mytable (category_id);

OK,搞定?先别高兴,如果你有不止一个选择条件呢?例如:

SELECT * FROM mytable WHERE category_id=1 AND user_id=2;

你的第一反应可能是,再给user_id建立一个索引。不好,这不是一个最佳的方法。你可以建立多重的索引。

CREATE INDEX mytable_categoryid_userid ON mytable (category_id,user_id);

注意到我在命名时的习惯了吗?我使用”表名_字段1名_字段2名”的方式。你很快就会知道我为什么这样做了。

现在你已经为适当的字段建立了索引,不过,还是有点不放心吧,你可能会问,数据库会真正用到这些索引吗?测试一下就OK,对于大多数的数据库来说,这是很容易的,只要使用EXPLAIN命令:

EXPLAIN

SELECT * FROM mytable
WHERE category_id=1 AND user_id=2;

This is what Postgres 7.1 returns (exactly as I expected)

NOTICE: QUERY PLAN:

Index Scan using mytable_categoryid_userid on
mytable (cost=0.00..2.02 rows=1 width=16)

EXPLAIN

以上是postgres的数据,可以看到该数据库在查询的时候使用了一个索引(一个好开始),而且它使用的是我创建的第二个索引。看到我上面命名的好处了吧,你马上知道它使用适当的索引了。

接着,来个稍微复杂一点的,如果有个ORDER BY字句呢?不管你信不信,大多数的数据库在使用order by的时候,都将会从索引中受益。

SELECT * FROM mytable
WHERE category_id=1 AND user_id=2
ORDER BY adddate DESC;

有点迷惑了吧?很简单,就象为where字句中的字段建立一个索引一样,也为ORDER BY的字句中的字段建立一个索引:

CREATE INDEX mytable_categoryid_userid_adddate
ON mytable (category_id,user_id,adddate);

注意: ”mytable_categoryid_userid_adddate” 将会被截短为

“mytable_categoryid_userid_addda”

CREATE

EXPLAIN SELECT * FROM mytable
WHERE category_id=1 AND user_id=2
ORDER BY adddate DESC;

NOTICE: QUERY PLAN:

Sort (cost=2.03..2.03 rows=1 width=16)
-> Index Scan using mytable_categoryid_userid_addda
on mytable (cost=0.00..2.02 rows=1 width=16)

EXPLAIN

看看EXPLAIN的输出,好象有点恐怖啊,数据库多做了一个我们没有要求的排序,这下知道性能如何受损了吧,看来我们对于数据库的自身运作是有点过于乐观了,那么,给数据库多一点提示吧。

为 了跳过排序这一步,我们并不需要其它另外的索引,只要将查询语句稍微改一下。这里用的是postgres,我们将给该数据库一个额外的提示–在 ORDER BY语句中,加入where语句中的字段。这只是一个技术上的处理,并不是必须的,因为实际上在另外两个字段上,并不会有任何的排序操作,不 过如果加入,postgres将会知道哪些是它应该做的。

EXPLAIN SELECT * FROM mytable
WHERE category_id=1 AND user_id=2
ORDER BY category_id DESC,user_id DESC,adddate DESC;

NOTICE: QUERY PLAN:

Index Scan Backward using
mytable_categoryid_userid_addda on mytable
(cost=0.00..2.02 rows=1 width=16)

EXPLAIN

现在使用我们料想的索引了,而且它还挺聪明,知道可以从索引后面开始读,从而避免了任何的排序。

以 上说得细了一点,不过如果你的数据库非常巨大,并且每日的页面请求达上百万算,我想你会获益良多的。不过,如果你要做更为复杂的查询呢,例如将多张表结合 起来查询,特别是where限制字句中的字段是来自不止一个表格时,应该怎样处理呢?我通常都尽量避免这种做法,因为这样数据库要将各个表中的东西都结合 起来,然后再排除那些不合适的行,搞不好开销会很大。

如果不能避免,你应该查看每张要结合起来的表,并且使用以上的策略来建立索引,然后再用EXPLAIN命令验证一下是否使用了你料想中的索引。如果是的话,就OK。不是的话,你可能要建立临时的表来将他们结合在一起,并且使用适当的索引。

要注意的是,建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件。对于一个经常需要更新和插入的表格,就没有必要为一个很少使用的where字句单独建立索引了,对于比较小的表,排序的开销不会很大,也没有必要建立另外的索引。

以 上介绍的只是一些十分基本的东西,其实里面的学问也不少,单凭EXPLAIN我们是不能判定该方法是否就是最优化的,每个数据库都有自己的一些优化器,虽 然可能还不太完善,但是它们都会在查询时对比过哪种方式较快,在某些情况下,建立索引的话也未必会快,例如索引放在一个不连续的存储空间时,这会增加读磁 盘的负担,因此,哪个是最优,应该通过实际的使用环境来检验。

在刚开始的时候,如果表不大,没有必要作索引,我的意见是在需要的时候才作索引,也可用一些命令来优化表,例如MySQL可用”OPTIMIZE TABLE”。

综上所述,在如何为数据库建立恰当的索引方面,你应该有一些基本的概念了。

Powered by WordPress | Theme: Motion by 85ideas.