MongoDB数据库设计思路
发布于 7 年前 作者 JarvisQJ 11482 次浏览 来自 问答

我的MongoDB设计思路很简单,就是类关系型数据库。操作中大量使用Mongoose的population做关联查询。一直感觉这种设计方式别扭,求教各路大神,如何设计MongoDB?

30 回复

说明你不会用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 比顺手

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,如何去设计数据库??这就是我的疑问所在

@qujinxiong

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 感觉是正解

回到顶部