MongoDb 非关系数据库 NoSql 数据库一员, 将数据使用灵活,类JSON形式进行存储。更多:what-is-mongodb

MongoDb is a member of the NoSql, it stores data in flexible, JSON-like documents.

概念 Concepts between SQL and MongoDb

SQL MongoDb
Table Collection
Row Document
Column Field
JOINs Embedded documents, $lookup & $graphLookup
GROUP_BY Aggregation -〉group by

操作 Operation between SQL and MongoDb

SQL MongoDb
INSERT INTO users (user_id, age, status) VALUES ‘bcd001’, 45, ‘A’) db.users.insert({ user_id: ‘bcd001’, age: 45, status: ‘A’})
SELECT * FROM users db.users.find()
UPDATE users SET status = ‘C’ WHERE age > 25 db.users.update( { age: { $gt: 25 } }, { $set: { tatus: ‘C’ } }, { multi: true })
db.start_transaction() cursor.execute(orderInsert, orderData) cursor.execute(stockUpdate, stockData)

db.commit()|s.start_transaction() orders.insert_one(order, session=s) stock.update_one(item, stockUpdate, session=s)s.commit_transaction() (new feature in 4.0 version)|

最大区别 Biggest different between SQL and MongoDb

SQL MongoDb
使用关系型数据库, 需要在数据库中定义对应的表和字段关联。当你需要修改到对应的字段, 必须对数据库进行停机修改,会影响现有的所有数据, 降低应用可用性。In SQL, you pre-define your database schema based on your requirements and set up rules to govern the relationships between fields in your tables.Any changes in schema necessitates a migration procedure that can take the database offline or significantly reduce application performance. 使用MongoDb, 字段 无需在数据库中进行定义,使用代码定义对应的关系。如果需要添加一个新的字段,无需影响其他的document,无需停机进行更新。In MongoDb, Fields is no need to declare the structure of documents to the system – documents are self-describing in Code。If a new field needs to be added to a document,then the field can be created without affecting all other documents in the collection,without updating a central system catalog, and without taking the system offline.
更多的控制在数据库(DBA), 索引,字段 都需要在数据库进行定义处理More control in Db, Indexes. Filed all controlled in Db side. 更多的控制在代码(开发), 开发可以在代码中定义对应的索引,字段结构。Less control in Db, more control in Code. Indexes, Fields can controlled in Code side.

参考:mongodb-mysql

Select 只获取必要的字段

why:

select *会增加cpu/io/内存/带宽的消耗

指定字段能有效利用索引覆盖:find({id: “test”}).select({id: 1}) 命中索引id, 因只select了id, 所以mongo直接返回了id, 不会再索引到具体的document,效率大大提高。

避免过度使用嵌入文档,最多只能一层, 不使用数组嵌套

why:

document有16MB限制。

尽量避免使用负向查询以及%开头的模糊查询

why:

ne、nin %开头 无法有效使用索引

禁止使用look up

why:

分片后,look up操作失效

不在数据库中进行数据计算

why:

js精度问题 (0.1 + 0.2 = 0.30000000000000004__)

cpu计算导致数据库卡顿,解放数据库CPU,把复杂逻辑计算放到服务层。

平衡范式与冗余

为提高效率,可以冗余数据

拒绝大sql,大批量 操作

禁止在更新十分频繁、区分度不高的属性上建立索引

why:

更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能

“性别”这种区分度不大的属性,建立索引是没有什么意义的,不能有效过滤数据,性能与全表扫描类似

索引内存也是有限的

使用explain 优化查询

查看explain结果,

可以简单查看inputStages.stage判断查询效率。

COLLECTION:全表查询

IXSCAN:命中索引查询

禁止使用自带全文索引

why:

效率低

MongoDb_Demo

参考: mysql 50条军规

co流程控制

nodejs常见异步流程

使用回调

1
2
3
4

fs.readFile("./file.js",function(err,data){
console.log(data.toString());
})

使用promise

1
2
3
4
5
6
7

var Promise = require("bluebird")
var fs = require("fs");
fs = Promise.promisifyAll(fs);
fs.readFileAsync("./test.js").then(function(data){
console.log(data.toString());
})

使用co+promise

1
2
3
4
5
6
7
8

var fs = require("fs");
var Promise = require("bluebird")
fs = Promise.promisifyAll(fs);
co(function* (){
var data = yield fs.readFileAsync('./test.js');
console.log(data.toString());
})

结论:使用co模块编写代码,形式与同步代码一致,没有回调和then,逻辑更加清晰。

Read More

#mongodb3.* 设置用户认证

1、mongodb是没有默认管理员账号,所以要先添加管理员账号,在开启权限认证。
2、切换到admin数据库,添加的账号才是管理员账号。
3、用户只能在用户所在数据库登录,包括管理员账号。
4、管理员可以管理所有数据库,但是不能直接管理其他数据库,要先在admin数据库认证后才可以。这一点比较怪

添加管理员账号:
默认情况下系统中没有用户,正常启动mongo:mongod

Read More

1
As we know, 服务端程序一般都是运行在Linux系统中,而Linux下的一些日常软件,却没办法做到像Windows下那样的精美,so,问题来了:有没有办法做到在Windows上进行代码的编写,而运行是在linux下呢???

环境需求:

  • 虚拟机(vmware,vbox…)
  • Windows 操作系统

虚拟机安装linux

在Windows下想要同时使用到linux系统,果断是必须安装虚拟机的,如何安装虚拟机在这里就略过了,
一般服务器都是采用Centos系统作为服务器运行的Linux系统,所以我们选择一个centos的镜像网站
下载centos镜像浙江大学镜像,一般选择6.*版本的,这个是centos6.7版本的镜像路径:http://mirrors.zju.edu.cn/centos/6.7/isos/x86_64/ ,选择minimal版本iso镜像下载,不需要带桌面的,可以减少虚拟机的资源占用.
减下来就是安装了,略过.

设置虚拟机网络.

安装的Linux虚拟机我们会通过ssh进行连接,所以虚拟机和本机之间必须通过桥接模式进行连接.设置虚拟机网络桥接不同虚拟机有不同的设置方法,略过.

Read More

任务/成就系统

游戏中任务/成就系统是必不可少的,如何实现一个成就系统?

任务系统基本需求

  1. 检测玩家完成该任务
  2. 奖励
  3. 领取奖励有触发下一阶段任务

名词解析:

任务链:

同一类型的任务为一个链

如:
玩家连续登陆任务,连续登陆1天,连续登陆2天,连续登陆3天,…为一种类型的任务链
获得多少金币,
通过多少次副本,
加多少好友

Read More

相关

这次要介绍如何在谷歌插件中使用nodejs模块,演示的项目是 一个后台定时提醒的插件

运行环境

##基础框架搭建

###创建一个基础的chrome插件框架
可以从谷歌插件的github克隆相应的例子进行修改

基本架构只需要包含:

  • manifest.json (谷歌插件配置文件)
  • background.js (后台逻辑js文件)

##将nodejs库使用转化为浏览器可使用的库

Read More

##leanCloud介绍
官网:leancloud
LeanCloud 是国内的移动应用一站式云服务。
LeanCloud提供了数据存储、实时消息、统计分析以及多种扩展组件,全面涵盖移动应用开发的需求,支持 iOS、Android、Web 等多平台。
它帮助开发者摆脱后端开发负担以专注于产品创新,同时缩短开发周期、节省开发投入、快速进入市场。


很久之前看到baas的相关介绍,感觉自己要失业了,知道现在才有机会试用一下leancloud


##正文

###环境

nodejs
leancloud命令行工具

####下载安装nodejs
百度

####下载安装leancloud命令行工具(在已安装nodejs的基础上)
npm install -g avoscloud-code

环境搭建完毕

Read More

在使用tornado框架进行开发的过程中,发现tornado的mysql数据库操作并不是一步的,造成了所有用户行为的堵塞.tornado本身是一个异步的框架,要求所有的操作都应该是异步的,但是数据库这一层就把整个服务器都拖住了.

##查找到的解决办法:

  1. 使用异步的mysql操作库. 查找了一下,有两个比较完善的异步操作库
    一个是AsyncTorndb,国人自己写的异步操作,看了一下,好像不错的样子,但是没有响应的测试用例,不敢用.

    一个是Tornado-MySQL是对PyMySQL的异步化的一个库,测试用例,文档,都比较齐全,可以尝试使用.

2.仿照(torngas)[https://github.com/mqingyn/torngas]的异步线程池,使用tornado的concurrent.run_on_executor装饰器对数据库操作进行异步化

3.使用任务队列,太过麻烦,对之前的代码修改过大,不使用该方案

  • 在使用Tornado-MySQL过程中,发现对现有代码更改太过严重,放弃,使用了异步线程池的方式.做到最小的代码更改以及异步数据库操作的实现

##如何使用异步线程池concurrent.run_on_executor

  1. 在原先的同步的数据库执行的方法添加@concurrent.run_on_executor装饰器,如以下例子:

    1
    2
    3
    4
    5
    6
    7
    @concurrent.run_on_executor
    def runSql(self):
    t = time.time()
    db = client.conn()
    db.execute('''select * from TABLE_CONSTRAINTS join (CHARACTER_SETS,STATISTICS)''')
    db.close()
    return time.time() - t

Read More