V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
solaro
V2EX  ›  数据库

QQ 里的‘好友动态’,微信里的‘朋友圈’该怎么设计表结构呢?

  •  1
     
  •   solaro · 2015-04-21 13:10:24 +08:00 · 2540 次点击
    这是一个创建于 3511 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,我很好奇,像他们腾讯用户量这么大,时刻更新的数据也这么多,他们要怎么去设计数据库的表结构?怎么优化???如果用户量不大的情况下,日活200万,每个人可以关注5000个朋友,这个时候表结构得怎么设计才合理,有啥其他的优化方法吗?数据库用mysql。这个是一个实际项目问题。求各位大神。

    40 条回复    2015-04-29 08:40:32 +08:00
    J2eePro
        1
    J2eePro  
       2015-04-21 13:25:49 +08:00
    Sphinx?
    decken
        2
    decken  
       2015-04-21 13:25:59 +08:00
    应该用nosql了
    huijiewei
        3
    huijiewei  
       2015-04-21 13:26:00 +08:00 via iPhone
    这种一般都是 NoSQL 数据库
    ipconfiger
        4
    ipconfiger  
       2015-04-21 13:26:32 +08:00   ❤️ 1
    关系型数据库不擅长处理这类结构
    solaro
        5
    solaro  
    OP
       2015-04-21 13:26:49 +08:00
    啊。。nosql。。monogdb??redis??
    palytoxin
        6
    palytoxin  
       2015-04-21 13:28:38 +08:00 via iPhone
    redmine中的项目动态设计思路挺有趣
    arkilis
        7
    arkilis  
       2015-04-21 13:31:28 +08:00   ❤️ 1
    monogdb, I guess
    solaro
        8
    solaro  
    OP
       2015-04-21 13:38:40 +08:00
    @palytoxin 求个解决方案。。
    Prothunder
        9
    Prothunder  
       2015-04-21 13:41:02 +08:00
    redis
    hahasong
        10
    hahasong  
       2015-04-21 13:41:53 +08:00
    用户量大就加机器呗,自建机房,北京,深圳,上海都有。一天光电费都要烧很多。上次新闻上海的还挖断过光缆
    YORYOR
        11
    YORYOR  
       2015-04-21 13:50:31 +08:00
    hbase
    abscon
        12
    abscon  
       2015-04-21 13:52:25 +08:00 via iPhone
    我猜是 Graph database
    caoyue
        13
    caoyue  
       2015-04-21 13:55:23 +08:00
    瞎猜一个,如果是我可能这么设计:
    假设 A 和 B 关注了 C,C 发布了一条更新
    那么把这条更新同时写到 A,B 各自的关注表里面去
    A 和 B 各自读自己的关注表就行了
    这样算起来,单独看个人的数据量就没有那么大了=-=
    xenme
        14
    xenme  
       2015-04-21 14:05:51 +08:00
    @caoyue 你想每个人的好友至少几十个吧,就算50个,数据量就变成了50倍。
    explon
        15
    explon  
       2015-04-21 14:08:46 +08:00
    @caoyue 新加一个好友还要全部拷贝一遍?
    huijiewei
        16
    huijiewei  
       2015-04-21 14:09:39 +08:00
    @caoyue 高速分布式缓存可以这样用,基础数据库结构这样设计可以算严重事故类型了
    faceair
        17
    faceair  
       2015-04-21 14:11:43 +08:00 via iPhone
    @explon 肯定不会拷贝的,应该是筛选访问权限
    Kilerd
        18
    Kilerd  
       2015-04-21 14:31:11 +08:00
    那么大的数据量,关系型的数据库已经不能用了吧。非关系型的会好很多。

    不过我更喜欢mongodb
    xiaogui
        19
    xiaogui  
       2015-04-21 14:34:38 +08:00
    redis,建议楼主搜下新浪微博分享出来的对 redis 使用的资料
    zts1993
        20
    zts1993  
       2015-04-21 14:55:57 +08:00
    redis
    wizardforcel
        21
    wizardforcel  
       2015-04-21 15:01:03 +08:00 via Android
    朋友圈、微博和说说都是一类东西,这种现成的解决方案应该早就烂大街了。

    觉得扛不住就加机器。关系型数据库不合适,是因为,一张表很难以合适的方法切开,放到几台机子上。
    caoyue
        22
    caoyue  
       2015-04-21 15:01:40 +08:00
    @xenme
    @explon
    @huijiewei
    1. 我之前做过测试,微信朋友圈新加的好友是**看不到**之前的设置为好友可见的更新的,目前看来不存在新加的拷贝问题
    2. 刷新朋友圈的时候,是只读一个表还是读五十个表方便嘛
    3. 占用空间不叫事
    4. 我只是猜一个思路,不用局限到关系数据库还是缓存还是别的什么东西上
    5. 任何一个复杂到朋友圈级别的系统,都不是单单数据库能解决的问题
    6. 不存在什么牛逼的单个工具,用了就能支撑起这么复杂的系统
    7. Push 和 Pull 模式还有 Feed 架构已经讨论了这么多年了,楼主可以找资料参考
    xenme
        23
    xenme  
       2015-04-21 15:03:19 +08:00
    @caoyue 看起来有道理
    explon
        24
    explon  
       2015-04-21 15:20:18 +08:00
    @caoyue 可以看到的,不知道你怎么测试的
    dbfox
        25
    dbfox  
       2015-04-21 15:58:36 +08:00
    hadoop
    hbase

    应该是与这些东西相关的
    wanjun
        26
    wanjun  
       2015-04-21 16:00:15 +08:00
    分地区,分圈子,分时间
    caoyue
        27
    caoyue  
       2015-04-21 17:22:12 +08:00
    @explon
    从 *朋友圈* 看到和点头像进个人的 *Profile* 看到是 两个逻辑

    测试方法:
    1. A 和 B 是好友
    2. A 和 B 互相删除好友
    3. A 发布一条朋友圈
    4. A 和 B 互相加为好友
    5. A 刚发布的更新不会出现在 B 的朋友圈
    6. B 在 A 的 Profile 页面可以看到 A 的更新

    如果 A 和 B 本来就不是好友,1 和 2 可以忽略
    cheng007
        28
    cheng007  
       2015-04-21 19:01:30 +08:00
    被自己过往经验把自己的思路堵死了
    学点分布式构架吧。
    cheng007
        29
    cheng007  
       2015-04-21 19:02:03 +08:00
    @dbfox 和这些没关系。
    xjx0524
        30
    xjx0524  
       2015-04-21 19:29:40 +08:00 via Android
    zhuchaowe
        31
    zhuchaowe  
       2015-04-21 20:02:54 +08:00
    最近也在做消息流,我的想法是这样的,当然采用的是nosql。
    1.用户发布一条消息的时候,向所有的好友们的timeline里面都插入这条消息。虽然看上去数据量会很大,不过再仔细想想,这里的“每份”不需要存储完整信息,只需要存储消息的ID和时间(可能需要)。再说了以空间换时间,这种做法在nosql里还是很常见的。
    2.这样做的缺点:
    就导致了消息流不可以被编辑和修改,不然每个好友的timeline都要更新,所以微信仅仅提供了删除的功能。
    3.微信还有一个消息屏蔽功能,发布的时候时候需要考虑屏蔽的人的话,那就还要去读取每个有权限阅读的人的屏蔽人清单,然后根据每个人的清单去决定是不是放到这个人的timeline中,显然这又会增加多大的计算量。但是仔细一想,都已经好友们每个人都有一份自己的timeline数据的话,那就简单了,客户端渲染的时候,读一下自己的屏蔽列表,然后该隐藏的隐藏,都不用做什么关联查询,也算这种做法的优点。

    大概就是这么多,这样做可以实现多台服务器做分布式,牺牲一点空间还是很合算的。
    xiaowangge
        32
    xiaowangge  
       2015-04-21 20:02:59 +08:00 via Android
    请搜索「腾讯 CMem」,我猜用得是它。←_←
    decken
        33
    decken  
       2015-04-22 00:43:01 +08:00 via Android
    @zhuchaowe 2中 微信仅提供删除 这是出于设计理念的考虑吧
    wuyadong
        34
    wuyadong  
       2015-04-22 00:44:13 +08:00
    大家多看看分布式相关的,会有好处的~~~
    safilar
        35
    safilar  
       2015-04-22 08:25:09 +08:00   ❤️ 1
    标准观察者设计模式,也能讨论成这样。需要表结构?
    cxe2v
        36
    cxe2v  
       2015-04-22 09:10:41 +08:00
    @safilar 来展开一下是怎么个设计细节?讲大的概念基本都会
    YORYOR
        37
    YORYOR  
       2015-04-22 13:42:39 +08:00
    @safilar 嘴巴选手? talk is easy , give me code
    solaro
        38
    solaro  
    OP
       2015-04-24 11:18:22 +08:00
    @safilar 大神讲讲吧,我们都很想知道!
    @YORYOR
    @cxe2v
    safilar
        39
    safilar  
       2015-04-29 08:40:03 +08:00
    @solaro 不好意思,几天没上了。我只是认为这个状况很适合观察者设计模式,而且这根本就不是大的概念。23种设计模式之一而已,你去看 Head First 第二章,我记得就是说类似的一个样例。但是这种设计能否承受大数据量,我保持怀疑态度。
    safilar
        40
    safilar  
       2015-04-29 08:40:32 +08:00
    Head First 设计模式
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2443 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:02 · PVG 00:02 · LAX 08:02 · JFK 11:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.