至于你举得例子,“女性力气小不适合做搬砖工作”,说实在话,也是一种偏见和刻板印象。
不不不,这是常识,甚至可以有统计依据,不是偏见。但如果把这个结论强加到某个具体女性身上,由她是女性来判断她力气小,才属于刻板印象。
第一眼看那篇文章也觉得哪里不舒服,其实我看任何营销帐号发的东西都不舒服。随着讨论的激烈,我又觉得一些拿“性别歧视”上纲上线的论调让人不舒服。
性别歧视是一个大帽子,拿着这顶大帽子可以完全站在道德制高点。但具体哪句话是性别歧视没人去谈论了,大家都在说性别歧视,下面这段到底“搭讪”、“抱得美人归”、“颜值”哪个有歧视的意思看了几遍也没想出来。
“99%的妹子是想搭讪你”
“只有剩下1%才真的只想学写代码”
.
任务1
抱得美人归
.
判断妹子的天赋
妹子颜值特别高嘛?
如果颜值特别高,请迅速放弃任务2,专攻任务1。
数学物理挂过科吗?
如果挂过科,请专注任务1,不要管任务2了。
魔方可以10秒还原吗?
如果可以,请专注任务1,如果接受了任务2,可能会触发“女朋友编程比我牛逼”的困难模式副本。
我觉得技术相关的各种活动无非都是学习 + 社交。没有纯粹的学习活动,即使是一群男程序员在一起,也还有成为朋友或男男朋友的因素。如果一个技术活动的宣传强调可以遇到大牛、投资人等,这有歧视吗?
回到“Rails Girl”,Girl 本身就是活动的一个噱头,假设活动改为“Rails Boy”会达到现在的关注程度么?可能也会有热心的教练,但不可否认,有了 Girl 让教练更
加热心。反过来 Girl 也是一样,有想学 Rails,顺便和 Coach 交流一下的;有想和 Coach 交流,顺便学一下 Rails 的。其实社交问题是实实在在存在的问题,却被刻意回避和无视,这让我想起了《房间里的大象》。
另外一个话题是,技术社区里的女性确实被特殊对待。她们的帖子即使灌水也会有很多顶帖;即使是新手问题也有很多回答;工作中女程序员犯了愚蠢错误也更
容易被领导和同事容忍;在招聘过程中对女程序员的要求标准可能更低;一个女程序员如果优秀会被特别的强调。这让我想起和菜头关于同性恋问题的一段回复:
如你所见,我从未在微博祝福过任何一对异性恋。此时若我祝福你们,形同承认你们有所不同,那么我本人和你们在暗夜里牵手时所畏惧的目光又有什么不同呢?不去做区分,不施以额外的祝福,在于我就是最大的尊重。
每个人的视角不一样,我理解 bazinga 所说的“想法不一样”,虽然我不是完全认同她写的内容,但至少她有这样表达的自由,如果她理解的 Rails Girl 是那个样子,为什么不能这么说呢?如果其他人有不同的看法完全可以在一个平等的基础上进行对话,以道德绑架的方式要求删帖就显得太脆弱了。
有吗有吗
bundle viz
吧,还带 group 信息...
这问题像脑筋急转弯
是啊,如果你的表足够大了,count(*) 单纯从 sql 语句上是没发再优化的。
Innodb count(*) 都需要扫全索引,只不过是使用了覆盖索引,就是说你查询的列从索引里就可以返回结果了,不需要根据索引再次 IO 读取。
其实 MySQL 默认选择的应该是最快的,你 force index (primary) 可能更慢。
#4 楼 @tesla_lee 3-4 大版本升级,改实现了有什么奇怪的。
概括成一句话:应该用代理键做主键。
Rails.cache.clear
javaeye
视图在 sql 查询层面没任何优化。
但在 AR 对象生成的层面是有优化和简化的。
另,Rails 对视图支持不友好。
直接/scores/:score_id 就好了。
我从另一个角度给你解释为什么不需要带上上层的 id:
假设你给另外系统提供 API 接口,获取 score 信息,正常情况是 /scores/:score_id
,对方有 score id 就可以 CRUD 了。而你要是把嵌套信息也加到 url 里,那么对方请求你一次 API 需要知道你整个数据库的结构了,才能给你提供 univerty_id college_id clazz_id student_id homework_id,这就是耦合。因为你自己的页面一般查完 score 就查 college 等信息你没发觉而已。
和 reset 没关系啊,你自己生成的 url...
关于定时刷新问题其实没有想象那么严重,上面提到按照你数据变更的频繁程度,自己选择是实时、延迟、还是定时刷新
。实际项目中,其实写入没有那么频繁,比如像 RubyChina 这样的应用,我只要保证有回帖和发帖实时刷新就可以,性能完全不是问题。当然,数据量大到一定程度的话,实时刷新代价太大,可以考虑延迟和定时刷新,这样只会有部分数据发生微小偏差,但可以保证最终数据的一致性。
还是实际中使用的问题,您的需求显然是为 eager group 专门设计的,但我只要稍微改变一点需求,eager group 立马变得不可用,而且这个改动还是非常合理的:按照 approved_comments_count 倒序分页。Materialized View 方案就完全可以解决:
Materialized View + JOIN 方案:
posts = Post.joins(:post_agg_mv).order("approved_comments_count DESC").limit(10).all
posts.each do |post|
post.comments_average_rating #需要delegate一下
post.approved_comments_count
end
Materialized View + include 方案:
// 注:post_agg_mv.approved_comments_count 上面上可以加索引的
posts_mv = PostAggMv.include(:post).order("approved_comments_count DESC").limit(10).all
posts_mv.each do |post_mv|
post = post_mv.post
post.comments_average_rating #需要delegate一下
post.approved_comments_count
end
提供另外两种方案:
counter cache with condition 的思路是继续在 post 表里加字段,记录带条件的聚合查询结果:
belongs_to :folder
counter_cache_with_conditions :folder, :messages_count, {}
counter_cache_with_conditions :folder, :unread_messages_count, :unread => true
counter_cache_with_conditions :folder, :unread_messages_count, [:read, :source], lambda{|read, source| read == false && source == 'message'}
counter_cache_with_conditions :folder, :published_events_count, [:published_at], lambda{|published_at| published_at != nil }
项目地址,似乎不维护了:https://github.com/skojin/counter_cache_with_conditions
SQL 里,group 是在做 aggregation,join 在做 composition。通过这两个,我们可以得到任意结果。
原本 comments_count 和 approved_comments_count 不在 post 表里,但我们可以通过 aggregation 和 composition 让他们在一起。
SELECT posts.id AS post_id, COUNT(comments.id) AS comments_count, COUNT(comments.apporved = 1) AS approved_comments_count
FROM posts
INNER JOIN comments ON posts.id = comments.post_id
GROUP BY posts.id
LIMIT 5;
+---------+----------------+-------------------------+
| post_id | comments_count | approved_comments_count |
+---------+----------------+-------------------------+
| 56621 | 1 | 1 |
| 56626 | 1 | 1 |
| 56627 | 1 | 1 |
| 56628 | 1 | 1 |
| 56632 | 1 | 1 |
+---------+----------------+-------------------------+
有了这个视图,我们可以用 join 把所需的数据组合起来,变成这个样子:
+---------+-------+------+----------------+-------------------------+
| post_id | title | body | comments_count | approved_comments_count |
+---------+-------+------+----------------+-------------------------+
| 56621 | title | body | 1 | 1 |
| 56626 | title | body | 1 | 1 |
| 56627 | title | body | 1 | 1 |
| 56628 | title | body | 1 | 1 |
| 56632 | title | body | 1 | 1 |
+---------+-------+------+----------------+-------------------------+
看到这里,大家一定觉得我在扯淡,又 join 又视图的,性能怎么能变快?
是的,视图其实和正常的 SQL 查询一样,我们上面的过程其实等价于先 GROUP 一次,然后再 JOIN 一次。所以结果会慢的惊人。更重要的是视图不能利用索引。
引入物化视图:
CREATE MATERIALIZED VIEW post_agg_mv AS
SELECT posts.id AS post_id, COUNT(comments.id) AS comments_count, COUNT(comments.apporved = 1) AS approved_comments_count
FROM posts
INNER JOIN comments ON posts.id = comments.post_id
GROUP BY posts.id
ORDER BY posts.id ASC
post_agg_mv 是一个真实存在的表,可以在上面加索引。同步的话,可以使用REFRESH MATERIALIZED VIEW post_agg_mv
,按照你数据变更的频繁程度,自己选择是实时、延迟、还是定时刷新;是在 callback 还是 trigger。反正最终数据是一致的。
+---------+----------------+-------------------------+
| post_id | comments_count | approved_comments_count |
+---------+----------------+-------------------------+
| 56621 | 1 | 1 |
| 56626 | 1 | 1 |
| 56627 | 1 | 1 |
| 56628 | 1 | 1 |
| 56632 | 1 | 1 |
+---------+----------------+-------------------------+
然后,组合的时候也不需要用 JOIN,include 仍然有效:
posts = Post.include(:post_agg_mv).all
posts.each do |post|
post.comments_average_rating #需要delegate一下
post.approved_comments_count
end
物化视图的作用不止用于聚合,同样可以用于组合,比如 catalog、SPU、SKU 这种嵌套很深的表结构,有时候查询需要 JOIN 几个表,在查询的时候直接使用物化视图来查结果快很多,有写入的时候刷新一下就保证数据同步。
看到活动记录就不想读了
@_@
多域名单实例的难点上 session 同步啊
你这段代码能简化主要上 send 的作用,proc 的用处不明显。改成方法应该是这个样子的,有一点啰嗦:
def add_by_attr(total, item, attr)
total + item.send(attr).to_i
end
item_list.resuce(0) { |total, item| add_by_attr(total, item, :a1) }
item_list.resuce(0) { |total, item| add_by_attr(total, item, :a2) }
item_list.resuce(0) { |total, item| add_by_attr(total, item, :a3) }
item_list.resuce(0) { |total, item| add_by_attr(total, item, :a4) }