[转载]Android2.2 SDK正式提供下载

mikel阅读(956)

[转载]Android2.2 SDK正式提供下载 — Windows Live.

就在5月20日的谷歌I/O大会基调演讲中,Android2.2(代号Froyo)正式公布。紧接着没多久,Android2.2 SDK就开始正式提供下载。联想到之前几个版本的发布过程,我们有理由相信Android2.2的更新极有可能在六月上中旬发布!

下载:Android2.2 SDK

此外,Adobe的Flash Player 10.1 for Android也开始正式提供beta下载,但需要使用2.2版本的Android访问,看来只有少量使用2.2的内部人员才能参与测试吧。 

下载:Adobe的 Flash Player 10.1 for Android

[转载]基于Mapabc API的周边查询应用

mikel阅读(1091)

[转载]基于Mapabc API的周边查询应用 – 小狼的世界 – 博客园.

现在,越来越多的 Location Based 应用,或者Geolocation的应用出现在网络、手机等各种各样的终端上,为人们的日常生活、出行和工作都提供了不少的便利。最常见的就是出门前,利 用地图工具,看看合适的公共交通路线,寻找一个自己最满意的方案,既方便有低碳环保。有时候,对周边环境不熟悉,想要找到周边的医院、银行、学校等一些单 位的时候,地图同样可以帮上我们的大忙。

今天,我就做了一个基于Mapabc地图API的周边查询工具,利用Mapabc详尽的基础地 物信息,为我查找周边的便民信息提供了有利的帮助。

开始之前,我大概需要知道最后的结果是什么样子的,可以借助传统的纸和笔,也可以用 现代的原型工具,当然PS这样的重量级工具就不太需要了。下面是效果图:

1131

有了效果图,接下来需要稍微规划一下代码。 Mapabc的API在页面加载完成后,需要初始化地图,所以初始化的操作放在一个函数 pageInit() 中。周边查询的操作,希望通过用户输入一个关键词,然后通过点选地图设置中心点的方式实现。那么就需要一个函数来监听鼠标在地图上的单击事件,然后一个负 责查询的函数和一个负责显示结果的函数。程序的结构大致如此,接下来就进入实质的编码过程。

编码的重点函数有以下几个:

mapObj.addEventListener(mapObj, MOUSE_CLICK, searchAround);

对地图添加监听事件。

mls.poiSearchByCenterXY(new MLngLat(cordx, cordy),keyword,citycode,mlsp);

利用中心点坐标查询查找周边信息

利用这两个函数,加上参考Mapabc官方的示例,我们就可以完成这个应 用。

1132

通过修改区号和关键字,可以在不同城市之间切 换,怎么样,简单吧。

[转载] DedeCMS采集规则-过滤-替换-技巧

mikel阅读(897)

[转载]DedeCMS采集规则-过滤-替换-技巧 – jim.ma (农民的天空) – 域名博客中心 – Powered by X-Space.

过滤替换

CODE:

1.采集去除链 接
[Copy to clipboard]CODE:
{dede:trim}]*)>([^<]*){/dede:trim}
--------------------------------

让field:title 标题突破30这个长度,修改代码的方法
找到./include/inc_arcpart_view.php
行291 :
if($titlelen=="") $titlelen = 30;
修改为
if($titlelen=="") $titlelen = 60;
就可以了,然后, 你可以这样调用了
{dede:channelArtlist typeid='0' col=1 tablewidth='100%'}
{dede:arclist row="10"}
[field:title function="cn_substr('@me',38)" /]

{/dede:arclist}
{/dede:channelArtlist}

把 这个延伸一下:关于inc_arcpart_view.php
function GetArcList($typeid=0,$row=10,$col=1,$titlelen=30,$infolen=160,
$imgwidth=120,$imgheight=90,$listtype="all",$orderby="default",$keyword="",
$innertext="",$tablewidth="100",$arcid=0,$idlist="")
这 里的参数都可以更改你实际需要的模板元素尺寸大小.

2. 采集过虑中去掉链接保留文字的方法!

柏老大的 方法是{dede:trim}<a ([^>]*)>([^<]*)</a>{/dede:trim}
这样 做会去掉<a hf.......>与</a>之间的字符!这样整个文章就少了部分字符,不完整了!

后来我多次 测试,总算找到了正确的使用方法!如下:
{dede:trim}<a([^>]*)>{/dede:trim}
{dede:trim}</a>{/dede:trim}

做 成两条采集规则就可以了!
在实际使用中好像([^<]*)([^>]*)两条一起使用才行!

3. 过滤div
{dede:trim}]*)>{/dede:trim}
{dede:trim}
{/dede:trim}
过 滤js
{dede:trim}]*)>([^<]*){/dede:trim}

过滤未知变量字符
固 定(.*)固定

4.dede万能过滤代码
以下是常用的正则表达式标签
{dede:trim}<tbody(.*)>{/dede:trim}
{dede:trim}</tbody>{/dede:trim}
{dede:trim}<table(.*)>{/dede:trim}
{dede:trim}</table>{/dede:trim}
{dede:trim}<tr(.*)>{/dede:trim}
{dede:trim}</tr>{/dede:trim}
{dede:trim}<td(.*)>{/dede:trim}
{dede:trim}</td>{/dede:trim}
{dede:trim}<font(.*)>{/dede:trim}
{dede:trim}</font>{/dede:trim}
{dede:trim}<a(.*)>{/dede:trim}
{dede:trim}</a>{/dede:trim}
{dede:trim}<param(.*)>{/dede:trim}
{dede:trim}<embed(.*)</embed>{/dede:trim}
{dede:trim}<object(.*)</object>{/dede:trim}
{dede:trim}<iframe(.*)</iframe>{/dede:trim}
{dede:trim}<form(.*)</form>{/dede:trim}
{dede:trim}<input(.*)>{/dede:trim}
{dede:trim}<scrīpt(.*)</scrīpt>{/dede:trim}
{dede:trim}<style(.*)</style>{/dede:trim}
{dede:trim}<!--(.*)-->{/dede:trim}

以 下为不常用的正则表达式标签
{dede:trim}<div(.*)>{/dede:trim}
{dede:trim}</div>{/dede:trim}
{dede:trim}<center(.*)>{/dede:trim}
{dede:trim}</center>{/dede:trim}
{dede:trim}<p(.*)>{/dede:trim}
{dede:trim}</p>{/dede:trim}
{dede:trim}<span(.*)>{dede:trim}
{dede:trim}</span>{dede:trim}
{dede:trim}<img(.*)>{/dede:trim}

/////////////////////////////////////

5. 织梦标题不全,鼠标指向显示全部的代码:
{dede:arclist titlelen='100'}

[field:title function=' ( strlen("@me")>40 ? cn_substr("@me",40): "@me" ) '/]
{/dede:arclist}

6.dede/inc /inc_archives_functions.php第100行(flash频道远程flash本地化的BUG)
$cfg_uploaddir = $GLOBALS['media_dir'];
修改成
$cfg_uploaddir = $GLOBALS['cfg_other_medias'];

6.发布时间,来源,作者可以通过@me函数实现,如:在自定义处理接口: 处输入  @me = "Azure·【博】" 就表示来源为“Azure·【博】”
7.内容的替换:在所采集的文章内容中有多媒体,使用的是相 对路径,采集的时候又不想下载,最好的办法就是将地址替换成媒体的实际地址。可以这样实现,在文章内容规则部分的自定义处理接口:处输入 @me=str_replace('src="str1','src="str2',@me);

dedecms 带超连接关键字 如何去掉
全部去
{dede:trim}^<a*'>*</a>${/dede:trim}
dede 自带采集器的高阶技巧

CODE:


dede 系统自带的采集器其实相当强大,特别是整个dede系统是完全开源的,即使有些采集上的特殊需求,只要对PHP的基本语言有掌握的话,也可以轻意实现。诛 仙外挂
要实现特殊的采集要求,内容规则里有一个自定义处理接口非常关键。
比如说,你要在每篇采集文章正文前加一个前言,前言的内容是正文的前100个字,应该怎么做呢?
首先,需要定义好文章内容的采集规则诛仙外挂,保证最后得到的只是文章的正文(这属于最基本的东西,不再说明)
然后,就需要在自定义处理接口里写一段程序:
@me='前言:'.substr(@me, 0, 200).'<br><br>'.@me
其中,因为汉字是双字节的,所以200个字节表示100个汉字,另外,如果正文里混有其它html代码的话,还需要调整一下字节数。以上代码中'前言:' 和'<br><br>'只是一个最基本的美工修饰,让前言和文章主体分离。
通过以上一段代码,所有采集的文章都会自动加上一个前言,这是一个最简单的例子了。
现在举一个复杂些的例子,需要修改源代码。
假设,你现在需要在文章正文处贴上文章来源的网址,比如说你从http://aa.com/43456.html采集到一篇文章,现在你需要在文章正文显 示这个网址,怎么做呢?
这个需求可能大家遇上的不多,但举一反正,诛仙外挂其它类似的需求也就有解决的思路了。
我们注意到,在自定义处理 接口的右边有@body,@litpic,@me三个预定变量,分别表示原始网页,缩略图、当前标记值和最终结果。那么我们现在要再增加一个变量 @url,表示当
前文章的网址。要做到这个功能,就必须改源代码。
只需改一个文件就可以了,即:include目录下的pub_collection.php(注意,这里使用的是DEDE4.0版本)
在文件最 后有一个函数:
//---------------------------------
//用扩展函数处理采集到的原始数据
//-------------------------------
function RunPHP($fvalue,$phpcode)
{
$DedeMeValue = $fvalue;
$phpcode = preg_replace("/'@me'|\"@me\"|@me/isU",'$DedeMeValue',$phpcode);
if(eregi('@body',$phpcode)){
$DedeBodyValue = $this->tmpHtml;
$phpcode = preg_replace("/'@body'|\"@body\"|@body/isU",'$DedeBodyValue',$phpcode);
}
if(eregi('@litpic',$phpcode)){
$DedeLitPicValue = $this->breImage;
$phpcode = preg_replace("/'@litpic'|\"@litpic\"|@litpic/isU",'$DedeLitPicValue',$phpcode);
}
@eval($phpcode.";");
return $DedeMeValue;
}
这里定义了默认的几个预定变量
现在我们要增加一个@url
因此上一段就要改成:
function RunPHP($fvalue,$phpcode, $dourl=false)
{
$DedeMeValue = $fvalue;
$phpcode = preg_replace("/'@me'|\"@me\"|@me/isU",'$DedeMeValue',$phpcode);
if(eregi('@body',$phpcode)){
$DedeBodyValue = $this->tmpHtml;
$phpcode = preg_replace("/'@body'|\"@body\"|@body/isU",'$DedeBodyValue',$phpcode);
}
if(eregi('@litpic',$phpcode)){
$DedeLitPicValue = $this->breImage;
$phpcode = preg_replace("/'@litpic'|\"@litpic\"|@litpic/isU",'$DedeLitPicValue',$phpcode);
}
if(eregi('@url',$phpcode)){
$DedeUrlValue = $dourl;
$phpcode = preg_replace("/'@url'|\"@url\"|@url/isU",'$DedeUrlValue',$phpcode);
}
@eval($phpcode.";");
return $DedeMeValue;
}
注意,为了给@url传递值,我们在函数的参数里增加了一个参数$dourl=false,因此还 需要在调用这个函数的地方改一下($dourl=false表示该参数并不是必须的,一般调用时可以不用此参数)
找到如下代码:
//用户 自行对内容进行处理的接口
if($sarr["function"]!=""){
if(!eregi('@litpic',$sarr["function"])){
$v = $this->RunPHP($v,$sarr["function"]);
$artitem .= "{dede:field name='$k'}$v{/dede:field}\r\n";
}else{
$tmpLtKeys[$k]['v'] = $v;
$tmpLtKeys[$k]['f'] = $sarr["function"];
}
把 其中的
$v = $this->RunPHP($v,$sarr["function"]);
改成:
$v = $this->RunPHP($v,$sarr["function"], $dourl);
就可以了,至此源代码全部修改完毕。
要 使用这个新的变量@url很简单
比如说,在文章内容的自定义处理接口里写下:
@me=@me.'<br><br& gt;文章来源:'.@url
就可以了
转自 bbs.dedecms.com

[原创]Dedecms5.5采集自定义模型修改

mikel阅读(1215)

打开 :dede/templets/co_add_step0.htm

修改
Select id,typename From `#@__channeltype` where id in(1,2) order by id asc
改为
Select id,typename From `#@__channeltype` where id>-1 order by id asc

这 样就行了,不过官方不会提供任何技术支持的

[转载]linq to sql 系列之 linq to sql性能优化技巧

mikel阅读(1133)

[转载]linq to sql 系列之 linq to sql性能优化技巧 – 欢迎光临赵玉开的技术博客 – 博客园.

linq to SQL 是一个代码生成器和ORM工具,他自动为我们做了很多事情,这很容易让我们对他的性能产生怀疑。但是也有几个测试证明显示在做好优化的情况下,linq to SQL的性能可以提升到ado.net datareader性能的93%。

因此我总结了linq to sql的10个性能提升点,来优化其查询和修改的性能。

1. 不需要时要关闭 DataContext的ObjectTrackingEnabled 属性

1 using (NorthwindDataContext context = new NorthwindDataContext())
2 {
3 context.ObjectTrackingEnabled = false;
4 }

关闭这个属性会使linq to sql停止对对象的标识管理和变化跟踪。但值得注意的是关闭ObjectTrackingEnabled 意味着也将DeferredLoadingEnabled属性设置为false,当访问相关表时会返回null。

2. 不要把所有的数据对象都拖到一个DataContext中

一个DataContext代表一个工作单元,并非整个数据库。如果几个数据库对象之间没有关系,或者在程序中用不到的数据库对象(例如日志表,批 量操作表等等),让这些对象消耗内存空间和DataContext对象跟踪服务是完全没有必要的。

建议将所有的数据库对象按工作单元分给几个DataContext来处理。你也可以通过构造函数配置这些DataContext使用相同的数据库连 接,这样也可以发挥据库连接池的用途。

3. CompiledQuery — 有必要就得用

在创建一个linq to sql表达式并将它转换成对应的sql语句执行的过程,需要几个关键的步骤

1) 创建表达式树
2) 转换成sql
3) 运行sql语句
4) 取回数据
5) 将数据转换成对象

很显然,当我们一遍又一遍的执行相同的查询时,上面1),2)两个步骤重复执行是在浪费时间。使用System.Data.Linq命名空间下的 CompiledQuery类的Compile方法可以避免这种浪费。

请看下面的使用示例:

1 Func<NorthwindDataContext, IEnumerable<Category>> func =
2 CompiledQuery.Compile<NorthwindDataContext, IEnumerable<Category>>
3 ((NorthwindDataContext context) => context.Categories.
4 Where<Category>(cat => cat.Products.Count > 5));

func变量现在是一个已经编译后的查询,他只需要在第一次运行时编译一次,就可以重复使用,现在我们将其存储到一个静态类中,如下所示:

01 /// <summary>
02 /// Utility class to store compiled queries
03 /// </summary>
04 public static class QueriesUtility
05 {
06 /// <summary>
07 /// Gets the query that returns categories with more than five products.
08 /// </summary>
09 /// <value>The query containing categories with more than five products.</value>
10 public static Func<NorthwindDataContext, IEnumerable<Category>>
11 GetCategoriesWithMoreThanFiveProducts
12 {
13 get
14 {
15 Func<NorthwindDataContext, IEnumerable<Category>> func =
16 CompiledQuery.Compile<NorthwindDataContext, IEnumerable<Category>>
17 ((NorthwindDataContext context) => context.Categories.
18 Where<Category>(cat => cat.Products.Count > 5));
19 return func;
20 }
21 }
22 }

如何使用它呢,请看下面的代码片段:

1 using (NorthwindDataContext context = new NorthwindDataContext())
2 {
3 QueriesUtility.GetCategoriesWithMoreThanFiveProducts(context);
4 }

4. 使用DataLoadOptions.AssociateWith设置仅从数据库中取需要的数据

请参考:http://www.cnblogs.com/yukaizhao/archive/2010/05/17/linq_to_sql_DeferredLoadingEnabled_dataloadoption_loadwith_associatewith.html
5. 仅在需要时打开积极并发控制,换句话说如果不需要请将列的UpdateCheck属性设置为UpdateCheck.Never,这样在更新和删除时可以 减少不必要的条件判断

01 [Column(Storage=“_Description”, DbType=“NText”,
02 UpdateCheck=UpdateCheck.Never)]
03 public string Description
04 {
05 get
06 {
07 return this._Description;
08 }
09 set
10 {
11 if ((this._Description != value))
12 {
13 this.OnDescriptionChanging(value);
14 this.SendPropertyChanging();
15 this._Description = value;
16 this.SendPropertyChanged(“Description”);
17 this.OnDescriptionChanged();
18 }
19 }
20 }

可以参考:http://www.cnblogs.com/yukaizhao/archive/2010/05/13/linq_to_sql_1.html 这篇文章中的第三点。

6. 经常设置DataContext.Log查看linq to sql执行时使用的sql,分析取回的数据是否刚好够用。

1 using (NorthwindDataContext context = new NorthwindDataContext())
2 {
3 context.Log = Console.Out;
4 }

7. 仅在有必要时使用Attach方法。

在linq to sql中对象附加是一个的非常好用的机制,但是什么事情都不是免费的。当在DataContext中Attach对象时,就意味着过一段时间你会使用这个 对象,DataContext会给这个对象做“马上要做修改的”标记。

但是有时候Attach并非必要,例如使用AttachAll去附加一个集合,这个集合中的元素并非都会发生变化。

8. 注意实体标识管理的开销

在一个非只读的DataContext中,对象一直会被跟踪,因此要知道在非直觉的情况下也可能会导致DataContext做对象跟踪,请看下面 的代码

1 using (NorthwindDataContext context = new NorthwindDataContext())
2 {
3 var a = from c in context.Categories
4 select c;
5 }

非常简单,就是一个最基本的linq查询,让我们再看下另一个语句

01 using (NorthwindDataContext context = new NorthwindDataContext())
02 {
03 var a = from c in context.Categories
04 select new Category
05 {
06 CategoryID = c.CategoryID,
07 CategoryName = c.CategoryName,
08 Description = c.Description
09 };
10 }

这两种写法哪一种更快呢,事实证明第二个语句比第一个要快得多http://blogs.msdn.com/ricom/archive/2007/06/29/dlinq-linq-to-sql-performance-part-3.aspx

为什么呢? 因为在第一个查询中查询出的每一个对象都需要存储在DataContext中,并对他们做可能会发生变化的跟踪,而在第二个查询中你生命了一个新的对象, 就不需要再做跟踪了,所以第二个语句效率会高一些。

9. Linq to sql 提供了Take和Skip方法,使用他们来取需要的记录,不要把整个表中的记录都取下来

10. 不要滥用CompiledQuery 方法,如果你确认某个查询只会执行一遍,那就不要使用CompiledQuery来了,使用它也是需要付出代价的。

最后希望这些技巧对你有用。欢迎发表评论。

本文是翻译文章;

原文请看 http://www.sidarok.com/web/blog/content/2008/05/02/10-tips-to-improve-your-linq-to-sql-application-performance.html

linq to sql相关随笔:

1.  从 CUD开始,如何使用LINQ  to SQL插入、修改、删除数据

2.  查 询 使用LINQ to SQL做简单查询

3.  查 询 延迟加载与立即加载,使用LoadWith和AssociateWith

4.  查 询 inner join,left outer join

5.  Linq to SQL中的聚合grouping having

6.  LINQ to SQL查询优化,需要忧虑性能吗?


请尊重作者的劳动,转载请保留链接 玉开的技术博客

[转载]DedeCms增加采集网页测试地址

mikel阅读(980)

[转载]DedeCms增加采集网页测试地址_技术专题_中国站长站 CHINAZ.COM.

DEDE自带的采集,测试时,默认是列表页的最后一条记录,不能像火车头一样手工提交测试地址,非常不便!

为了方便改动如下:

打开co_test_rule.php

找到

以下为引用的内容:
<tr>
<td height=”24″ colspan=”2″ align=”center”>
<textarea name=”r2″ id=”r2″ style=”width:100%;height:250″>测试网址:$turl \r\n <?
$co->TestArt($turl); ?></textarea>
</td>
</tr>

改为

以下为引用的内容:
<form action=”co_test_rule.php”>
<tr>
<td height=”24″ align=”center”>测试地址:</td>
<td><? if(empty($testurl))$testurl=$turl;?>
<INPUT TYPE=”hidden” NAME=”nid” value=”<?echo $nid;?>”>
<INPUT TYPE=”text” NAME=”testurl” size=90 value=”<?echo $testurl;?>”> <INPUT TYPE=”submit” value=”测试”></td>
</tr>
</form>
<tr>
<td height=”24″ colspan=”2″ align=”center”>
<textarea name=”r2″ id=”r2″ style=”width:100%;height:250″>测试网址:$turl \r\n <?
$co->TestArt($testurl); ?></textarea>
</td>
</tr>

这样就有测试地址可以手工提交了,非常实用!

但是不知道为什么我的测试采集规则的地址总是不能用,无奈只能将测试地址写死在了dede/templates/co_test_url.php里

<textarea name=”r2″ rows=”15″ id=”r2″ style=”width:98%;height:250px”>测试网址: <?php  echo “$turl \r\n”; $co->TestArt(‘http://www.zhubajie.com/task/iv/307762’); ?></textarea>

[转载]jQuery备忘之(一):jQuery处理.Net后台返回的Xml格式与Json格式的数据的比较分析

mikel阅读(843)

[转载]jQuery备忘之(一):jQuery处理.Net后台返回的Xml格式与Json格式的数据的比较分析 – 一切问题最终都是时间问题,一切烦恼其实都是自寻烦恼。 – 博客园.

最近项目空闲下来,手头也没有什么事情,所以研究了一下JQuery对后台返回数据格式的处理。可能也是因为之前用JS写code的习惯,所以比较倾向于 用JS处理XML格式的数据,当然这也就会造成我后台返回的数据的格式全部为XML的格式,处理起来相对繁琐。

当然我也早就发现JQuery与Json格式的数据结合的非常好,但是一直苦于.NET的对数据转换成Json格式的繁琐,所以一直也 没有采用Json格式的数据,或者是在数据相对简单的情况下采用Json格式的数据,其他千篇一律XML,但是今天我分析了一下jQuery对两种数据格 式的处理之后,完全改变了心态,并力推大家用jQuery + Json处理后台返回数据。

请看如下比较:

jQuery + Xml】

如下代码是我查询IPInfo表中前10条数据,并以XML格式输出:

代码

public void XmlToAjax()
{
DataTable dt
= SQLHelper.ExecuteDataTable(SQLHelper.conStrings, CommandType.Text, select top(10) * from IPInfo);
DataSet ds
= new DataSet();
ds.Tables.Add(dt);
//Console
Response.ContentType = text/xml;
Response.Charset
= UTF-8;
Response.Clear();
Response.Write(
<?xml version=\1.0\ encoding=\utf8\ ?>\n + ds.GetXml());
Response.End();
}

我在前台接收到数据后进行如下处理:

代码

function checkText() {
var xmlT;
if ($.trim($(#txtID).val()) == “”) {
$(
#sm).text(请 输入XML条件);
$(
#txtID).focus();
return false;
}
else {
$(
#sm).text(“”);
$.ajax({
type:
GET,
//contentType: “application/json”, //WebService 会返回Json类型
url: ../Ajax/Ajax1.aspx,
dataType:
xml,
data:
“”, //这里是要传递的参数,格式为 data: ” {paraName:paraValue}”,下面将会看到
success: function(result) { //回调函数,result,返回值
var ID = ;
$(result).find(
Table1).each(function() {
ID
+= $(this).children(IPid).text() + <br>;
});
$(
#divMsg).html(ID);
}
});
}

}

下面是输出结果:

result.xml 的结果集为:

代码

result.xml
<?xml version=”1.0″?>
<NewDataSet>
<Table1>
<IPid>1</IPid>
<IPFrom>0.0.0.0 </IPFrom>
<IPTo>0.255.255.255 </IPTo>
<IPLocation>IANA  CZ88.NET</IPLocation>
<IPToNumber>16777215</IPToNumber>
<IPFromNumber>0</IPFromNumber>
</Table1>
<Table1>
<IPid>2</IPid>
<IPFrom>1.0.0.0 </IPFrom>
<IPTo>1.255.255.255 </IPTo>
<IPLocation>IANA  CZ88.NET</IPLocation>
<IPToNumber>33554431</IPToNumber>
<IPFromNumber>16777216</IPFromNumber>
</Table1>
<Table1>
<IPid>3</IPid>
<IPFrom>2.0.0.0 </IPFrom>
<IPTo>2.255.255.255 </IPTo>
<IPLocation>IANA  CZ88.NET</IPLocation>
<IPToNumber>50331647</IPToNumber>
<IPFromNumber>33554432</IPFromNumber>
</Table1>
<Table1>
<IPid>4</IPid>
<IPFrom>3.0.0.0 </IPFrom>
<IPTo>3.255.255.255 </IPTo>
<IPLocation>美国 新泽西通用电气公司</IPLocation>
<IPToNumber>67108863</IPToNumber>
<IPFromNumber>50331648</IPFromNumber>
</Table1>
<Table1>
<IPid>5</IPid>
<IPFrom>4.0.0.0 </IPFrom>
<IPTo>4.9.255.255 </IPTo>
<IPLocation>美国  CZ88.NET</IPLocation>
<IPToNumber>67764223</IPToNumber>
<IPFromNumber>67108864</IPFromNumber>
</Table1>
<Table1>
<IPid>6</IPid>
<IPFrom>4.10.0.0 </IPFrom>
<IPTo>4.10.255.255 </IPTo>
<IPLocation>美国 新泽西州立大 学</IPLocation>
<IPToNumber>67829759</IPToNumber>
<IPFromNumber>67764224</IPFromNumber>
</Table1>
<Table1>
<IPid>7</IPid>
<IPFrom>4.11.0.0 </IPFrom>
<IPTo>4.11.255.255 </IPTo>
<IPLocation>美国 夏威夷</IPLocation>
<IPToNumber>67895295</IPToNumber>
<IPFromNumber>67829760</IPFromNumber>
</Table1>
<Table1>
<IPid>8</IPid>
<IPFrom>4.12.0.0 </IPFrom>
<IPTo>4.19.77.255 </IPTo>
<IPLocation>美 国  CZ88.NET</IPLocation>
<IPToNumber>68374015</IPToNumber>
<IPFromNumber>67895296</IPFromNumber>
</Table1>
<Table1>
<IPid>9</IPid>
<IPFrom>4.19.78.0 </IPFrom>
<IPTo>4.19.78.255 </IPTo>
<IPLocation>美国 西南政法大学</IPLocation>
<IPToNumber>68374271</IPToNumber>
<IPFromNumber>68374016</IPFromNumber>
</Table1>
<Table1>
<IPid>10</IPid>
<IPFrom>4.19.79.0 </IPFrom>
<IPTo>4.19.79.63 </IPTo>
<IPLocation>美 国 Armed Forces Radio/Television</IPLocation>
<IPToNumber>68374335</IPToNumber>
<IPFromNumber>68374272</IPFromNumber>
</Table1>
</NewDataSet>

看到这一串代码,那我接下来面对的问题就是去分析这一串代码,取出我所需要的数据,以前一直都是这样处理的(),就像这一段 代码:

$(result).find(Table1).each(function() {    ID += $(this).children(IPid).text() + <br>; }); 是要取出XML中的所有IPid的数据。

(顺便插入一句:因为用Jquery操作XML,所以代码相对比较简洁,如果用JS的话会较之麻烦一些。)

那我们接下来再看看Jquery是如何处理Json格式的数据的:

【Jquery + Json】

在处理之前,首先我们要做一件事,就是将数据库取出的数据转换成Json格式,可能已存在有多种转换方法,这里呢我就先说下自己的Json转换方法:

首先创建一个JsonHelper的类如下:

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using System.Runtime.Serialization.Json;

namespace LinqModel
{
public static class JsonHelper
{
/// <summary>
/// 格式化 成Json字符串
/// </summary>
/// <param name=”obj”>需要格式化的对象</param>
/// <returns>Json 字符串</returns>
public static string ToJson(this object obj)
{
// 首先,当然是JSON序列化
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());

// 定义一个stream用来存发序列化之后的内容
Stream stream = new MemoryStream();
serializer.WriteObject(stream, obj);

// 从头到尾将stream读取成一个字符串形式的数据,并且返回
stream.Position = 0;
StreamReader streamReader
= new StreamReader(stream);
return streamReader.ReadToEnd();
}
}
}

当然这里我们需要引用两个DLL文件 (System.Runtime.Serialization.Json,System.ServiceModel.Web),当然这里直接添加添 加.net引用,找到这两个DLL就OK了,然后我们需要创建一个实体类,以便用泛型操作,代码如下:

代码

/// <summary>
/// 实体类 IPInfo 。(属性说明自动提取数据库字段的描述信息)
/// </summary>
[DataContract]
public class IPInfo
{
public IPInfo()
{ }
#region Model
private long _ipid;
private string _ipfrom;
private string _ipto;
private string _iplocation;
private string _ipcity;
private string _iptonumber;
private string _ipfromnumber;
/// <summary>
/// Key
/// </summary>
[DataMember]
public long IPid
{
set { _ipid = value; }
get { return _ipid; }
}
/// <summary>
/// 区间开 始
/// </summary>
[DataMember]
public string IPFrom
{
set { _ipfrom = value; }
get { return _ipfrom; }
}
/// <summary>
/// 区间结 束
/// </summary>
[DataMember]
public string IPTo
{
set { _ipto = value; }
get { return _ipto; }
}
/// <summary>
/// 位置
/// </summary>
[DataMember]
public string IPLocation
{
set { _iplocation = value; }
get { return _iplocation; }
}
/// <summary>
/// 城市
/// </summary>
[DataMember]
public string IPCity
{
set { _ipcity = value; }
get { return _ipcity; }
}
/// <summary>
///
/// </summary>
[DataMember]
public string IPToNumber
{
set { _iptonumber = value; }
get { return _iptonumber; }
}
/// <summary>
///
/// </summary>
[DataMember]
public string IPFromNumber
{
set { _ipfromnumber = value; }
get { return _ipfromnumber; }
}
#endregion Model

}

注意:如果要对该类进行序列化,一定要在类前面添加上“[DataContract]”,在属性前面添加上 “[DataMember]”,这样才能被“DataContractJsonSerializer”序列化成JSON。

下面我们来看如何调用这个方法转换成Json格式的数据:

代码

public void JsonToAjax()
{
using (SQLDataReader reader = SQLHelper.ExecuteReader(SQLHelper.conStrings, CommandType.Text, select top(10) * from IPInfo))
{
List
<LinqModel.IPInfo> list = new List<LinqModel.IPInfo>();
while (reader.Read())
{
LinqModel.IPInfo model
= new LinqModel.IPInfo();
model.IPCity
= reader[IPCity].ToString();
model.IPFrom
= reader[IPFrom].ToString();
model.IPFromNumber
= reader[IPFromNumber].ToString();
model.IPid
= long.Parse(reader[IPid].ToString());
model.IPLocation
= reader[IPLocation].ToString();
model.IPTo
= reader[IPTo].ToString();
model.IPToNumber
= reader[IPToNumber].ToString();
list.Add(model);
}
//list.ToJson();
Response.Write(list.ToJson());
Response.End();
}

}

就是如此调用:list.ToJson(),简单吧,下面看一下输出 的结果:

代码

[{“IPCity”:””,”IPFrom”:”0.0.0.0 “,”IPFromNumber”:”0″,”IPLocation”:”IANA CZ88.NET”,”IPTo”:”0.255.255.255 “,”IPToNumber”:”16777215″,”IPid”:1}, {“IPCity”:””,”IPFrom”:”1.0.0.0 “,”IPFromNumber”:”16777216″,”IPLocation”:”IANA CZ88.NET”,”IPTo”:”1.255.255.255 “,”IPToNumber”:”33554431″,”IPid”:2}, {“IPCity”:””,”IPFrom”:”2.0.0.0 “,”IPFromNumber”:”33554432″,”IPLocation”:”IANA CZ88.NET”,”IPTo”:”2.255.255.255 “,”IPToNumber”:”50331647″,”IPid”:3}, {“IPCity”:””,”IPFrom”:”3.0.0.0 “,”IPFromNumber”:”50331648″,”IPLocation”:” 美国 新泽西通用电气公司”,”IPTo”:”3.255.255.255 “,”IPToNumber”:”67108863″,”IPid”:4}, {“IPCity”:””,”IPFrom”:”4.0.0.0 “,”IPFromNumber”:”67108864″,”IPLocation”:” 美国 CZ88.NET”,”IPTo”:”4.9.255.255 “,”IPToNumber”:”67764223″,”IPid”:5}, {“IPCity”:””,”IPFrom”:”4.10.0.0 “,”IPFromNumber”:”67764224″,”IPLocation”:” 美国 新泽西州立大学”,”IPTo”:”4.10.255.255 “,”IPToNumber”:”67829759″,”IPid”:6}, {“IPCity”:””,”IPFrom”:”4.11.0.0 “,”IPFromNumber”:”67829760″,”IPLocation”:” 美国 夏威夷”,”IPTo”:”4.11.255.255 “,”IPToNumber”:”67895295″,”IPid”:7}, {“IPCity”:””,”IPFrom”:”4.12.0.0 “,”IPFromNumber”:”67895296″,”IPLocation”:” 美国 CZ88.NET”,”IPTo”:”4.19.77.255 “,”IPToNumber”:”68374015″,”IPid”:8}, {“IPCity”:””,”IPFrom”:”4.19.78.0 “,”IPFromNumber”:”68374016″,”IPLocation”:” 美国 西南政法大学”,”IPTo”:”4.19.78.255 “,”IPToNumber”:”68374271″,”IPid”:9}, {“IPCity”:””,”IPFrom”:”4.19.79.0 “,”IPFromNumber”:”68374272″,”IPLocation”:” 美 国 Armed Forces Radio\/Television”,”IPTo”:”4.19.79.63 “,”IPToNumber”:”68374335″,”IPid”:10}]

标准的Json格式,呵呵,看了上面的代码,是不是很方便,我想下面的操作就更简单了,看下面的Jquery代码:

代码

function checkText1() {
var xmlT;
if ($.trim($(#txtID1).val()) == “”) {
$(
#sm1).text(请 输入Json条件);
$(
#txtID1).focus();
return false;
}
else {
$(
#sm1).text(“”);
$.ajax({
type:
GET,
contentType: application/json,
url: ../Ajax/Ajax1.aspx,
dataType: json,
data:
“”, //这里是要传递的参数,格式为 data: ” {paraName:paraValue}”,下面将会看到
success: function(result) { //回调函数,result,返回值
var aa = ;
aa
+= result[1][IPid] + <br>;
aa
+= result[1][IPFrom] + <br>;
aa
+= result[1][IPTo] + <br>;
aa
+= result[1][IPLocation] + <br>;
aa
+= result[1][IPCity] + <br>;
aa
+= result[1][IPToNumber] + <br>;
aa
+= result[1][IPFromNumber] + <br>;
$(
#divMsg).html(aa);
}
});
}

我们再来看一下 result的结果集:

result
{…}
[0]: {…}
[1]: {…}
[2]: {…}
[3]: {…}
[4]: {…}
[5]: {…}
[6]: {…}
[7]: {…}
[8]: {…}
[9]: {…}

result[0]
{…}
IPCity: “”
IPFrom: “0.0.0.0        ”
IPFromNumber: “0”
IPid: 1
IPLocation: “IANA  CZ88.NET”
IPTo: “0.255.255.255  ”
IPToNumber: “16777215”

就像操作一个泛型一样简单,便捷。

[转载]JQuery 的跨域方法 可跨新浪、腾讯、经网等任意网站

mikel阅读(829)

[转载]JQuery 的跨域方法 可跨新浪、腾讯、经网等任意网站 – Taven – 博客园.

因发现有不少博友发园内短信问及JS的跨域问题,我想很多程序员的脑海里面还认为JS是不能跨域的,其实这是一个错误的观点;有很多人在网上找其解 决方法,教其用IFRAME去解决的文章很多,真有那么复杂吗?其实很简单的,如果你用JQuery,一个GETJSON方法就搞定了,而且是一行代码搞 定。

下面开始贴出方法。

//跨域(可跨所有域 名)
$.getJSON(http://user.hnce.com.cn/getregion.aspx?id=0&jsoncallback=?,function(json){

//要求远程请求页面的数据格式为: ?(json_data)
//例如:
//?([{“_name”:”湖南省”,”_regionId”:134},{“_name”:”北京 市”,”_regionId”:143}])
alert(json[0]._name);

});

注意,getregion.aspx中,在输出JSON数据时,一定要用Request.QueryString[“jsoncallback”],将获 取的内容放到返回JSON数据的前面,假设实际获取的值为42342348,那么返回的值就是 42342348([{“_name”:”湖南省”,”_regionId”:134},{“_name”:”北京 市”,”_regionId”:143}])

因为getJSON跨域的原理是把?随机变一个方法名,然后返回执行的,实现跨域响应的目的。

具体getJSON的使用说明,请参考JQuery手册。

下面一个是跨域执行的真实例子:

代码

<script src=http://common.cnblogs.com/script/JQuery.js type=text/JavaScript></script>
<script type=text/JavaScript>
//跨域(可跨所有域名)
$.getJSON(http://e.hnce.com.cn/tools/ajax.aspx?jsoncallback=?, { id: 0, action: jobcategoryjson }, function(json) {

alert(json[0].pid);
alert(json[
0].items[0]._name);

});
</script>

作者:Taven.李锡远
出处:http://taven.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

[转载]Asp.Net 4.0 SEO增强之 UrlRouting

mikel阅读(1163)

[转载]Asp.Net 4.0 SEO增强之 UrlRouting – 欢迎光临赵玉开的技术博客 – 博客园.

在.Net 4.0之前我们为了做出搜索引擎友好的,对用户也友好的url都是需要自己实现Url重写,现在不需要了,.Net 4.0为我们做这一切。UrlRouting之所以称之为Routing是因为它不但实现了Url重写还可以通过参数得到重写后的Url在页面上使用。

1. Url Routing 的通常用法
UrlRouting在ASP.NET Mvc项目中被广泛使用,在Mvc中很好用,所以移植到了webform中,我们先看下在webform中的使用方式
假定一个使用场景:我们需要 做博客每日文章的页面,我们希望的url地址是:
/archive/2010/05/10/default.aspx
这个地址将被映射 到~/posts.aspx文件上

要使用UrlRouting,需要将UrlRouting的规则注册到RouteTable中,如下Global文件中注册Routing规则的代 码

01 public static void RegisterRoutes(RouteCollection routes)
02 {
03 routes.Ignore("{resource}.axd/{*pathInfo}");
04
05 routes.MapPageRoute("blogs", //给这个UrlRouting规则起一个名字
06 "archive/{year}/{month}/{date}/default.aspx", //希望的友好Url地址 格式
07 "~/blogs.aspx", //映射到的aspx页 面路径
08 false, //是否需要检查用户权 限
09 new RouteValueDictionary{ { "year", DateTime.Now.Year },
10 { "month", DateTime.Now.Month },
11 {"date", DateTime.Now.Date}
12 },//参数的默认值
13 new RouteValueDictionary {
14 {"year",@"(19|20)\d{2}"},
15 {"month",@"\d{1,2}"},
16 {"date",@"\d{1,2}"}
17 } //参数的规则,我们在这里限制url中的年月日是我 们想要的数据格式
18 );
19
20 }
21
22 void Application_Start(object sender, EventArgs e)
23 {
24 //在Application_Start时注册的Routing规则
25 RegisterRoutes(RouteTable.Routes);
26 }

2. 在页面中使用UrlRouting参数值
1) 在后台代码中使用Route的值

1 protected void Page_Load(object sender, EventArgs e)
2 {
3 string year = (string)RouteData.Values["year"];
4 string month = (string)RouteData.Values["month"];
5 string date = (string)RouteData.Values["date"];
6 }

2) 在页面上使用

1 <asp:Literal ID="literalYear" runat="server" Text="<%$RouteValue:year %>"></asp:Literal>
2 -<asp:Literal ID="literal1" runat="server" Text="<%$RouteValue:month %>"></asp:Literal>
3 -<asp:Literal ID="literal2" runat="server" Text="<%$RouteValue:date %>"></asp:Literal>

3) 在DataSource中使用RouteParameter

1 <asp:SQLDataSource ID="SQLDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TestDb %>"
2 SelectCommand="SELECT BlogID,BlogTitle FROM Blogs Where Category = @category">
3 <SelectParameters>
4 <asp:RouteParameter Name="category" RouteKey="category" />
5 </SelectParameters>
6 </asp:SqlDataSource>

4) 在页面上显示RouteUrl

1 <a href='<%=GetRouteUrl("blogs",new {year=2010,month=05,date=05}) %>'>2010年5月1日的博客</a>

3. UrlRouting和UrlRewrite的区别

UrlRouting相对于Url重写是一个比较新的事物,UrlRouting的长处是可以做双向转换,既可以做url重写,还可以根据一些参数 获得重写后的Url地址,但是它也有自己的不足之处,比如说如果你想连域名一起重写,比如博客地址yukaizhao.cnblogs.com这样的重 写,UrlRouting就做不到了,只能用UrlRewrite。

ASP.NET 4.0 新特性相关随笔:

1. 从 页面标记<%%>说起
2. Asp.Net 4.0 中可以用自定义的Provider做OutputCache 了
3. SEO 增强支持MetaKeywords,和MetaDescription,RedirectPermanant
4. SEO 增强之URL Routing

[转载]Memcache and Mongodb

mikel阅读(926)

[转载]Memcache and Mongodb – lovecindywang – 博客园.

先说说自己对Memcache和Mongodb的一些看法,主要是抛砖引玉了,希望看到大家的意见和补充。

Memcache

Memcache的优势我觉得总结下来主要体现在:

1) 分布式。可以由10台拥有4G内存的机器,构成一个40G的内存池,如果觉得还不够大可以增加机器,这样一个大的内存池,完全可以把大部分热点业务数据保 存进去,由内存来阻挡大部分对数据库读的请求,对数据库释放可观的压力。

2) 单点。如果Web服务器或App服务器做负载均衡的话,在各自内存中保存的缓存可能各不相同,如果数据需要同步的话,比较麻烦(各自自己过期,还是分发数 据同步?),即使数据并不需要同步,用户也可能因为数据的不一致而产生用户体验上的不友好。

3) 性能强。不用怀疑和数据库相比确实是,根源上还是内存的读写和磁盘读写效率上几个数量级的差距。有的时候我们在抱怨数据库读写太差的情况下可以看看磁盘的 IO,如果确实是瓶颈的话装啥强劲的数据库估计也档不了,强不强无非是这个数据库多少充分的利用了内存。

但是也不太建议在任何情况下使 用Memcache替代任何缓存:

1) 如果Value特别大,不太适合。因为在默认编译下Memcache只支持1M的Value(Key的限制到不是最大的问题)。其实从实践的角度来说也不 建议把非常大的数据保存在Memcache中,因为有序列化反序列化的过程,别小看它消耗的CPU。说到这个就要提一下,我一直觉得Memcache适合 面向输出的内容缓存,而不是面向处理的数据缓存,也就是不太适合把大块数据放进去拿出来处理之后再放进去,而是适合拿出来就直接给输出了,或是拿出来不需 要处理直接用。

2) 如果不允许过期,不太适合。Memcache在默认情况下最大30天过期,而且在内存达到使用限制后它也会回收最少使用的数据。因此,如果我们要把它当作 static变量的话就要考虑到这个问题,必须有重新初始化数据的过程。其实应该这么想,既然是缓存就是拿到了存起来,如果没有必定有一个重新获取重新缓 存的过程,而不是想着它永远存在。

在使用Memcache的过程中当然也会有一些问题或者说最佳实践:

1) 清除部分数据的问题。Memcache只是一个Key/Value的池,一个公共汽车谁都可以上。我觉得对于类似的公共资源,如果用的人都按照自己的规则 来的话很容易出现问题。因此,最好在Key值的规范上上使用类似命名空间的概念, 每一个用户都能很明确的知道某一块功能的Key的范围,或者说前缀。带来的好处是我们如果需要清空的话可以根据这个规范找到我们自己的一批Key然后再去 清空,而不是清空所有的。当然有人是采用版本升级的概念,老的Key就让它过去吧,到时候自然会清空,这也是一种办法。不过Key有规范总是有好处的,在 统计上也方便一点。

2) Value的组织问题。也就是说我们存的数据的粒度,比如要保存一个列表,是一个保存在一个键值还是统一保存为一个键值,这取决于业务。如果粒度很小的话 最好是在获取的时候能批量获取,在保存的时候也能批量保存。对于跨网络的调用次数越少越好,可以想一下,如果一个页面需要输出100行数据,每一个数据都 需要获取一次,一个页面进行上百次连接这个性能会不会成问题。

那么Memcache主要用在哪些功能上呢?

其实我觉 得平时能想到在内存中做缓存的地方我们都可以考虑下是不是可以去适用分布式缓存,但是主要的用途还是用来在前端或中部挡一下读的需求来释放Web服务器 App服务器以及DB的压力。

Mongodb

Mongodb是一款比较优良的非关系型数据库的文档型的数据库。它的优势主要体现在:

1) 开源。意味着即使我们不去改也可以充分挖掘它,MS SQL除了看那些文档,谁又知道它内部如何实现。

2) 免费。意味着我们可以在大量垃圾服务器上装大量的实例,即使它性能不怎么高,也架不住非常多的点啊。

3) 性能高。其它没比较过,和MS SQL相比,同样的应用(主要是写操作)一个撑500用户就挂了,一个可以撑到2000。在数据量上到百万之后,即使没索引,MS SQL的插入性能下降的也一塌糊涂。其实任何事物都有相对性的,在变得复杂变得完善了之后会牺牲一部分的性能,MS SQL体现的是非常强的安全性数据完整性,这点是Mongodb办不到的。

4) 配置简单并且灵活。在生产环境中对数据库配置故障转移群集和读写分离的数据库复制是很常见的需求,MS SQL的配置繁琐的步骤还是很恐怖的,而Mongodb可以在五分钟之内配置自己所需要的故障转移组,读写分离更是只需要一分钟。灵活性体现在,我们可以 配置一个M一个S,两个M一个S(两个M写入的数据会合并到S上供读取),一个M两个S(一个M写入的数据在两个S上有镜像),甚至是多个M多个S(理论 上可以创建10个M,10个S,我们只需要通过轮询方式随便往哪个M上写,需要读的时候也可以轮训任意一个S,当然我们要知道不可能保证在同一时间所有的 S都有一致的数据)。那么也可以配置两个M的对作为一套故障转移群集,然后这样的群集配置两套,再对应两个S,也就是4个M对应2个S,保证M点具有故障 转移。

5) 使用灵活。在之前的文章中我提到甚至可以通过SQL到JS表达式的转换让Mongodb支持SQL语句的查询,不管怎么说Mongodb在查询上还是很方 便的。

之前也说过了,并不是所有数据库应用都使用采用Mongodb来替代的,它的主要缺点是:

1) 开源软件的特点:更新快,应用工具不完善。由于更新快,我们的客户端需要随着它的更新来升级才能享受到一些新功能,更新快也意味着很可能在某一阶段会缺乏 某个重要功能。另外我们知道MS SQL在DEV/DBA/ADM多个维度都提供了非常好的GUI工具对数据库进行维护。而Mongodb虽然提供了一些程序,但是并不是非常友好。我们的 DBA可能会很郁闷,去优化Mongodb的查询。

2) 操作事务。Mongodb不支持内建的事务(没有内建事务不意味着完全不能有事务的功能),对于某些应用也就不适合。不过对于大部分的互联网应用来说并不 存在这个问题。

在使用Mongodb的过程中主要遇到下面的问题:

1) 真正的横向扩展?在使用Memcache的过程中我们已经体会到这种爽了,基本可以无限的增加机器来横向扩展,因为什么,因为我们是通过客户端来决定键值 保存在那个实例上,在获取的时候也很明确它在哪个实例上,即使是一次性获取多个键值,也是同样。而对于数据库来说,我们通过各种各样的方式进行了 Sharding,不说其它的,在查询的时候我们根据一定的条件获取批量的数据,怎么样去处理?比如我们按照用户ID去分片,而查询根本不在乎用户ID, 在乎的是用户的年龄和教育程度,最后按照姓名排序,到哪里去取这些数据?不管是基于客户端还是基于服务端的Sharding都是非常难做的,并且即使有了 自动化的Sharding性能不一定能有保障。最简单的是尽量按照功能来分,再下去就是历史数据的概念,真正要做到实时数据分散在各个节点,还是很困难。

2) 多线程,多进程。在写入速度达不到预期的情况下我们多开几个线程同时写,或者多开几个Mongodb进程(同一机器),也就是多个数据库实例,然后向不同 的实例去写。这样是否能提高性能?很遗憾,非常有限,甚至可以说根本不能提高。为什么使用memcache的时候多开线程可以提高写入速度?那是因为内存 数据交换的瓶颈我们没达到,而对于磁盘来说,IO的瓶颈每秒那么几十兆的是很容易达到的,一旦达到这个瓶颈了,无论是开多少个进程都无法提高性能了。还好 Mongodb使用内存映射,看到内存使用的多了,其实我对它的信心又多了一点(内存占用多了我觉得CPU更容易让它不闲着),怕就怕某个DB不使用什么 内存,看着IO瓶颈到了,内存和CPU还是吃不饱。

Memcache和Mongodb的配合

其实有了Memcache和Mongodb我们甚至可以让80%以上的应用摆脱传统关系型数据库。我能想到它们其实可以互 相配合弥补对方的不足:

Memcache适合根据Key保存Value,那么有的时候我们并不知道需要读取哪些Key怎么办呢?我在想 是不是可以把Mongodb或说数据库当作一个原始数据,这份原始数据中分为需要查询的字段(索引字段)和普通的数据字段两部分,把大量的非查询字段保存 在Memcache中,小粒度保存,在查询的时候我们查询数据库知道要获取哪些数据,一般查询页面也就显示20-100条吧,然后一次性从 Memcache中获取这些数据。也就是说,Mongodb的读的压力主要是索引字段,而数据字段只是在缓存失效的时候才有用,使用Memcache挡住 大部分实质数据的查询。反过来说,如果我们要清空Memcache中的数据也知道要清空哪些Key。

作 者:lovecindywang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。