2012 年 08 月

浏览模式: 标准 | 列表 | 图文
mongodb删除索引

mongodb删除索引

在讲今天的内容前,请允许我说几句:what the fuck,再说一句:“你哭著對我說童話裡都是騙人的”
前两天说过为了速度我建了索引,虽然给id建了unique的索引,但是数据还是不由分说的插了重复的。好吧。因为数据在unique前就进数据库了。所以。。。我必须要再加上dropDups这个条件。

于是乎,我就先开始删除索引,然后灾难就来了:

b.archive.dropIndex({id:1,unique:true})
{ "errmsg" : "index not found", "ok" : 0 }
> db.archive.dropIndex({"id":1,"unique":true})
{ "errmsg" : "index not found", "ok" : 0 }
> db.archive.dropIndex({"id":1,"unique":true},{name:"id"})
{ "errmsg" : "index not found", "ok" : 0 }
> db.archive.dropIndex({"id":1,"unique":true},{"name":"id"})
{ "errmsg" : "index not found", "ok" : 0 }
> db.archive.dropIndex({category_id:1})
{ "errmsg" : "index not found", "ok" : 0 }
> db.archive.dropIndex({"category_id":1})
{ "errmsg" : "index not found", "ok" : 0 }
> db.archive.dropIndex({"key":{"status":1}})
{ "errmsg" : "index not found", "ok" : 0 }

为什么为什么????
为什么我会这么做?是因为:http://www.mongodb.org/display/DOCS/Indexes
这里面写着:

Dropping Indexes

To delete all indexes on the specified collection:

db.collection.dropIndexes();

To delete a single index:

db.collection.dropIndex({x: 1, y: -1})

Running directly as a command without helper:

// note: command was "deleteIndexes", not "dropIndexes", before MongoDB v1.3.2 // remove index with key pattern {y:1} from collection foo db.runCommand({dropIndexes:'foo', index : {y:1}}) // remove all indexes: db.runCommand({dropIndexes:'foo', index : '*'})

我晕啊。这是肿么了。。。
后来还是神仙和赵拂衣说了一句,试一下dropIndex("xxx"),果然。。。Over了。你说,你这不是忽悠人嘛 ,为了这个,我折腾了一个晚上啊。。。。
害得我当时只能dropIndexes,先删除所有的,再重建索引。。。数据又多,我等了好久好久啊。

mongodb用索引与不用索引的区别(续)

mongodb用索引与不用索引的区别(续)

前段时候做了个一万条数据的对比,这回做了个2000000条数据的对比:
测试方式还是和以前一样:

测试开始:
1、order by id ASC limit 25,很常见的查询吧。每页显示25条。
没有索引的时候:0.05秒左右(1万条是0.88秒,很奇怪)
用了id,unique索引后,0.004,第一次的时候0.08,后面稳定在0.00x左右(与1W左右一致)

2、where category_id = 1 limit 25,某个条件
无索引时:24秒左右 (很夸张。。。)
有索引:第一次0.06左右,后面稳定在0.00x(x>6),即在0.006~0.01之间(与1W左右一致)

3、where category_id = xx order by pubdate limit 25
无索引:20秒左右,最慢的一次达到了70秒
有索引的时候,与条件2差不多。。

虽然不是特别的深入测试,但这样也几乎足够了。不过,这带来另一个问题。内存消耗比较大啊。果然是吃内存大户

php header 设置Cache

php header 设置Cache

在手册里,关于header函数的说明是说服务端会输出一系列的头,用firebug也可以看得很清楚
一般来说,我们用header控制的情况不是特别多,毕竟不会主动去改什么:一般也就设置设置编码、跳转、压缩等,不太会过多的干涉。下载的时候也会设置头,黑黑

手册上,我们对于cache都是写着如何设置,以便让代码不被cache:


header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Pragma: no-cache"); // Date in the past

而且在设置的时候还得注意在header前不能有输出,否则header设置无效,但都没有写过,如何给页面设置Cache,虽然我们知道有一些办法,比如 E-TAG之类的。当然也有简单的设置:
比如我们在输出前,对内容进行md5,将它当成e-tag只要没变化,就不会有影响。也有其他的方式:

$seconds_to_cache = 3600;
$ts = gmdate("D, d M Y H:i:s", time() + $seconds_to_cache) . " GMT";
header("Expires: $ts"); header("Pragma: cache");
header("Cache-Control: max-age=$seconds_to_cache");

缓存1小时,主要是过期时间得用gmdate来设置,而不是date,这个要注意,其他都差不多。maxage要和expire能够对得上。

不算笔记的笔记。

粗心,又见粗心

粗心,又见粗心

有时候会用到gzip函数,只是有时候而已。。。
于是。。有些函数就会直接用上了。比如 :gzencode,gzdecode,gzcompress,gzuncompress,gzdeflate,gzinflate
在用的时候。。有些是想当然的。。。比如有Gzencode,就一定会有gzdecode吧?错。。。gzdecode暂时还没有正式版本支持,只存在于svn中,虽然手册上有。。但也说明了不能用

gzcompress与gzdeflate的区别,一个是基于RFC1950协议,一个是基于RFC1951,gzcompress因为是用的1950协议,手册上说了,它需要zlib库。gzdeflate就不需要
所以,gzcompress现在用的相对又少了一点。

好吧,现在说说我的粗心了,大家都知道Gzip压缩是有等级的(压缩软件都有,1~9,1最低压缩,9是最高压缩比),用9的话压缩出来的文件最小,但是解压的时候最耗CPU。所以一般 都是level4,其实就算是1也不错了。

粗心的就在于gzinflate的时候,想当然的将第二个参数length想成level了。结果一直在报错。居然我5分钟后才反应过来。NND,太粗心了。。。
第二个参数是length,不是level啊。

mongodb用索引与不用索引的区别

mongodb用索引与不用索引的区别

因为我mongo也是刚刚开始用,所以有一些地方的测试就不如很多专业人士了,但不代表我不能发言啊。。。

测试数据,11000左右,全部是int型字段(关于int型和字符串型,之前讲过了)
11000条,占用空间并不大,关键是看速度。。
11000条的数据的字段:id,pubdate,category_id,status,is_top,为什么只有这些字段 ?因为详细字段的Cache已经由redis实现,而redis不支持条件查询,所以将这些条件查询用mongo来代替了。你懂的。。为了速度。。。

测试开始:
1、order by id ASC limit 25,很常见的查询吧。每页显示25条。
没有索引的时候:0.88秒左右
用了id,unique索引后,0.004,第一次的时候0.08,后面稳定在0.00x左右

2、where category_id = 1 limit 25,某个条件
无索引时:0.6秒左右
有索引:第一次0.06左右,后面稳定在0.00x(x>6),即在0.006~0.01之间

3、where category_id = xx order by pubdate limit 25
无索引:0.8,最慢的一次达到了1.5秒
有索引的时候,与条件2差不多

至此第一步测试完毕,下一步测试200万左右数据。。还没有开始。因为都是真实数据,插起来比较麻烦

转:macosx如何锁屏

转:macosx如何锁屏

因为要执行一个脚本,时间会比较长,但是不能让别人碰电脑,所以只能想到锁屏了。平时只会sleep。。就找了这个资料

以下都是转载:

很多剛開始使用Mac OS X的用戶經常抱怨,為甚麼Mac OS X沒有一個簡單的方法,來實現快速鎖屏和切換用戶。的確,Mac顯然沒有對這個需求給與足夠的重視,提供的方法或比較蹩腳和不盡如人意,而且,對於習慣使 用鍵盤快捷鍵的朋友,更是沒有甚麼好的方法來實現。隨著Snow Leopard的發佈,快捷鍵鎖屏/快速切換用戶終於成為現實,雖然還是不太直觀,但到底還是好用了。

這篇文章,算是給這個古老的需求命題做個總結,總結下現有的方法,個位可以按照自己喜好來定。這裡的每一個方法,可能會被後面的某個方法使用到,請按照順序閱讀。

1:懶人方法
通過設定 Preferences(系統偏好設置)–>Security(安全)–>Gerneral(通用) 中的 Requeired password ****** after sleep or screen saver begins 的時長,來讓系統在睡眠或屏保啓動後的一段時間後啓動密碼保護

2:半智能方式

因為 第一節 中的時間選項有“Immediately 立即啓動”, 我們可以通過這個來實現快速鎖屏。Preferences(系統偏好設置)–>Security(安全)–>Gerneral(通用), 選擇時間為立即啓動

然後去到 Preferences(系統偏好設置)–>Exposé & Spaces–>Exposé

由於我們設定了在屏保啓動後立即啓動密碼保護,這樣的話,我們離開電腦時只要將鼠標移動到設定的相應觸發角出發屏保,即可同時啓動密碼保護

3:使用Keychain Access(鑰匙鏈)應用程序

去到Applications(應用程序)–>Utilities(實用工具) 打開Keychain Access.app

打開Keychain Access的偏好設置–>General(通用頁),勾選Show Status in Menu Bar(在菜單欖顯示),這時菜單欄會顯示鎖圖標

點擊此圖標,在下拉菜單中,你會找到 Lock Screen (鎖屏) 選項。

4:利用快速切換用戶,達到鎖屏目的

通過用戶切換功能,使系統回到登陸界面,也可以達到鎖屏的目的 Preferences(系統偏好設置)–>Accounts(用戶賬戶)

首先點擊左下角鎖,輸入管理員帳號密碼解開鎖定,解開鎖定後,點擊Login Options (登陸選項)

勾選 Show fast user switching menu as(在菜單欄顯示快速用戶切換) 這裡有三種方式,可以任選(Name, Short Name, Icon),選好後,菜單欄中,你會看見這個圖標

點擊圖標,你會發現有用戶列表和 Login Window的按鈕,點擊Login Window,系統會立即切換到登陸界面
(注意,這個跟註銷有本質區別,這個是保持此用戶狀態)

5:快捷鍵

前面介紹的方法基本都是鼠標操作,我們下面介紹如何通過鍵盤快捷鍵快速的進行鎖屏前面我們說過,通過設定屏保啓動後立即啓動密碼保護,那個是用觸發 角或時間控制的。但是,我們如果在設定了啓動屏保後立即啓動密碼保護,然後通過快捷鍵激活屏保,這樣就達到了前面用觸發角一樣的效果

要設定這個啓動屏保快捷鍵,請啓動 Applications(應用程序)–>Automator

啓動後,選擇新建服務

在創建服務頁面中,按照下圖所示,創建啓動屏保服務

配置完後按Command+S保存,系統會提示你輸入Service(服務)名稱,輸入lockScreen去到 Preferences(系統偏好設置)–>Keyboard(鍵盤)–>Keyboard Shotcuts(鍵盤快捷鍵) 選中左邊欄中的Services(服務)

到右邊欄找到你剛才的 lockScreen 服務,如果沒找到,點擊 “+” 添加即可,然後配置成你適合的快捷鍵即可。

要求完美的朋友也許對這個方法不滿意,那沒沒關係,我們可以換一個解決方案,還是打開Automator,新建服務,如圖,完成後保存

---
看到红字没》原文应该也是转贴的,这里有图文并茂的:http://blog.csdn.net/afatgoat/article/details/3891515
和我上面转的不太一样。。
最终我用的是4的方法,即:快速切换用户

Yii的又一个BUG?

Yii的又一个BUG?

先申明一下,这个可能不是BUG。只是算起来是实现的方式不一样而已。
场景:我有一个MYSQL数据库,但是现在容量越来越大,主要是因为其中有大字段,多个大字段,所以在查询的时候会特别特别慢。所以想到用mongo来存储一些查询用的结构。单条的时候,我还是准备采用MYSQL。当然其实单条用mongo也合适。不过因为迁移数据有点麻烦,所以还是先忍忍,一步一步来。

测试阶段:因为MYSQL to MONGO有点小麻烦,没有现成的工具。官方说有mongoimport,我看过了,确实OK,但是只支持一些基础的结构,比如:json,csv等。其他的则需要第三方工具。但我自己先在测试中,所以就直接写了个脚本,先将数据用AR取出来。然后插入到mongo中。结果发现,在排序的时候。。9999比10000还大。问了一下神仙 ,他说这应该是按字符串排序的方式来做的。

于是做了一个测试,写进了一个数字,果然就对了。。难道是yii的AR的BUG?想想这不太应该啊。于是我写了一个小的Demo:

$db = mysql_connect("localhost","root","123456");
mysql_select_db("feed");
$query = mysql_query("select id from feeds_group limit 1");
while($rs = mysql_fetch_array($query)){
$result = $rs;
echo "<pre>";
var_dump($result);
echo "</pre>";
}
echo "<hr />";
$dsn = 'mysql:host=localhost;dbname=feed';
$user = 'root';
$password = '123456';
$dbh = new PDO($dsn, $user, $password);
$sth = $dbh->prepare("select id from feeds_group limit 1");
$sth->execute();
$result = $sth->fetchAll();
echo "<pre>";
var_dump($result);
echo "</pre>";

打印出来一看:

array(2) {
[0]=>
string(1) "1"
["id"]=>
string(1) "1"
}

array(1) {
[0]=>
array(2) {
["id"]=>
string(1) "1"
[0]=>
string(1) "1"
}
}

果然出来就是字符串了,最后只能自己在插到mongo的时候写了一个小函数,对于数值型字段做了转换,问题就这样解决了。

NND被mongodb的limit BUG搞死了

NND被mongodb的limit BUG搞死了

昨天下载了php-mongo的组件进行了安装。结果在进行limit查询的时候一直reset。。查了半天,以为是语法错误 ,但最终都没有发现任何问题。当时我下的包是:https://nodeload.github.com/mongodb/mongo-php-driver/tarball/master,嗯。这是一个最新版。文件名是:mongodb-mongo-php-driver-1.3.0beta1-15-ge426381.tar.gz,一眼就可以看出这是一个beta版。我晶。。。就因为它,害得我折腾了一个晚上

各位看官:

$mongo = new Mongo();
$db = $mongo->selectCollection('orange','archive');
$query = $db->find(array("pubdate"=>array('$gt'=>'100000000'),'status'=>array('$in'=>array('0','9'))))->limit(10);
foreach ($query as $q) {
echo "<pre>";
print_r($q);
echo "</pre>";
}

这两句没问题吧。。。但事实上在1.3中就会导致 直接reset。如果不加limit条件就一切正常。我算是。。。蛋疼了。

后来从pecl.php.net中搜索mongo,网址其实就是在:http://pecl.php.net/package/mongo,然后下载了1.2.12:http://pecl.php.net/get/mongo-1.2.12.tgz,下载完后重新编译,又是那两句简单的代码:
phpize
./configure
make install
然后重启。。。一切就太平了。

mongodb 与 redis混用

mongodb 与 redis混用

本来一直在用redis,也没有觉得不爽,直到我需要对数据进行排序。。。进行条件查询。
一下子问题就来了。redis不支持这种条件查询。
于是。。我先hmGetAll,然后利用usort先排一下序,然后再利用数组的slice进行切分。这么一处理。。只有3000多条数据,0.2秒就这么浪费了。我晕啊。这怎么可以。。。这不科学啊。

于是,0.001949 一下子就刺瞎了我的钛金狗眼。
因为mongo的查询没有redis那样方便。于是在hashset的这一块,和list的这一块,我还是用redis方便,毕竟可以当成一个简单的链表处理,还是很方便的。。

对于有条件的查询,还是用mongoDB会更方便一点。测试了一下。原来只需要mongodb 512M内存就足够了,哥很大方,给了他1G,小样,你还不开心?

mongodb 的一些常规用法和疑问

mongodb 的一些常规用法和疑问

mongoDB现在对于PHP来说已经用起来很方便了,pecl直接下载安装编译类库就OK了
先下载:https://github.com/mongodb/mongo-php-driver/tarball/master
然后tar zxvf master
进入目录 。。
$ phpize
$ ./configure
$ make install
看好文件存在哪里。就存在刚才解 开的目录下的modules目录里。有一个mongo.so,OK,拷到扩展目录,然后加一行配置:extension=mongo.so

重启apache。命令行下运行 php -i |grep mongo
黑黑,一下子可以看到几段信息了吧?

-------
安装mongodb,在ubuntu下来说实在是太容易了,比如:apt-get install mongodb一下子就完事了
不想一直运行?在测试的时候运行:mongod -journal -maxConns=2400 -rest
嗯,还提供rest风格的请求。。。

-----

$a = $c->find(array('id'=>array('$gt'=>'10000'),'status'=>array('$ne'=>"1")));//->sort(array("pubdate"=>-1));
$result = iterator_to_array($a);
echo "<pre>";
print_r($result);
echo "</pre>";

排序什么的都方便。。。只是在这里遇到点小问题
上面这段代码能够正常输出。只是我将status换成array('$in'=>array("0","9"))的时候,就一条数据也没有了。但明明是有的,比如 上面$ne = 1,即不等于1的情况(就是0和9),可以查询到数据。。。真纠结啊
明天再测试测试。