写这篇文章的时候,我都想笑,谢谢唐建法老师,一天搞的 2群满500,六群狂进人,群里多了50个人,OMG你们是想让我开9群的速度。是的成功的人,大家都想追逐,凭借一己之力拉来2000万美元,世间又有多少人可以做到,可背后的心酸和苦楚,又有谁知道,他们又能和谁说,我记得有句话,英雄大多都是孤独的,只有在别人都倒下了,他还能微笑的站着,不是身体还能支撑,而是精神的能量巨大,且我等凡人只能探究外表,不能达到内心。
专访唐建法-从MongoDB中国第一人到TapData掌门人的故事
MongoDB 双机热备那篇文章是 “毒”
可能是MongoDB是数据库业界的一朵奇葩,吸引了唐老师曾经加入到这个成功的数据库公司共同发展,创造万人NoSQL社区的神话,如果MongoDB用现代流行的占星学观点,算是十二星座里面的水瓶座,人称火星人。一般人要理解且明白水瓶座的思维,估计是困难了点,因为水瓶座都是在用上帝视角来看问题,且大部分时间他们都是在向下兼容你。我为什么要说MongoDB是水瓶座,参见下方水瓶座注解:
水瓶座的人不容易改变自己的意见或主张,但另一方面却又极端厌倦和别人争执。有时在要跟别人起正面冲突时,他们会装做完全听不到众多指责声音的样子,而只按自己的想法行事,或许这也是你听到太多其他数据库替换MONGODB,且MongoDB少有把他替换别的数据库的事情宣扬出去的一个原因。
完全听不到,指责的声音,MongoDB被指责的不少,大部分时间他都在,I don't care, who do you think you are !的状态中。
可能是最近一篇和MongoDB 有关的文章,让很多人有了对MongoDB产生了兴趣,在群里问要书的事情,个人作为一个用了8年的MongoDB person, 想说说这些年见过的一些,一些人在学习MonogoDB中的“有意思”的问题。顺便科普一下,MongoDB的入门,作为一个十分愿意和喜欢和水瓶座交流的其他星座人士,我觉得人生认识几个水瓶座的人,是一件非常棒的事情,高级的水瓶座看问题很准,很有逻辑,且愿意和你去讲述原理。
问题1:MongoDB 丢数据是真的吗?
呵呵,说到这个问题,我只想笑,一个数据库如果丢数据,他还能活那么多年,且成为数据库行业的NOSQL一哥,你信吗,然后你问MongoDB 丢数据吗?我觉得你去看看脑子比较好,那个肯可能对你更重要。首先要说明,MongoDB 不丢数据,如果MongoDB丢数据了,那么一定是使用MongoDB的人,有问题,或者说他根本没有懂MongoDB的形成方式,所导致的问题。MongoDB 在生产环境是一定要至少3台主机的,也就是MongoDB Replica,这是一种基本的MongoDB的安装及使用的模式,不要说我单机用MongoDB行不行,你这个问题和问,我用一条腿走路行不行。行,那你就等着摔跤,行,那你就等着MongoDB给你丢数据。
所以MongoDB不丢数据,如果有人说他们家的MongoDB丢数据了,就可以认为为他根本不会使用MongoDB 而已。
这主要是基于MongoDB在设计之初,就是为了云和本地共同使用的产品,在云上分布式的产品要保证数据的安全,并不是完全基于单节点来完成的,而是基于多节点写来保证的,也就是一条数据需要至少在两个MongoDB节点写来完成数据的不丢失,所以再次重申MongoDB不丢数据,不丢,谁在说MongoDB丢数据,那只能展现你的无知和无畏。
问题2:MongoDB 只能存Json数据
MongoDB 能存Json,但MongoDB只能存Json ,这是哪个大师告诉你的??MongoDB除了进行复杂的json存储,计算,聚合,同时还是一个大型的文件分布式存储数据库,此时那些传统数据库都不行了吧?行你给我们存个大量的音频,视频文件,你要敢,DBA 不打死你的。MongoDB是有特殊的方式来存储,视频,图片,音频等文件,且用分布式的方式,来满足一些分布式文件提取,且保证完整性要求的业务场景。
问题3:MongoDB 写入数据后,读不到
这个问题问的最多,这一定不是MongoDB的问题,谁说写入数据后就一定要读到,如果要读到你是否理解MongoDB的5个readPreference(),此时你是否把你的readPreference,调整到了primaryPreferred,如果你调整到这个这个位置,那么还读不到,那么你就快看看你的集群还稳定吗,这就是另一个话题了。
1 primary:指示驱动程序只从主节点读取数据。如果主节点不可用,则抛出错误。
2 primaryPreferred:优先从主节点读取数据,但如果主节点不可用,则从副本集成员读取数 据。
3 secondary:只从副本集成员读取数据,不管主节点的可用性。
4 secondaryPreferred:优先从副本集成员读取数据,但如果所有副本集成员都不可用,则从主节点读取数据。
5 nearest:从离客户端最接近的节点读取数据。该模式将根据各个节点的延迟和负载情况来选择。
const MongoClient = require('mongodb').MongoClient;
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri, { useNewUrlParser: true });
client.connect().then(async () => {
const db = client.db('mydatabase');
const collection = db.collection('mycollection');
// 设置不同的读取偏好模式
const result1 = await collection.find({}).readPreference('primary').toArray();
const result2 = await collection.find({}).readPreference('primaryPreferred').toArray();
const result3 = await collection.find({}).readPreference('secondary').toArray();
const result4 = await collection.find({}).readPreference('secondaryPreferred').toArray();
const result5 = await collection.find({}).readPreference('nearest').toArray();
console.log(result1);
console.log(result2);
console.log(result3);
console.log(result4);
console.log(result5);
}).catch(err => {
console.error(err);
});
问题 4:我链接MongoDB,切换后我就没法写数据了?
这个问题还是个人没有掌握MongoDB的链接串的使用方式,MongoDB并不是写一个主库的链接串给应用就可以了,而是应该写三个节点的统一的连接串给应用,在节点切换后应用会自动找到对应新的主节点,并写入数据,这些都是自动的,并不需要像POSTGRESQL ,MYSQL那样的中间件,或者DNS切换系统,因为这些都在MongoDB的数据库内集合了这个功能,这也就是说MongoDB是目前为数不多的,集成了节点切换后,应用自动连接到新主和读上的功能的数据库产品。
const MongoClient = require('mongodb').MongoClient;
// Replica Set URI
const uri = 'mongodb://host1:27017,host2:27017,host3:27017/mydatabase?replicaSet=myReplicaSet';
// Create a new MongoClient
const client = new MongoClient(uri, { useNewUrlParser: true });
// Connect to the MongoDB Replica Set
client.connect().then(() => {
console.log('Connected to MongoDB Replica Set');
}).catch(err => {
console.error('Error connecting to MongoDB Replica Set:', err);
});
问题 5 MongoDB可以双机热备吗?
不可以,不可以,不可以,原因参见
MongoDB 双机热备那篇文章是 “毒”
问题 6 MongoDB 有没有事务,可以不可以有事务?
可以,MongoDB 可以有事务,表达的方式不同,可以有循环,事务,跨库事务,跨表事务等 下面是一个案例,异步事务
const mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017';
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
const session = mongoose.startSession();
session.withTransaction(async () => {
const db1 = session.client.db('database1');
const db2 = session.client.db('database2');
// 在db1的collection1中插入数据
await db1.collection('collection1').insertOne({ name: 'John' });
// 在db2的collection2中更新数据
await db2.collection('collection2').updateOne({ name: 'Alice' }, { $set: { age: 30 } });
})
.then(() => {
console.log('Transaction committed successfully');
})
.catch(error => {
console.error('Transaction aborted:', error);
})
.finally(() => {
session.endSession();
});
其实写到这里,我知道还有许多的问题,比如MongoDB是可以没有表就建立索引吗,MongoDB是没有表就可以建立约束吗,MongoDB到底是自己生成主键好,还是自己定义主键好,等等!
所以如果MongoDB出现了一些你不理解的问题,你就尝试着想,可能问题在自己不了解他呢?善待身边的水瓶座,不定那天就给你带来真理和惊喜。
另外MongoDB一直在开展考MongoDB认证,MongoDB给你报销考试费的活动,我回来咨询后,可以写一篇文章来告知大家如何操作。
本文分享自 AustinDatabases 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!