三人脉关系怎么存储比较合理呢 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ohmyga
V2EX    PHP

三人脉关系怎么存储比较合理呢

  •  
  •   ohmyga 2015-09-21 08:01:04 +08:00 via iPhone 4934 次点击
    这是一个创建于 3672 天前的主题,其中的信息可能已经有所发展或是发生改变。
    A 推荐 B 注册 B 就是 A 的一级人脉

    B 推荐 C 注册 C 就是 B 的一级人脉, C 是 A 的二级人脉

    C 推荐 D 注册 D 就是 C 的一级人脉, D 是 B 的二级人脉, D 是 A 的三级人脉

    每注册一人数据库记录该人上级关系可行吗

    D-C-1
    D-B-2
    D-A-3

    C-B-1
    C-A-2

    B-A-1
    23 条回复    2017-08-02 01:08:23 +08:00
    ljbha007
        1
    ljbha007  
       2015-09-21 08:37:11 +08:00
    你那种也可以 但是查询会很不方便 有几层人脉关系就要查询几次

    如果楼主的业务逻辑是树状关系 可以这样解决:
    http://falsinsoft.blogspot.com/2013/01/tree-in-sql-database-nested-set-model.html


    如果楼主的关系网络是图状关系 那么最好使用专业的图数据库 graph database

    比如说一个: http://neo4j.com
    http://thinkaurelius.github.io/titan/

    这个 neo4j 我粗略看了一下 跟 sql 很类似 应该可以做到比较容易的迁移
    dong3580
        2
    dong3580  
       2015-09-21 08:50:11 +08:00 via Android
    多少层无关紧要,都是父子而已,所谓的关系型数据库就是这个道理!
    lavadore
        3
    lavadore  
       2015-09-21 08:52:31 +08:00
    只记录上级就可以了,多少层看你查询的时候怎么查了
    ohmyga
        4
    ohmyga  
    OP
       2015-09-21 09:01:32 +08:00
    @lavadore 用户数量大概 10W, 只查用户的 特别级别的人脉,不会一起查询用户的所有级别人脉.如果查询用户一级人脉还好,如果要查询用户的所有的 2 级 或 3 级人脉.只记录上一级是不是渣了些.
    quericy
        5
    quericy  
       2015-09-21 09:19:44 +08:00
    羡慕 LZ,我们产品搞的是 5 级人脉....还要查所有上级和下级 直接是个 N 叉树的林了
    ohmyga
        6
    ohmyga  
    OP
       2015-09-21 09:44:43 +08:00
    @quericy 哈哈 5 级交叉 压力够大啊
    ljbha007
        7
    ljbha007  
       2015-09-21 09:48:57 +08:00
    @ohmyga
    如果知识树状关系用我发的那种办法查询子树效率很高 也很容易理解 大概是这个样子

    SELECT * FROM users WHERE users.left > myleft and users.right < myright;
    lavadore
        8
    lavadore  
       2015-09-21 10:02:32 +08:00
    @ohmyga 一级直接记录了,不用查啊, 2 , 3 级 join 自己就可以了,考虑效率的话可以提取到另外一张表中。个人感觉比都塞在一张表中要好
    mulog
        9
    mulog  
       2015-09-21 10:18:20 +08:00
    Neo4j
    我只是随便说说^^
    500miles
        10
    500miles  
       2015-09-21 10:20:29 +08:00
    那种 left right 的预先排序方式 , 明显不太适合业务场景, 不停的有人注册, 真要命...

    parent_id 的方式, 查询时候太费劲, 你后面可能大量统计

    所以 楼主提出的详细记录就挺好的啊....

    另外 path 的方式 我觉得也非常合适. 简洁明快, 也容易搞缓存.
    liangqing
        11
    liangqing  
       2015-09-21 10:27:47 +08:00
    最大多少级?如果这个级数不大的话,比如 10 ,放 10 个 Key 就行了阿。。简单粗暴。
    ohmyga
        12
    ohmyga  
    OP
       2015-09-21 10:46:15 +08:00
    @liangqing 就三级
    wintersun
        13
    wintersun  
       2015-09-21 10:56:57 +08:00
    @ohmyga 同意 @ljbha007 的建议,关系数据库保存基本信息和一度关系, Graph Database 保存多维度关系
    目前我也在研究 Neo4j ,虽然有评测说其读写性能远低于 MongoDB ,更不用说 MySQL 了,但是我相信其编程模型有利于简化代码,并且在实际应用场景中效率未必就关系数据库差……
    Yanel
        14
    Yanel  
       2015-09-21 11:27:42 +08:00
    这样只记录了上级的数据库查询,一个拥有几千下级的用户查询就会非常费劲啦
    thinkmore
        15
    thinkmore  
       2015-09-21 11:41:24 +08:00
    @ljbha007 网址打不开
    liangqing
        16
    liangqing  
       2015-09-21 11:41:26 +08:00
    @wintersun 我们用过 Neo4j , 13 万数据,存储公司的员工关系,查询速度惨不忍睹, 1 个页面 50 几秒才出来。就是遍历一边也不要这么久阿。后来改用 Elasticsearch 了,秒出。
    run2
        17
    run2  
       2015-09-21 12:10:33 +08:00
    @wintersun 效率这么低啊?
    他们自己的服务器例子
    http://console.neo4j.org/

    Query took 295 ms and returned 4 rows.
    Query took 993 ms and returned 4 rows.

    后来页面里再 run 倒是降到 2ms 之类的(缓存了?)
    takato
        18
    takato  
       2015-09-21 12:53:27 +08:00
    @liangqing - -做了一个怎样的查询?
    liangqing
        19
    liangqing  
       2015-09-21 13:24:11 +08:00
    @takato 不止一个查询,有大量连接操作。
    ljbha007
        20
    ljbha007  
       2015-09-21 13:41:11 +08:00
    @500miles
    对 我没考虑到用户表是个经常插入的表这个问题 这样的话用 left 和 right 的效率还不如有多少层查询多少次
    BobLuo
        21
    BobLuo  
       2015-09-21 13:45:58 +08:00
    可以考虑用图形数据库来做存储
    raincious
        22
    raincious  
       2015-09-21 14:11:37 +08:00
    可能我没理解这个问题。但是这样的静态数据不能用缓存来减少查询么?

    比如建立一张表,`user_relation_registerinvitations`,结构就像:

    (Primary Key ),
    userID int,
    inviters char

    然后`inviters`里存这个用户的上一级邀请者数组,比如用户 D 的邀请者们是:用户 A,用户 B,用户 C

    当有用户 E 通过这个用户 D 的邀请注册的时候,就将这个用户 D 的`inviters`数组读出来放到一个变量里, Shift 出最前的那个用户 A , Push 进用户 D 。然后用变量里的那个新的`inviters`数组为用户 E 建立`人脉表`的数据项,表示他们分别是用户 E 的第 X 级人脉(记得倒过来)。

    最后,为用户 E 在`user_relation_registerinvitations`里新建一个项,数据是

    `userID` = 用户 E 的 ID
    `inviters` = 用户 B,用户 C,用户 D (新的`inviters`数组)

    这样当这个用户也要请其他用户注册的时候,就可以延续了。
    HanSonJ
        23
    HanSonJ  
       2017-08-02 01:08:23 +08:00
    @raincious #22 这样设计的缺点在于不利于查询,假若要查询 用户 C 下面的用户,总不能用 like 吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     892 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 20:46 PVG 04:46 LAX 13:46 JFK 16:46
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86