我的MongoDB设计思路很简单,就是类关系型数据库。操作中大量使用Mongoose的population做关联查询。一直感觉这种设计方式别扭,求教各路大神,如何设计MongoDB?
说明你不会用mongodb,你这样还不如你去用mysql。
nosql换句话说,是以空间换时间
@biggerV 你的确看清了真相,但是能说一下如何设计吗?搜索到的都是大话
@qujinxiong 你的场景直接用 mysql 有什么不好?
@alsotang 现在回头看确实可以直接用mysql,但是如果就是想用mongodb呢?求mongodb设计方案
为了MongoDB而用MongoDB吗?
@qujinxiong 做 population 感觉最方便的还是在 mongoose 里面定义关系,然后 mongodb 的表就按 mysql 的范式设计就好了。
@alsotang 是啊,通过population就可以把mongodb设计的和mongoose一样
@jiangzhuo 不是为了用而用,是前人选型已选好了,现在不会做mongodb的设计
我是开发网络游戏的,现在用的是mongodb , package 用的mongoose . 设计的时候, 基本上是按照mysql 的思路去设计docoment。 游戏中每一个玩家有唯一的ID :uid , 然后其他的相关的表,都会包括一个uid字段。 userSchema { _id : 使用默认的ObjectId类型 } 例如关卡表: mission schema设计如下 {uid : String, missionId : String, status : Number, createTime : Number } 这里的uid 就是userSchema 的_id
游戏里面的功能大都是独立的,所以关系性 不是特别强, 用uid 去关联足够了,业务逻辑写起来也非常的简单
@NextZeus 我也是这样的设计思路,这样的设计是可以解决问题,只是没有发挥出非关系型数据库的优势。可惜网上只能看到一些说的很宽泛的指导,实际操作会很麻烦。比如看到有人说,所有的数据存在一张集合,简直不能想想如何实操。还有的说,实际上根据mongodb的文档也能看出来,mongodb的设计者也是不提倡使用ref。但是不用ref,如何去设计数据库??这就是我的疑问所在
@NextZeus 网游中的金钱事务操作怎么实现的?
@qujinxiong 用ref关联的话,感觉有点蹩脚,我这边没有用。要说发挥非关系型数据库的优势,mongodb对比mysql的优势不止一点,比如说在数量级别达到一定程度情况下,mongodb比mysql的非索引查询快很多,大量数据的情况下,mongodb比mysql性能要高许多, 这只是说一个优势吧 , 其他肯定还有 。 这就要看 你想要发挥mongodb的哪方面的优势了 。
@idreamshen mysql事务,我的业务里没有用到。基本上都是最简单的CRUD操作,另外写个工具方法,检测下数据的正确性。
这就是捡个东西就当宝的结局
@NextZeus 你说的用uid关联是怎么实现的
@yakczh 不是什么时候都有选择机会的
@yakczh 而且node里面用mongodb的确比用mysql查询起来顺手
@qujinxiong 选择 > 努力
@qujinxiong 比顺手
User.where('username', '=', 'xx').fetch().then(function(user) {
console.log(JSON.stringify(user));
});
User.where('username', '=', 'xxxx')
.save({
username: 'oooo',
password: 'xxoo',
role: 99
}).then(function(res) {
console.log(JSON.stringify(res));
}).catch(function(err) {
console.log(err);
});
User.where('id', '=', 7)
.destroy()
.then(function(res) {
console.log(res);
})
.catch(function(err) {
console.log(err);
});
如果只是查询一些固定的字段,可是试试多做几个冗余字段,,就是维护数据的时候麻烦点,事实上我们这边项目都是这么用的,虽然看上去很low,
@nnliang 就是考虑到一各地方改,其他地方都要改才用了ref
@alsotang 我也是这样的设计思路,这样的设计是可以解决问题,只是没有发挥出非关系型数据库的优势。可惜网上只能看到一些说的很宽泛的指导,实际操作会很麻烦。比如看到有人说,所有的数据存在一张集合,简直不能想想如何实操。还有的说,实际上根据mongodb的文档也能看出来,mongodb的设计者也是不提倡使用ref。但是不用ref,如何去设计数据库??这就是我的疑问所在
userSchema = new mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId, //默认不需要定义
});
var userInfo = new userSchema({});
userInfo.save();
//关联
otherSchema = new mongoose.Schema({
uid : String //指的是userSchema的_id
});
var otherDocument = new otherSchema({
uid : userInfo._id
});
@yakczh 请问有何依据 说这样的对比?
@qujinxiong 数据量大不大?数据量不大的时候,按最方便编程和理解的方式来做,不要考虑那么多性能和所谓nosql的优势。数据量大的话,详细描述场景和数据结构,我再帮你看看。
@idreamshen 2段提交模拟事务,现在在做涉及到金额的操作,写起来很冗长
@alsotang 数据量不大,现在按照关系型数据库设计模式做完全能实现功能,只是心理上有点过不去。因为我用了大量的ref,而mongodb的官方文档对ref的介绍几乎一笔带过,意思就是不鼓励mongodb使用ref。下面是我设计的一个集合,用了四次ref。 var orderSchema = new Schema({ orderNo: {type: String, default: “”}, createTime: {type: Number, default: Date.now}, owner: {type: Number, default: 0,ref:‘User’}, medicineList: {type: Array, default: []}, serviceFee: {type: Number, default: 0}, medicarePaid: {type: Number, default: 0}, totalPrice: {type: Number, default: 0}, totalQuantity: {type: Number, default: 0}, orderState: {type: String, default: ‘待付款’}, logisticsState: {type: String, default: ‘去支付’}, seller: {type: Number, default: 0,ref:‘Hospital’}, consignee_id: {type: Number, default: 0,ref:‘Consignee’}, paymentMode: {type: String, default: ‘’}, signBy: {type: String, default: ‘’}, signTime: {type: Number, default: 0}, courier: {type: Number, default: 0,ref:‘User’}, getPackageWhen: {type: Number, default: 0}, packageReadyWhen: {type: Number, default: 0} });
@qujinxiong 反正你们一开始数据库选型就有问题,就不要纠正美不美的问题啦哈哈
@alsotang 感觉是正解