HTML <form> 标签的 accept-charset 属性定义和用法accept-charset 属性规定服务器处理表单数据所接受的字符集。
accept-charset 属性允许您指定一系列字符集,服务器必须支持这些字符集,从而得以正确解释表单中的数据。
该属性的值是用引号包含字符集名称列表。如果可接受字符集与用户所使用的字符即不相匹配的话,浏览器可以选择忽略表单或是将该表单区别对待。
此属性的默认值是 "unknown",表示表单的字符集与包含表单的文档的字符集相同。
提示:请避免使用该属性。应该在服务器端验证文件上传。
accept-charset
一个很少用到的表单属性,利用它实现在不同编码的页面里实现表单的提交也是一种很方便的解决方法。转自老王的baidu空间,记录在此。
作者:老王
问题背景:
两个应用编码不同,一个是GBK编码,另一个是UTF-8编码。现在要在GBK编码的应用里使用表单向UTF-8编码的应用里提交数据,很显然,如果不做特殊处理的话,会出现乱码。
解决方案:
当然了,可以自己使用ICONV或者MB扩展来转换编码,但这不是我们要的。
在W3里介绍了一个不太常见的属性:accept-charset,用它可以完成我们的需求。
在GBK编码的页面里编写如下代码:
<form method="post" action="..." accept-charset="utf-8">
...
</form>
如此的代码在Firefox等正常的浏览器下没有任何问题,但是遇到IE这个变态浏览器就不灵光了,我们还得用点不入流的手段Hack一下:
<form method="post" action="..." accept-charset="utf-8" onsubmit="document.charset='utf-8';">
...
</form>
剩下的工作浏览器会搞定。
参考:
http://www.w3school.com.cn/tags/att_form_accept_charset.asp
http://blog.zol.com.cn/795/article_794546.html
来源:http://gfeng.org/?m=201009
accept-charset 属性允许您指定一系列字符集,服务器必须支持这些字符集,从而得以正确解释表单中的数据。
该属性的值是用引号包含字符集名称列表。如果可接受字符集与用户所使用的字符即不相匹配的话,浏览器可以选择忽略表单或是将该表单区别对待。
此属性的默认值是 "unknown",表示表单的字符集与包含表单的文档的字符集相同。
提示:请避免使用该属性。应该在服务器端验证文件上传。
accept-charset
一个很少用到的表单属性,利用它实现在不同编码的页面里实现表单的提交也是一种很方便的解决方法。转自老王的baidu空间,记录在此。
作者:老王
问题背景:
两个应用编码不同,一个是GBK编码,另一个是UTF-8编码。现在要在GBK编码的应用里使用表单向UTF-8编码的应用里提交数据,很显然,如果不做特殊处理的话,会出现乱码。
解决方案:
当然了,可以自己使用ICONV或者MB扩展来转换编码,但这不是我们要的。
在W3里介绍了一个不太常见的属性:accept-charset,用它可以完成我们的需求。
在GBK编码的页面里编写如下代码:
<form method="post" action="..." accept-charset="utf-8">
...
</form>
如此的代码在Firefox等正常的浏览器下没有任何问题,但是遇到IE这个变态浏览器就不灵光了,我们还得用点不入流的手段Hack一下:
<form method="post" action="..." accept-charset="utf-8" onsubmit="document.charset='utf-8';">
...
</form>
剩下的工作浏览器会搞定。
参考:
http://www.w3school.com.cn/tags/att_form_accept_charset.asp
http://blog.zol.com.cn/795/article_794546.html
来源:http://gfeng.org/?m=201009
file_get_contents() 函数
定义和用法
file_get_contents() 函数把整个文件读入一个字符串中。
和 file() 一样,不同的是 file_get_contents() 把文件读入一个字符串。
file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来增强性能。
语法
file_get_contents(path,include_path,context,start,max_length)参数 描述
path 必需。规定要读取的文件。
include_path 可选。如果也想在 include_path 中搜寻文件的话,可以将该参数设为 "1"。
context 可选。规定文件句柄的环境。
context 是一套可以修改流的行为的选项。若使用 null,则忽略。
start 可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 新加的。
max_length 可选。规定读取的字节数。该参数是 PHP 5.1 新加的。
说明
对 context 的支持是 PHP 5.0.0 添加的。
针对超时或页面过慢,一般可采取两个解决方案:
1. 利用file_get_contents()第三个参数
<?php
$url = "http://zhoz.com/zhoz.php";
$ctx = stream_context_create(array(
‘http’ => array(‘timeout’ => 10)
)
);
$result = @file_get_contents($url, 0, $ctx);
if($result){
var_dump($result);
}else{
echo " Buffer is empty";
}
?>
阅读全文
定义和用法
file_get_contents() 函数把整个文件读入一个字符串中。
和 file() 一样,不同的是 file_get_contents() 把文件读入一个字符串。
file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来增强性能。
语法
file_get_contents(path,include_path,context,start,max_length)参数 描述
path 必需。规定要读取的文件。
include_path 可选。如果也想在 include_path 中搜寻文件的话,可以将该参数设为 "1"。
context 可选。规定文件句柄的环境。
context 是一套可以修改流的行为的选项。若使用 null,则忽略。
start 可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 新加的。
max_length 可选。规定读取的字节数。该参数是 PHP 5.1 新加的。
说明
对 context 的支持是 PHP 5.0.0 添加的。
针对超时或页面过慢,一般可采取两个解决方案:
1. 利用file_get_contents()第三个参数
<?php
$url = "http://zhoz.com/zhoz.php";
$ctx = stream_context_create(array(
‘http’ => array(‘timeout’ => 10)
)
);
$result = @file_get_contents($url, 0, $ctx);
if($result){
var_dump($result);
}else{
echo " Buffer is empty";
}
?>
阅读全文
http://gfeng.org/?p=147
在PHP中用exec()或popen()函数将一个shell命令行推到后台去.
PHP执行Shell命令发现popen好像是异步执行的,奶奶的。。奇怪了。。关注下
在PHP中用exec()或popen()函数将一个shell命令行推到后台去.
PHP执行Shell命令发现popen好像是异步执行的,奶奶的。。奇怪了。。关注下
今天,在写shell的时候,需要读取一个sh文件的内容,然后给予拼接字符串后执行这个字符串,出现换行的情况,于是,经过苦心查找,原来是读取vi编辑文件的后面有换行符,通过php的trim对其做了处理,OK,以前一直没有注意,原来Linux的vi一直都在干这个事情,哈哈哈,特别写下这个记录!
----------------------------------------------------------------------------------------------------------------------------------------------------
Linux下vi一个jackxiang.txt,然后,sz下来,用编辑器:FlexHEX.ext打开Jackxiang.txt,换行符的查看:
换行符(\n) 相当于ASCII 换行字符(十六进制0A),
因此,在文本模式下打开的文件作为新行字符读入CR/LF 对,并且作为CR/LF 写入新行字符。
原来是vi编辑器自己在行尾加了个\n换行符。用od命令可看的很清楚:od -A d -t c jackxiang.txt
PHP用trim去掉换行符,即可! "\n" (ASCII 10 (0x0A)), a new line (line feed).
阅读全文
----------------------------------------------------------------------------------------------------------------------------------------------------
Linux下vi一个jackxiang.txt,然后,sz下来,用编辑器:FlexHEX.ext打开Jackxiang.txt,换行符的查看:
16进制:6A 61 63 6B 78 69 61 6E 67 0A
原文:jackxiang
原文:jackxiang
换行符(\n) 相当于ASCII 换行字符(十六进制0A),
因此,在文本模式下打开的文件作为新行字符读入CR/LF 对,并且作为CR/LF 写入新行字符。
原来是vi编辑器自己在行尾加了个\n换行符。用od命令可看的很清楚:od -A d -t c jackxiang.txt
Onecent:/usr/local/tads/htdocs/*****_2010/bin # od -A d -t c jackxiang.txt
0000000 j a c k x i a n g \n
0000010
0000000 j a c k x i a n g \n
0000010
PHP用trim去掉换行符,即可! "\n" (ASCII 10 (0x0A)), a new line (line feed).
阅读全文
[个人原创]awk取得绝对路径和文件名拼接的方法
Php/Js/Shell/Go jackxiang 2010-9-21 17:19
原因很简单,需要某个目录下的shell文件同时推到后台执行:
引申:
结果如下:
TTTTT:/usr/local/tads/htdocs/*/data/20100920 #
导入到文件:
其实际在shell编程过程中,往往需要用到绝对地址的时候,就不用这个,如下:
路径已经在里面了!
awk -v var=$(pwd) 'BEGIN{print var}'
引申:
ls -lart GrepQQCommand_*|awk -v PWD=$PWD '{print PWD "/" $9}'
结果如下:
/usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_ak
/usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_bc
/usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_ef
/usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_bc
/usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_ef
TTTTT:/usr/local/tads/htdocs/*/data/20100920 #
ls -lart GrepQQCommand_*|awk -v PWD=$PWD '{print "nohup sh " PWD "/" $9 "&"}'
nohup sh /usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_ak&
nohup sh /usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_bc&
nohup sh /usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_ef&
nohup sh /usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_bc&
nohup sh /usr/local/tads/htdocs/*/data/20100920/GrepQQCommand_ef&
导入到文件:
s -lart GrepQQCommand_*|awk -v PWD=$PWD '{print "nohup sh " PWD "/" $9 "&"}' > ccc.sh
然后:sh ccc.sh即可。其实际在shell编程过程中,往往需要用到绝对地址的时候,就不用这个,如下:
ls -lart /usr/local/tads/htdocs/*****_2010/data/20100921/GrepQQCommand_*
-rwxrwxrwx 1 root users 284064 Sep 22 15:39 /usr/local/tads/htdocs/*****_2010/data/20100921/GrepQQCommand_aa
-rwxrwxrwx 1 root users 284064 Sep 22 15:39 /usr/local/tads/htdocs/*****_2010/data/20100921/GrepQQCommand_aa
路径已经在里面了!
cat CCC_ad |awk '{print '"$(date +"%Y%m%d%H%M%S")"',$1,$5,$6,$7,$8}'
cat CCC_ad |awk '{print strftime(), $1,$5,$6,$7,$8}'
now=$(date +%Y-%m-%d" "%H:%M:%S)
echo $now
echo $now
Math.round(Math.random()*10000)
alert(Math.round(Math.random()*10000))
使用如下:
var item = $("input:radio:checked");
var checkedvalue = item.val();
var fqq = $('#FVotedQQ').val();
var frominvite = $('#frominvite').val();
var random = Math.round(Math.random()*10000);
var getaward = $.ajax({
url: "http://***.act.***.com/c/vote/add",
data:"FVotedQQ="+fqq+"&kindid="+checkedvalue+"&frominvite="+frominvite+"random="+random,
async: false
}).responseText;
eval('var data = '+getaward);
alert(data.message);
split -l 5000 CCC.txt CCC_New.txt
[~/split]# ls
CCC_New.txtaa CCC_New.txtad CCC_New.txtag CCC_New.txtaj CCC_New.txtam CCC_New.txtap
CCC_New.txtab CCC_New.txtae CCC_New.txtah CCC_New.txtak CCC_New.txtan CCC_New.txtaq
CCC_New.txtac CCC_New.txtaf CCC_New.txtai CCC_New.txtal CCC_New.txtao CCC.txt
今天接到一个需求是提取5月访问某域名的所有用户号码,文件一存放访问域名下地址A的用户号码,剩余用户按照50万整数一个包为规则提取。
这个剩余用户按照50万一个包让人看着有点紧张,怎么提?难道要用rownum?
不要被蒙蔽!还是提成一个文件好了,用linux下的split一分就完事了。
怎么用?
这样写
split -l 500000 js_24875.csv new_js_24875.csv
split -l n
把infile拆分为n行的段,默认一个文件为1000行、、split --help
-l, --lines=NUMBER put NUMBER lines per output file
-l, --lines=NUMBER put NUMBER lines per output file
注意:
split: Output file suffixes exhausted 注意此处:split在提示我们说输出时的文件名后缀被用光了
[root@linux ~]# split [-bl] file PREFIX
参数:
-b :后面可接欲分割成的档案大小,可加单位,例如 b, k, m 等;
-l :以行数来进行分割。
范例:
范例一:我的 /etc/termcap 有七百多K,若想要分成 300K 一个档案时?
[root@linux ~]# cd /tmp; split -b 300k /etc/termcap termcap
[root@linux tmp]# ls -l termcap*
-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapaa
-rw-rw-r-- 1 root root 307200 8月 17 00:25 termcapab
-rw-rw-r-- 1 root root 184848 8月 17 00:25 termcapac
# 那个档名可以随意取的啦!我们只要写上前导文字,小档案就会以
# xxxaa, xxxab, xxxac 等方式来建立小档案的!
范例二:如何将上面的三个小档案合成一个档案,档名为 termcapback
[root@linux tmp]# cat termcap* >> termcapback
# 很简单吧?就用资料流重导向就好啦!简单!
一、 MySQL: 索引以B树格式保存
Memory存储引擎可以选择Hash或BTree索引,Hash索引只能用于=或<=>的等式比较。
1、普通索引:create index on Tablename(列的列表)
alter table TableName add index (列的列表)
create table TableName([...], index [IndexName] (列的列表)
2、唯一性索引:create unique index
alter ... add unique
主键:一种唯一性索引,必须指定为primary key
3、全文索引:从3.23.23版开始支持全文索引和全文检索,FULLTEXT,
可以在char、varchar或text类型的列上创建。
4、单列索引、多列索引:
多个单列索引与单个多列索引的查询效果不同,因为:
执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。
5、最左前缀(Leftmost Prefixing):多列索引,例如:fname_lname_age索引,以下的搜索条件MySQL都将使用
fname_lname_age索引:firstname,lastname,age;firstname,lastname;firstname,其他情况将不使用。
二、根据sql查询语句确定创建哪种类型的索引,如何优化查询
选择索引列:
a.性能优化过程中,选择在哪个列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有
两种类型的列:在where子句中出现的列,在join子句中出现的列。
b.考虑列中值的分布,索引的列的基数越大,索引的效果越好。
c.使用短索引,如果对字符串列进行索引,应该指定一个前缀长度,可节省大量索引空间,提升查询速度。
d.利用最左前缀
e.不要过度索引,只保持所需的索引。每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能。
在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,索引越多,所花的时间越长。
MySQL只对一下操作符才使用索引:<,<=,=,>,>=,between,in,
以及某些时候的like(不以通配符%或_开头的情形)。
来源:http://database.51cto.com/art/200905/122789.htm
Memory存储引擎可以选择Hash或BTree索引,Hash索引只能用于=或<=>的等式比较。
1、普通索引:create index on Tablename(列的列表)
alter table TableName add index (列的列表)
create table TableName([...], index [IndexName] (列的列表)
2、唯一性索引:create unique index
alter ... add unique
主键:一种唯一性索引,必须指定为primary key
3、全文索引:从3.23.23版开始支持全文索引和全文检索,FULLTEXT,
可以在char、varchar或text类型的列上创建。
4、单列索引、多列索引:
多个单列索引与单个多列索引的查询效果不同,因为:
执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。
5、最左前缀(Leftmost Prefixing):多列索引,例如:fname_lname_age索引,以下的搜索条件MySQL都将使用
fname_lname_age索引:firstname,lastname,age;firstname,lastname;firstname,其他情况将不使用。
二、根据sql查询语句确定创建哪种类型的索引,如何优化查询
选择索引列:
a.性能优化过程中,选择在哪个列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有
两种类型的列:在where子句中出现的列,在join子句中出现的列。
b.考虑列中值的分布,索引的列的基数越大,索引的效果越好。
c.使用短索引,如果对字符串列进行索引,应该指定一个前缀长度,可节省大量索引空间,提升查询速度。
d.利用最左前缀
e.不要过度索引,只保持所需的索引。每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能。
在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,索引越多,所花的时间越长。
MySQL只对一下操作符才使用索引:<,<=,=,>,>=,between,in,
以及某些时候的like(不以通配符%或_开头的情形)。
来源:http://database.51cto.com/art/200905/122789.htm
InnoDB存储引擎将InnoDB表保存在一个表空间内,该表空间可由数个文件创建。这样,表的大小就能超过单独文件的最大容量。表空间可包括原始磁盘分区,从而使得很大的表成为可能。表空间的最大容量为64TB。
MySQL表最大能达到多少:
事实上MySQL能承受的数据量的多少主要和数据表的结构有关,并不是一个固定的数值。表的结构简单,则能承受的数据量相对比结构复杂时大些。
据D.V.B团队以及Cmshelp团队做CMS系统评测时的结果看来,MySQL单表一般在2千万条记录(4G)下能够良好运行,经过数据库的优化后5千万条记录(10G)下运行良好。
那些CMS厂商非但没有把内核做好反而还在添加很多花哨的功能,最终导致其产品自身负载过低。他们并没有针对自身负载效果作出相应的数据库优化方案及标准,而是继续保留着复杂的结构造成对MySQL的资源无休止的浪费,最终导致了其负载上的缺陷,于是他们便充分发挥中国人的传统优势——变通:避重就轻的采用了所谓的分表式存储,虽然在一定程度上缓解了自身负载的缺陷,但是导致了网站后期维护以及资源上的浪费,这样做是否是长久之计呢?虽然他们解决了眼前的问题,但以后呢?难道想无休止的分表来达到目的?MYLB.NET.CN博主追峰用一个不恰当的比喻来形容,MySQL中的的表就像一块地,单表就相当于利用这块地盖高层建筑充分利用达到高人员负载,但分表就相当于用这块地盖了一间平房,如果为了达到高人员负载的话那就需要另开地皮达到目的,但是我们要思考,是地不够,还是他的能力不够,如此做法让人感到资源的浪费以及规划的严重缺陷。那么对于这样的CMS系统,有谁敢用?难道为了达到让其良好的运行而无休止的更换着服务器配置么?况且大多情况下一台服务器中不是只有这么一个网站,那么我们就要思考,我们的腰包是否是为了满足这么庞大的小CMS而生。
InnoDB还是MyISAM 再谈MySQL存储引擎的选择
两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁.而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用。
我作为使用MySQL的用户角度出发,Innodb和MyISAM都是比较喜欢的,但是从我目前运维的数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,MyISAM绝对是我的首选。
原因如下:
1、首先我目前平台上承载的大部分项目是读多写少的项目,而MyISAM的读性能是比Innodb强不少的。
2、MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。
3、从平台角度来说,经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对,导致这个表没法正常用了,这个时候 MyISAM的优越性就体现出来了,随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的 binlog补上。如果是Innodb,恐怕不可能有这么快速度,别和我说让Innodb定期用导出xxx.sql机制备份,因为我平台上最小的一个数据库实例的数据量基本都是几十G大小。
4、从我接触的应用逻辑来说,select count(*) 和order by 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁表的,很多人以为Innodb是行级锁,那个只是 where对它主键是有效,非主键的都会锁全表的。
5、还有就是经常有很多应用部门需要我给他们定期某些表的数据,MyISAM的话很方便,只要发给他们对应那表的frm.MYD,MYI的文件,让他们自己在对应版本的数据库启动就行,而Innodb就需要导出xxx.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。
6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然 MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决。
7、如果是用MyISAM的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge表做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表。
当然Innodb也不是绝对不用,用事务的项目如模拟炒股项目,我就是用Innodb的,活跃用户20多万时候,也是很轻松应付了,因此我个人也是很喜欢Innodb的,只是如果从数据库平台应用出发,我还是会首选MyISAM。
另外,可能有人会说你MyISAM无法抗太多写操作,但是我可以通过架构来弥补,说个我现有用的数据库平台容量:主从数据总量在几百T以上,每天十多亿 pv的动态页面,还有几个大项目是通过数据接口方式调用未算进pv总数,(其中包括一个大项目因为初期memcached没部署,导致单台数据库每天处理 9千万的查询)。而我的整体数据库服务器平均负载都在0.5-1左右。
mysql的merge引擎引发的性能问题:
MERGE引擎类型可以把许多结构相同的表合并为一个表。通过对merge表的简单查询,可以轻松实现对多个子表进行查询的目的。
我们的日志系统按照月为单位进行分表,由merge联合所有月份子表,实现跨月(跨表)的日志查询。这样的做法是程序端的逻辑比较简单,无需关注多表的数据整合和处理。
随着子表越来越多、数据越来越大,查询的速度越来越慢。子表的数据量增长并非数量级的,那么从理论上讲通过merge进行查询,速度受到影响的浮动应该是很小的,但现实却非如此。
刚开始并不知道原因,通过profiling检查详细的耗时情况,发现Sending data占用了99%的时间,从官方解释来看,Sending data貌似是发送数据到client端的耗时,检查了一下,仅仅只有几K的数据发送,明显不是此原因。SQL挺简单的,基本的优化也都做了,那么是什么原因?
之后调试代码时无意中针对一个子表进行了一次查询,发现速度几十倍的提高,之前对merge的查询需要20多秒,现在仅仅不到1秒就执行完了,这个感觉是很明显的,于是进一步进行了测试,发现问题的确如此。
所以,建议还是在代码逻辑中对多表数据进行处理,避免使用Merge引擎。
有时间看一下源码中Sending data是如何计算的以及Merge是如何进行多表数据集合的。 希望Mysql能把Merge引擎做的更加稳定、高效,真正发挥Merge引擎的优势。
MySQL表最大能达到多少:
事实上MySQL能承受的数据量的多少主要和数据表的结构有关,并不是一个固定的数值。表的结构简单,则能承受的数据量相对比结构复杂时大些。
据D.V.B团队以及Cmshelp团队做CMS系统评测时的结果看来,MySQL单表一般在2千万条记录(4G)下能够良好运行,经过数据库的优化后5千万条记录(10G)下运行良好。
那些CMS厂商非但没有把内核做好反而还在添加很多花哨的功能,最终导致其产品自身负载过低。他们并没有针对自身负载效果作出相应的数据库优化方案及标准,而是继续保留着复杂的结构造成对MySQL的资源无休止的浪费,最终导致了其负载上的缺陷,于是他们便充分发挥中国人的传统优势——变通:避重就轻的采用了所谓的分表式存储,虽然在一定程度上缓解了自身负载的缺陷,但是导致了网站后期维护以及资源上的浪费,这样做是否是长久之计呢?虽然他们解决了眼前的问题,但以后呢?难道想无休止的分表来达到目的?MYLB.NET.CN博主追峰用一个不恰当的比喻来形容,MySQL中的的表就像一块地,单表就相当于利用这块地盖高层建筑充分利用达到高人员负载,但分表就相当于用这块地盖了一间平房,如果为了达到高人员负载的话那就需要另开地皮达到目的,但是我们要思考,是地不够,还是他的能力不够,如此做法让人感到资源的浪费以及规划的严重缺陷。那么对于这样的CMS系统,有谁敢用?难道为了达到让其良好的运行而无休止的更换着服务器配置么?况且大多情况下一台服务器中不是只有这么一个网站,那么我们就要思考,我们的腰包是否是为了满足这么庞大的小CMS而生。
InnoDB还是MyISAM 再谈MySQL存储引擎的选择
两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁.而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用。
我作为使用MySQL的用户角度出发,Innodb和MyISAM都是比较喜欢的,但是从我目前运维的数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,MyISAM绝对是我的首选。
原因如下:
1、首先我目前平台上承载的大部分项目是读多写少的项目,而MyISAM的读性能是比Innodb强不少的。
2、MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。
3、从平台角度来说,经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对,导致这个表没法正常用了,这个时候 MyISAM的优越性就体现出来了,随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的 binlog补上。如果是Innodb,恐怕不可能有这么快速度,别和我说让Innodb定期用导出xxx.sql机制备份,因为我平台上最小的一个数据库实例的数据量基本都是几十G大小。
4、从我接触的应用逻辑来说,select count(*) 和order by 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁表的,很多人以为Innodb是行级锁,那个只是 where对它主键是有效,非主键的都会锁全表的。
5、还有就是经常有很多应用部门需要我给他们定期某些表的数据,MyISAM的话很方便,只要发给他们对应那表的frm.MYD,MYI的文件,让他们自己在对应版本的数据库启动就行,而Innodb就需要导出xxx.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。
6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然 MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决。
7、如果是用MyISAM的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge表做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表。
当然Innodb也不是绝对不用,用事务的项目如模拟炒股项目,我就是用Innodb的,活跃用户20多万时候,也是很轻松应付了,因此我个人也是很喜欢Innodb的,只是如果从数据库平台应用出发,我还是会首选MyISAM。
另外,可能有人会说你MyISAM无法抗太多写操作,但是我可以通过架构来弥补,说个我现有用的数据库平台容量:主从数据总量在几百T以上,每天十多亿 pv的动态页面,还有几个大项目是通过数据接口方式调用未算进pv总数,(其中包括一个大项目因为初期memcached没部署,导致单台数据库每天处理 9千万的查询)。而我的整体数据库服务器平均负载都在0.5-1左右。
mysql的merge引擎引发的性能问题:
MERGE引擎类型可以把许多结构相同的表合并为一个表。通过对merge表的简单查询,可以轻松实现对多个子表进行查询的目的。
我们的日志系统按照月为单位进行分表,由merge联合所有月份子表,实现跨月(跨表)的日志查询。这样的做法是程序端的逻辑比较简单,无需关注多表的数据整合和处理。
随着子表越来越多、数据越来越大,查询的速度越来越慢。子表的数据量增长并非数量级的,那么从理论上讲通过merge进行查询,速度受到影响的浮动应该是很小的,但现实却非如此。
刚开始并不知道原因,通过profiling检查详细的耗时情况,发现Sending data占用了99%的时间,从官方解释来看,Sending data貌似是发送数据到client端的耗时,检查了一下,仅仅只有几K的数据发送,明显不是此原因。SQL挺简单的,基本的优化也都做了,那么是什么原因?
之后调试代码时无意中针对一个子表进行了一次查询,发现速度几十倍的提高,之前对merge的查询需要20多秒,现在仅仅不到1秒就执行完了,这个感觉是很明显的,于是进一步进行了测试,发现问题的确如此。
所以,建议还是在代码逻辑中对多表数据进行处理,避免使用Merge引擎。
有时间看一下源码中Sending data是如何计算的以及Merge是如何进行多表数据集合的。 希望Mysql能把Merge引擎做的更加稳定、高效,真正发挥Merge引擎的优势。
删除多余的空格
行末:$
行首:^
空格:\s
行末空格:\s\+$
行首空格:^\+\s
有些人认为行末的空格是无用,浪费而难看的。要删除这些每行后面多余的空格,可以
执行如下命令:
:%s/\s\+$//
命令前面指明范围是 "%",所以这会作用于整个文件。"substitute" 命令的匹配模式是
"\s\+$"。这表示行末($)前的一个或者多个(\+)空格(\s)。后面我们会介绍怎样
写这样的模式。|usr_27.txt|。
替换命令的 "to" 部分是空的:"//"。这样就会删除那些匹配的空白字符。
另一种没有用的空格是 Tab 前面的字符。通常这可以删除而不影响格式。但并不是总这
样!所以,你最好手工删除它。执行如下命令:
/
你什么都看不见,其实这是一个空格加一个 TAB 键。相当于 "/<Space><Tab>"。现在,
你可以用 "x" 删除多余的空格,并保证格式没有改变。接着你可以用 "n" 找到下一个
位置并重复这个操作。
来源:http://www.cublog.cn/u2/63696/showart_506107.html
行末:$
行首:^
空格:\s
行末空格:\s\+$
行首空格:^\+\s
有些人认为行末的空格是无用,浪费而难看的。要删除这些每行后面多余的空格,可以
执行如下命令:
:%s/\s\+$//
命令前面指明范围是 "%",所以这会作用于整个文件。"substitute" 命令的匹配模式是
"\s\+$"。这表示行末($)前的一个或者多个(\+)空格(\s)。后面我们会介绍怎样
写这样的模式。|usr_27.txt|。
替换命令的 "to" 部分是空的:"//"。这样就会删除那些匹配的空白字符。
另一种没有用的空格是 Tab 前面的字符。通常这可以删除而不影响格式。但并不是总这
样!所以,你最好手工删除它。执行如下命令:
/
你什么都看不见,其实这是一个空格加一个 TAB 键。相当于 "/<Space><Tab>"。现在,
你可以用 "x" 删除多余的空格,并保证格式没有改变。接着你可以用 "n" 找到下一个
位置并重复这个操作。
来源:http://www.cublog.cn/u2/63696/showart_506107.html
int *p[3] p是一个数组,此数组有3个元素,每个元素都是int*类型,也就是指向整型数据的指针类型。
int a=10,b=20,c=30;
int*p[3]={&a,&b,&c};
而int(*p)[3]中的p是一个指向数组的指针,此数组有3个int类型的元素。例如:
int a[3]={1,2,3}; 那么p就是指向这个数组a的指针。
int(*p)[3]=&a; // 这里赋值一定要用取地址符号。也就是取数组a的地址。
不可以这样赋值: int(*p)[3]=a; // error :类型不兼容。a本来是数组类型,是不可以赋值给int(*)[3]这个类型的。
但是这样是可以的int *p1=a; // ok 因为a可以隐式转换为int*类型,其值实际上就是数组第一个元素的地址,也就是&a[0]
*p[3] 这个是一个指针数组 它所代表的意思是每一个元素都相当于一个指针变量
而(*p)[3] p是一个指针变量,表示指向含有3个整型元素的一维数组
前者可以类似于二维数组 把它看成是由3个一维数组组成的 经常与字符串搭配使用 比较方便操作 把多个字符串放在一个指针数组中
后者是用来引用二维数组的 像a[2][3]这个二维数组 我们既可用指针来引用 又可用(*p)[3]来引用 一般使用(*p)[3
来源:http://zhidao.baidu.com/question/128144862.html
int a=10,b=20,c=30;
int*p[3]={&a,&b,&c};
而int(*p)[3]中的p是一个指向数组的指针,此数组有3个int类型的元素。例如:
int a[3]={1,2,3}; 那么p就是指向这个数组a的指针。
int(*p)[3]=&a; // 这里赋值一定要用取地址符号。也就是取数组a的地址。
不可以这样赋值: int(*p)[3]=a; // error :类型不兼容。a本来是数组类型,是不可以赋值给int(*)[3]这个类型的。
但是这样是可以的int *p1=a; // ok 因为a可以隐式转换为int*类型,其值实际上就是数组第一个元素的地址,也就是&a[0]
*p[3] 这个是一个指针数组 它所代表的意思是每一个元素都相当于一个指针变量
而(*p)[3] p是一个指针变量,表示指向含有3个整型元素的一维数组
前者可以类似于二维数组 把它看成是由3个一维数组组成的 经常与字符串搭配使用 比较方便操作 把多个字符串放在一个指针数组中
后者是用来引用二维数组的 像a[2][3]这个二维数组 我们既可用指针来引用 又可用(*p)[3]来引用 一般使用(*p)[3
#include <iostream.h>
int main()
{ int i,j;
int a[2][3]={3,4,5,6,7,8};
int *p[3] ;//表示存贮是3个整型变量地址;
int (*q)[3]; //表示指向3个整型数组元素的一维数组指针
//把第一行三个元素地址存放在p指针数组中
for( i=0;i<3;++i)
p[i]=&a[0][i];
//输出指针数组中地址所对应值
for( j=0;j<3;++j)
cout<< *p[j]<<" ";
cout<<endl;
q=a;//把数组a开始地址赋给指向一维数组q;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
cout<< *(*(q+i)+j)<<" "; //输出数组中元素
return 0;
}
int main()
{ int i,j;
int a[2][3]={3,4,5,6,7,8};
int *p[3] ;//表示存贮是3个整型变量地址;
int (*q)[3]; //表示指向3个整型数组元素的一维数组指针
//把第一行三个元素地址存放在p指针数组中
for( i=0;i<3;++i)
p[i]=&a[0][i];
//输出指针数组中地址所对应值
for( j=0;j<3;++j)
cout<< *p[j]<<" ";
cout<<endl;
q=a;//把数组a开始地址赋给指向一维数组q;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
cout<< *(*(q+i)+j)<<" "; //输出数组中元素
return 0;
}
来源:http://zhidao.baidu.com/question/128144862.html
最近awk用得比较多,于是简简单单记录一下。
awk非常的优秀,运行效率高,而且代码简单,对格式化的文本处理能力超强。基本上grep和sed能干的活awk全部都能干,而且干得更好。
先来一个很爽的例子:
文件a,统计文件a的第一列中是浮点数的行的浮点数的平均值。用awk来实现只需要一句话就可以搞定(当然,这个东东用python也可以很轻松的实现,只是无论如何都得新建一个文件;别妄想用bash shell来做,那可是浮点数!!!)
$cat a
1.021 33
1#.ll 44
2.53 6
ss 7
awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a
niubility!
awk非常的优秀,运行效率高,而且代码简单,对格式化的文本处理能力超强。基本上grep和sed能干的活awk全部都能干,而且干得更好。
先来一个很爽的例子:
文件a,统计文件a的第一列中是浮点数的行的浮点数的平均值。用awk来实现只需要一句话就可以搞定(当然,这个东东用python也可以很轻松的实现,只是无论如何都得新建一个文件;别妄想用bash shell来做,那可是浮点数!!!)
$cat a
1.021 33
1#.ll 44
2.53 6
ss 7
awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a
niubility!
[/diff]# awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a
1.7755
1.7755
string fgets ( int $handle [, int $length ] )
从 handle 指向的文件中读取一行并返回长度最多为 length - 1 字节的字符串。碰到换行符(包括在返回值中)、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。如果没有指定 length ,则默认为 1K,或者说 1024 字节。
bool feof ( resource $handle )
果传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
先上代码,正确的写法:
指针位置文件:line_number_mark.txt,需要读取N行的大文件:onlyQQFilteredByJack.txt
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists('line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "pointer_num=".$num."\n";
$fp = fopen('./onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
$i = 0;
while($i < $insert_num)
{
if(!feof($fp))
{
$data = fgets($fp);
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}else
{
echo "out of the file's bindery,exit the while loop..\n";
$position = ftell($fp);
$flag = 1;//set flag means it's already end
break;//Break 退出循环
}
}
if($flag)
file_put_contents($rootPath . 'line_number_mark.txt', $position);
else
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>
指针的越位,错误的写法:
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists($rootPath . 'line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "num=".$num."\n";
$fp = fopen($rootPath . 'onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
echo ftell($fp)."\n";
if(feof($fp))
{
echo "Out of the file's bond\n";
exit();
}
$i = 0;
while($i < $insert_num)
{
$data = fgets($fp);//没fget一次,指针自动加一,后面ftell的值也是加一后的值,而在while下造成了越界,下次在来读取后在上面的if(feof($fp))出现传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}
echo ftell($fp)."\n";
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>
阅读全文
从 handle 指向的文件中读取一行并返回长度最多为 length - 1 字节的字符串。碰到换行符(包括在返回值中)、EOF 或者已经读取了 length - 1 字节后停止(看先碰到那一种情况)。如果没有指定 length ,则默认为 1K,或者说 1024 字节。
bool feof ( resource $handle )
果传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
先上代码,正确的写法:
指针位置文件:line_number_mark.txt,需要读取N行的大文件:onlyQQFilteredByJack.txt
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists('line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "pointer_num=".$num."\n";
$fp = fopen('./onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
$i = 0;
while($i < $insert_num)
{
if(!feof($fp))
{
$data = fgets($fp);
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}else
{
echo "out of the file's bindery,exit the while loop..\n";
$position = ftell($fp);
$flag = 1;//set flag means it's already end
break;//Break 退出循环
}
}
if($flag)
file_put_contents($rootPath . 'line_number_mark.txt', $position);
else
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>
指针的越位,错误的写法:
<?php
$num = 0;
$insert_num = 10; //insert amount every time.
if(file_exists($rootPath . 'line_number_mark.txt'))
{
$num = trim(file_get_contents($rootPath . 'line_number_mark.txt'));
}
echo "num=".$num."\n";
$fp = fopen($rootPath . 'onlyQQFilteredByJack.txt', 'r');
fseek($fp, $num);
echo ftell($fp)."\n";
if(feof($fp))
{
echo "Out of the file's bond\n";
exit();
}
$i = 0;
while($i < $insert_num)
{
$data = fgets($fp);//没fget一次,指针自动加一,后面ftell的值也是加一后的值,而在while下造成了越界,下次在来读取后在上面的if(feof($fp))出现传递的文件指针无效可能会陷入无限循环中,因为 EOF 不会返回 TRUE。
$value = trim($data);
if(!empty($value))
{
$i++;
echo $value."\n";
}
}
echo ftell($fp)."\n";
file_put_contents($rootPath . 'line_number_mark.txt', ftell($fp));
?>
阅读全文