#2 楼 @jeff_duan 新站从老站系统二次开发,老站原本是 mongodb,数据迁移脚本在这里 https://github.com/chloerei/campo/blob/import/lib/tasks/import.rake 。
#2 楼 @jeff_duan 另外这个标题的主语是“我”。
迁移作为一个词语时,它的意思是离开原来的所在地而另换地点或由于自然力的作用从一地移向另一地。在心理学中,它指的是是一种学习对另一种学习的影响,指在一种情境中获得的技能、知识或态度对另一种情境中技能、知识的获得或态度的形成的影响。
推荐这个视频 Rails Conf 2013 Postgres, the Best Tool You're Already Using by Adam Sanderson
演示文档
好文。
再补充一个关于 link/denormalize/cache 的观点,来自 Sarah(Dispora 主要开发者之一) 的一篇文章: http://www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb/
Dispora 最初是基于 MongoDB 开发的,后来因 production 中的种种问题,后来被迫转到了关系型数据库。
Denormalization 是 MongoDB 的特定,但同时也是一个应用场景的很大限制。
有一段是关于 link(relationship) 的
Whether you’re duplicating critical data (ugh), or using references and doing joins in your application code (double ugh), when you have links between documents, you’ve outgrown MongoDB. .... If your data looks like that, you’ve got documents. Congratulations! It’s a good use case for Mongo. But if there’s value in the links between documents, then you don’t actually have documents. MongoDB is not the right solution for you
她认为 MongoDB 的 denormalize 在本质上就是 cache, 而把 cache 和实质数据存储混在一个层面有很大的问题。如果用关系型数据库,大不了使用核武器 -- 摧毁所有 cache 然后重建。但混在一起的话连这个核武器都没有了。
You can always delete the entire activity stream record out of your cache and regenerate it from your consistent backing store. It may be slow, but at least it’s possible.
What if there is no backing store? What if you skip step 1? What if the cache is all you have?
When MongoDB is all you have, it’s a cache with no backing store behind it. It will become inconsistent. Not eventually consistent — just plain, flat-out inconsistent, for all time. At that point, you have no options. Not even a nuclear one. You have no way to regenerate the data in a consistent state.
When Diaspora decided to store social data in MongoDB, we were conflating a database with a cache. Databases and caches are very different things. They have very different ideas about permanence, transience, duplication, references, data integrity, and speed.
#10 楼 @billy 我以前看过这篇文章,不太同意前半篇举的例子
MongoDB 提供了嵌入文档的功能,不意味所有能嵌入的地方都要嵌入,这种多个地方共享的数据不应该嵌入。这像是故意用错然后说工具不好。
我会这样设计:
// users
{
_id: 1,
name: Joe
}
// streams
{
_id: ...,
user_id: 1,
activities: [id, ...]
}
// activities
{
_id: ...,
user_id: 2,
title: 'today',
body: 'go fly a kite',
like_ids: [3, 1]
}
页面视图再缓存一次。
结构型的元数据存 Mysql,大量的自包含的数据(如交易日志)存 NoSQL,充分结合 2 者的好处。没有必要只用一种,NoSQL 概念很火,但是实际上面应用还是要多多考虑。我听过 netfix 的分享,他们把 oracle 换成 NoSQL 之后,发现有一些问题,主要是数据完整性方面的,然后他们就把架构改成了我上面说的那种
为什么我从 PHP 迁移到了 Ruby? 为什么我从 Ruby 迁移到了 Nodejs? 为什么我从 Nodejs 迁移到了 Go? ......
对于类似这样的标题,我总是想说:你好蛋疼。
一个功能如果能设计成即时的就不要设计成延时的,能够设计成延时的就不要设计成定时的,即使是统计类功能——Google Analytics Real-Time 报告有感。
每次遇到开发者说“这个数量每天晚上统计一次就行了,用户不会发现不一致的。。”“这个排名几天统计一次就行了,用户不关心的。。”,我就想问“既然这么不重要做这东西干什么”。
很遗憾,如果程序员可以影响到产品功能那这个世界会美好很多,程序员只要做出来,而且不影响服务器的性能就是胜利。也不要和我说“不想参与产品功能设计的不是好程序员”,正是要先完成本职工作才能有话语权。
@hooopo 从 Google Analytics 报告就宣称自己的做法是 Best Practice,那我的做法也是 Best Practice。
你确定 Google Analytics 不是采用异步实现的?我觉得你说的“把实时变成了定时是倒退。”一开始就搞错了概念,我们讨论的是数据的收集和存储,你讲的是用户是不是可以第一时间看到前面的统计结果,这是两个问题,Google Analytics 的实时是说在 Dashboard 上可以“实时”看到最近的统计,他的数据收集也是异步处理的,Google 并不是你跑去点击 report,然后他在跑去帮你统计。
系统会不间断地更新数据,每当有用户浏览网页时,您都可以在几秒钟内看到相关的报告。
至于标签云,标签有变化后,触发统计事件,根据你的访问量的情况写到 redis 或者 db 中,这是我觉得比较好的实践,从需求上讲 @nouse 说的每天统计也是很常见的,当然你可以说每个小时计算一次比较好或者按照事件触发比较好,但是你后面举得几个夸张的例子完全跟讨论无关
PostgreSQL 还是蛮强大的,除了 array 和 hstore 外还可以直接支持 json,简单的嵌套数据和少数的可变字段都可以存到 json 里面去。
我想知道,用 PostgreSQL 后,因为事务的问题,参考:https://ruby-china.org/topics/19499?page=1#reply28
隔离级别是修改为repeated read
还是说使用默认的+乐观锁
呢?