月度归档:2013年02月

mongodb初学习

目前学习使用mongodb,主要是一个项目中使用到了地理位置服务相关的内容。比如发布一个活动,客户端自动将当前位置获取到一同存储到后端;可以利用数据库中的地理位置信息实现如“附近的活动,附近的人;在地图上展现附近的活动、人”等功能。

原先的这些location功能实现是一并采用mysql建表实现的。

[mysql]

CREATE TABLE `i_event_locations` (
`event_id` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘活动id’,
`name` varchar(255) NOT NULL DEFAULT ” COMMENT ‘Name’,
`address` varchar(255) NOT NULL COMMENT ‘Address’,
`lat` double NOT NULL DEFAULT ‘0’ COMMENT ‘纬度’,
`lng` double NOT NULL DEFAULT ‘0’ COMMENT ‘经度’,
`created` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘创建时间’,
`updated` int(10) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘更新时间’,
UNIQUE KEY `event_id` (`event_id`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT=’Location Table’

[/mysql]

表结构就是如此,需要说明的是活动event与location是一对一的关系,event_id就是活动id即是外键也是主键。

这样的结构在后端业务中怎么实现呢,主要思路就是通过传入经纬度得到一个表达式distance,在event与location进行join联表查询时按distance进行desc的排序,得到最近的event list;如果需要限制在10km之间,那么就需要加上where distance < 10000


/**
* 返回计算距离的SQL语句表达式
* @param $lat
* @param $lng
*/
private function get_distance_exp($lat, $lng){
return DB::expr("(2 * 6378.137* ASIN(SQRT(POW(SIN(PI() * ($lat - lat)/360), 2) + COS(PI() * {$lat} / 180)
* COS(lat * PI() / 180) * POW(SIN(PI() * ({$lng} - lng) / 360), 2))))*1000");
}

就是上面这个东东,我也没看明白是什么原理。总之它返回的是以米为单位的一个数据值。

弊端确实有,需要联表查询且还要计算表达式可能会比较慢。(详细性能测试暂没有进行)

确实需要了解下性能方面的问题了,不能只听别人说mysql这样处理很慢就觉得慢,听别人说mongodb用的快就用;

mongodb是文档化schema free(自由格式)的数据库,开源有商业团队支持,高速发展,应用广泛;与mysql不存在谁取代谁的问题,只是什么环境下哪种数据库更适合。

回到那个地理位置检索的问题,将i_event_locations转变为mongodb collection后,可以根据建立的loc二维索引进行当前location 经纬度的检索,这样就得到了所有的event_id值,在通过这些event_id的到符合需求条件的event活动;

这样也就不用进行联表查询以及地理位置的表达式运算(这部分目前直接交予索引处理了);

MongoDB的特性 来自blog.nosqlfan.com

  • 简单的查询语句,没有Join操作
  • 文档型存储,其数据是用二进制的Json格式Bson存储的。其数据就像Ruby的hashes,或者Python的字典,或者PHP的数组
  • Sharding,MongoDB提供auto-sharding实现数据的扩展性
  • GridFS,MongoDB的提供的文件存储API
  • 数组索引,你可以对文档中的某个数组属性建立索引
  • MapReduce,可以用于进行复杂的统计和并行计算
  • 高性能,通过使用mmap和定时fsync的方法,避免了频繁IO,使其性能更高

MongoDB的优点

  • 高性能,速度非常快(如果你的内存足够的话)
  • 没有固定的表结构,不用为了修改表结构而进行数据迁移
  • 查询语言简单,容易上手
  • 使用Sharding实现水平扩展
  • 部署方便

使用MongoDB,你得记住以下几点:

  • MongoDB 假设你有大磁盘空间
  • MongoDB 假设你的内存也足够大于放下你的热数据
  • MongoDB 假设你是部署在64位系统上的(32位有2G的限制,试用还可以)
  • MongoDB 假设你的系统是little-endian的
  • MongoDB 假设你有多台机器(并不专注于单机可靠性)
  • MongoDB 假设你希望用安全换性能,同时允许你用性能换安全

MongoDB在下面领域不太擅长

  • 不太稳定,特别是auto-sharding目前还有很多问题
  • 不支持SQL,这意味着你很多通过SQL接口的工具不再适用
  • 持久化,MongoDB单机可靠性不太好,宕机可能丢失一段时间的数据
  • 相关文档比较少,新功能都有这个问题
  • 相关人才比较难找,这也是新功能的问题之一

安装mongodb

要学习使用,首先下载mongodb

windows 32位平台下也可以安装但是数据容量最大只有2G,可以作为测试学习之用,不推荐作为工作生产环境。

Linux 64位则最大可以达到128T,所以推荐linux平台上部署。

mongodb下载后解压到目录后

进入bin里面执行下面命令

–dbpath 是mongodb数据库文档存储目录,–logpath 是mongodb的日志文件,–install 则是将mongodb安装到系统服务里面去。要了解更多命令执行mongod –help查看。

执行完成后检查mongodb.log要是没有错误信息,则通过http://localhost:27017可以看到

You are trying to access MongoDB on the native driver port. For http diagnostic access, add 1000 to the port number
则说明成功了。而访问http://localhost:28017 可以查看mongodb的监控信息。

注意这里第一次安装没有成功时,mongodb_data里面新生成的的mongod.lock 可能会被锁住,再次安装时会产生

dbexit: really exiting now

这时需要删除掉mongod.lock,重新进行安装。

注意在windows xp 下面安装时可能会出现“无法定位程序输入点 InterlockedCompareExchange64 于动态链接库KERNEL32.dll上”

原因就是这样

“Mongodb最新的开发分支已经不再支持xp,也就是说vista是最陈旧支持的客户端,windows server2003是最陈旧的windows服务器版本,但是2.0的分支任然支持着xp,V2.0.6是最新也是最后一个新版本支持xp。因此最好还 是在 linux 下开发吧。”

我的windows xp安装版本是

db version v2.0.6, pdfile version 4.5
Wed Feb 27 22:24:02 git version: e1c0cbc25863f6356aa4e31375add7bb49fb05bc

所以还是推荐最新平台最新版本吧。

MongoDB shell命令

MongoDB自带一个JavaScript shell, 以命令行与MongoDB实例交互。

可以执行管理操作,检查运行实例等

启动Shell:

$ ./mongo

可以运行任何JavaScript程序,还可以利用JavaScript的标准库。所以所有的对象方法都是区分大小写的,输入命令时要注意!

可以定义和调用JavaScript函数。

可以使用多行命令。

show dbs; — 查看数据库

show databases;  –查看数据库

use dbname; –选择数据库

show collections; –查看表

show tables; –查看表

db.tablename.find(); — tablename的数据查询,

db.tablename.find({a: ‘k’}); — 对a字段进行数据k的匹配检索查询

db.tablename.find({a:’k’}).sort({id: -1}); –对a字段进行数据k的匹配检索查询且按照id进行倒叙排列,反之1则是正序排列了

db.tablename.find({a:’k’}).limit(5); –对a字段进行数据k的匹配检索查询只返回最初5条记录

db.tablename.find({a:’k’}).skip(2).limit(5); –对a字段进行数据k的匹配检索查询从第二条开始返回5条记录。skip()限制返回记录的开始点,就等于是mysql里面的offset

db.tablename.save({a: ‘haha’, id:’22}); — 添加新的记录

db.tablename.update({id: 22},  {$set: {a: ‘xixi’}}); — 对id为22的字段a进行修改;即第一个参数是query(也就是mysql中的where),第二个参数修改内容集合,还有第三个参数就是update时的一些设置;

db.tablename.remove({id:22}, 1); — 删除id为22的记录,第一个参数为where,第二个参数为limit,比如为1则只删除查询结果中的1条

db.tablename.drop(); –删除当前的表,drop()不同于remove(),remove只是清空数据,drop直接数据连同表删除了

db.dropDatabase(); –删除当前的数据库

mongodb crud manual

db.location.ensureIndex({loc: 2d}) –对location构建2d 地理位置的索引,{id: 1}设置为1则是正序索引,-1倒序索引;1(ascending),-1(descending)

db.location.getIndexes(); –查看location的索引。

db.location.getIndexKeys(); –查看location的索引keys。

db.location.dropIndex(‘loc’); –按索引名字删除索引,注意这里不是字段的名字

db.location.count(); –查询表中记录数

 

mongodb数据导出,不是进入到mongo shell里面去,

mongodump -d databasename -o D:/dirname -u username -p  –等于是mysql的mysqldump命令一样。

有导出当然有导入咯。

mongorestore -d test D:\mongodb_bak\test -u admin -p –还原test数据库

mongodb不推荐使用mongoexport与mongoimport来进行导出与导入;而是推荐使用mongodump与mongorestore来进行。

 

 

mongodb权限验证

mongodb 默认是无权限验证就可访问的。所以需要开启auth用户验证,需要在mongod安装时加上 –auth参数

Control Access to MongoDB Instances with Authentication

加入–auth参数安装好mongodb后;可以使用下面的进行用户设置

— 超级管理员,所有数据库都能访问

use admin

db.addUser(“username”,”password”);

— 普通管理员

user exampledb

db.addUser(“alex”,”alex”);

alex只能对exampledb进行查看管理

— 只读管理员,登录后只有读的权限

user exampledb

db.addUser(“alex”,”alex”,true);

 

对比之前的无认证环境,可以看到现在都出现了need login的信息内容了。

那首先就login

db.auth(“username”,”password”);  返回的是1,表示这个用户匹配上了,也就是登录成功了。

 

还有一种就是keyFile的方式,

Specify the path to a key file to store authentication information. This option is only useful for the connection between replica set members.

指定的密钥文件的路径存储身份验证信息。此选项只适用于副本集成员之间的连接。(没明白这个副本集成员之间的链接是什么意思)

同样是在安装时指定 mongod –keyFile filepath

keyFile 必须小于1kb,只是包含base64的字符;密钥文件没有组且具有 “world” permissions on UNIX systems

+++++

unix world permissions

unix的世界权限是个啥呢?Unix Permissions

找到了一篇解答

The third group of permission bits corresponds to the world permissions. These are the permissions granted to everyone.

也就是每一个人都具有这个权限,任何人都有这个权限。

+++++

在windows system上面不检测权限。

更多请看:Security Considerations for Replica Sets

 

 

 

更多命令看这里

学习资料推荐

MongoDB Manual

MongoDB资料汇总专题

MySQL和MongoDB设计实例对比

Php Mongodb Manual

MongoDB php driver

Php mongodb-odm

Kohanaframework mongodb module

从PHP客户端看MongoDB通信协议

2012这一年

现在已经是2013 2月13号了,大年初四;在元旦就开始计划需要写下2012这年所发生的事情以及验证检验下年初制定的计划完成度。

首先回顾下去年的总结文章。

2011年末总结系列之工作篇

2011年末总结系列之个人的生活篇

2011年末总结系列之个人情感篇

工作

2012 年前半年还是在忙mpf项目内容,还是一如既往的discuzx二次开发;下半年的时候再次看那些N复杂已经绕弯弯的业务需求真是不知道当初是怎么做出来 的。。。而且最关键的是,时间一长就忘了了这些代码为什么这样写(要是由他人后期维护真的会很纠结。)且不论需求的复杂度;就是一点被他们今天要一个A, 明天要一个B,且最关键的一点是我们的建议他听不进去,当初作死做活的功能,现在一句话就不要了。虽然公司是不亏的,但作为程序员来说这种东西一点成就感 也没有。

mpf从3月开始一直开发到7月,7月-8月就是由我一个人开发了。另一组员L调至一个移动应用开发组里面去了。然后其中主要开发 的一个需求是“将只能通过虚拟货币购买积分改为不仅能通过虚拟货币购买积分,还能直接通过RMB直接进行积分购买”。原先设计就是只能是余额足够的情况下 进行虚拟商品的购买,即只有记录的概念而没有订单的概念。而现在要的是在余额不足情况下,需要自动跳转至支付平台进行在线支付完成购买。

功 能设计不算复杂,但是最最麻烦的地方在于以现有代码的基础上进行修改。也就是改比新开发还有麻烦的事情被我碰上了。。。既然如此,现在网站以上线,且数据 量都已存在;那么现在的网站数据库结构就不能大调整了,只能加不能减。即代码最后都作用于新的数据库表上面,原始数据库表只要把数据导入到新表中,保持用 户的数据一致就行了。在完成设计后开发大概用了2个星期左右,又用了两个星期进行检查,测试,数据导入;集成了paypal,对discuzx自有的 alipay、tenpay进行了修改。(话说如果时间长了,估计我都不知道为什么这样写了,不过还好注释不少不少)

在mpf告一段落后, 公司决定暂时搁置这个项目(主要是给钱不积极啦)我就加入到了informatree项目组中,这个项目只是大概了解。公司从3月份开始立项,一直开发至 今;是一款主攻欧美国外市场的IOS、Android平台社交活动类的一款APP,大家可以再App store 里面搜索“intreest”下载安装。官网这里

intreest 这个项目周期也是比较长,app最新已经1.2版本了。移动应用采用前端+后端服务器的模式,与之前常见的b/s模式不同,在初期加入开发的过程中不是很 习惯啊。大致请求流程就是app通过TOKEN验证的api,向服务器发送一个请求,服务器验证token+有半小时时间期限的hash值(这个hash 主要用于api权限验证,只有app与服务器知道,避免有人知晓token后无限次的请求访问),验证通过后服务器将数据值json格式化返回给app。 到此完成一次请求。这个项目里面确实学到了不少东西,主要是oo方面构建对象后对数据的操作,以及各种微博系统,地理位置的业务逻辑熟悉使用,搜索方面使 用Apache solr进行数据检索。当然技术方面还是略显不足,很多地方只是原搬照用,还要加强学习。还有一个比较遗憾的地方就是在这个项目期间有三位开发方面的人员 离职了。

这 一年里,个人的技术风格以及定位有一个初步的认识,但并没有完全做好打算去怎样怎样,这也是自己不自信的原因。没错,你是做了很多事,但是这些事情都是 他人可以直接替代的,你的特长时什么?你的风格是什么?你未来的道路是什么?现在我还不能完全答复。这也是要在2012年里面更加的清晰和明了的。很多事 情充满了变数,又有很多事情难以改变的。比如你的性格,我的强迫症。

这是去年的一段话,我想把2012换成2013也是适用于今年的。。。改变一点都没看见啊。技术风格?特长,优势?哎。。。继续前行吧。

 

生活

生 活还是如此,平静而简单。今年就是多了一个看球,由于恒大的牛x,在亚冠中超牛xx的。向我这种伪球迷当然也就是“趋之若鹜”了,不是我不喜欢英超西甲, 而是我始终认为那种情况离我太遥远,没有一种情感代入感;所以还是好好看看家门口的中超吧,尽管现在他的水平还很低,但还是一如既往的支持。2013还看 恒大!当然武汉队也要看看!

老爸手工业制作者,房租突然涨了一倍,真的很贵快3000/月了。但是房子没有变大,地理位置也没有变得优势;万恶的房东啊,另一个房东却还是维持原价,差距怎么这么大呢!这样生意将变得更加难了,希望2013年里面好做,蛇年万事如意!

在1月的时候老爸新买一个“五菱之光”微面,4w多元,老妈说这是多年攒下的钱了。。。老爸一直希望有个车,这下终于买了,得了那就安心好好挣钱,平安开车吧。

朋友联系的还好,他们现在都还不错;只是见面相聚较少,真是越长大与孤单啊。

公司同事相比第一年来到时,2012大家出来相聚的时间更少了,可能人真的会厌倦吧。

表哥腊月24的结婚了,是介绍认识的,大概半年吧。其实我始终认为这样的婚姻感觉有那么些不自主,当然也就偏见的认为这不是男女主人自己想要的。但现在不管怎样,祝他们幸福。

 

情感

“在之前的生活篇里面也提到了,2012年龙年,第二个本命年里,我最大的期望与理想就是找到一位适合的、相爱的、谈婚论嫁的女朋友!这一目标在2012年里要坚定不移的执行实施!立字为证,明年这个时候,写文汇报。”

这文是写不出了,因为在自己的本命年里面,女朋友这一重要元素还是竹篮打水一场空。尽管做过一些努力但是很多时候我都不知道我喜欢什么样的,看这个也喜欢,看那个也喜欢。得到一个真理,网络上的都是假的!!还不如勇敢的在现实里面搭讪吧。

蛇年里面一定要有新动向啊!要不然就要被逼婚了。。。%>_<%

 

 

2013路还是继续走,希望能顺利一点。