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

好友关系用数据库怎么存?

  •  
  •   pinews · 2020-05-07 06:17:23 +08:00 · 5244 次点击
    这是一个创建于 1663 天前的主题,其中的信息可能已经有所发展或是发生改变。
    A 和 B 是好友,数据库存一条记录,

    查询 A 的好友时,有这条记录,
    查询 B 的好友时,也有这条记录,

    怎么表达这种相等的关系?
    我能想到的是存 2 条记录,

    之前的九九乘法歌是举例
    40 条回复    2020-06-09 17:59:04 +08:00
    ksaa0096329
        1
    ksaa0096329  
       2020-05-07 06:19:11 +08:00 via iPhone
    图数据库
    btnokami
        2
    btnokami  
       2020-05-07 06:21:21 +08:00 via iPhone
    sparql 和 gremlin 了解一下
    pinews
        3
    pinews  
    OP
       2020-05-07 06:21:55 +08:00
    或者用 OR,感觉都不是我想要的
    pinews
        4
    pinews  
    OP
       2020-05-07 06:25:37 +08:00
    @ksaa0096329
    @btnokami 对的对的,就是这种,谢谢。
    pinews
        5
    pinews  
    OP
       2020-05-07 06:29:05 +08:00
    用 mysql 能实现类似功能吗?
    lbfeng
        6
    lbfeng  
       2020-05-07 06:31:09 +08:00
    @pinews associate table 实现 many to many
    catror
        7
    catror  
       2020-05-07 06:37:09 +08:00 via Android
    单独建一个好友关系表,存一条记录就可以了,查询的时候同时检查两个字段。
    lihongming
        8
    lihongming  
       2020-05-07 06:47:22 +08:00 via iPhone   ❤️ 7
    建议分别存两条,原因有二:


    从产品上讲,你将来很可能会需要单向关注,而不是双向好友,分别存储就不用大改。


    从技术上讲,sns 是个典型的 nosql 应用场景,每次读取时间线都重新计算效率太低,不如每个用户存自己关注和关注自己的人,发动态时更新所有人的时间线。这样可以用队列等方式把服务器的空闲时间利用起来慢慢写入,而读取时间线就只需要读一条记录,效率极高。
    pinews
        9
    pinews  
    OP
       2020-05-07 06:58:05 +08:00
    @lihongming 好友关系只是举例,只用来描述是或不是的关系,表示一种绝对等价的关系。
    lihongming
        10
    lihongming  
       2020-05-07 07:10:34 +08:00 via iPhone   ❤️ 1
    @pinews 坦率地说,你的问题没法回答。


    学的越多,越明白系统设计需要跟业务特征紧密结合,凭空出题根本没法设计
    luopengfei14
        11
    luopengfei14  
       2020-05-07 07:14:59 +08:00 via iPhone
    如果是做 im,好友关系复杂,例如出现备注、设置免打扰、拉黑等,单独见表,互为好友对应两条记录。
    如果好友关系简单,一条记录就可以
    areless
        12
    areless  
       2020-05-07 07:25:16 +08:00 via Android
    存两条,关注~被关注。你要是单向关注就把 timeline 推过去会被用户打死的
    pinews
        13
    pinews  
    OP
       2020-05-07 07:28:07 +08:00
    @lihongming 就是一本小说,人物之间的各种关系,选中一个人,就可以查看和他所有有关系的人,挨个点下去,就能看到所有人的关系,就像看地图一样,图数据库,挺形象的,两个人的关系可能和复杂,会做详细说明,但是不去区分方向。就相比兄弟,不去区分谁是兄谁是弟,是夫妻,不区分谁是夫谁是妻,他们的关系会具体的详细另外再写。
    guoshim
        14
    guoshim  
       2020-05-07 07:28:10 +08:00
    这种是很典型的图关系。
    如果你希望数据库本身支持复杂的图操作,可以用图数据库。
    如果你希望短平快一点,延迟低一点,就正常的 mysql 或者 kv store 就可以了,分两部分来存,一个用来存点,即用户,另一个存边,即某两个用户之间的关系。当然,如果数据量很大,或者有非常高频的访问,可以再搞一层 memcache 。
    pinews
        15
    pinews  
    OP
       2020-05-07 07:33:35 +08:00
    @guoshim 好的,我去学习一下
    pinews
        16
    pinews  
    OP
       2020-05-07 07:48:52 +08:00
    我其实是想做一个兴趣 知识 计划之类的工具,比如我关注了 linux 这个点,但是这个知识点太大,我只能记录和我有关的几点内容,后来我又关注了 debian,又记录了 debian 的几点内容,其中特别关注了 linux 和 debian 共同,与其他不同的东西,然后又关注了 apache,我又想和 windows 下的 apache 对比一下,就是这样的知识点。

    和 tag 很像,但是也重视不同 tag 的联系的这种关系,好比我喜欢有山的画,喜欢有水的画,喜欢又有山又有水还有花的画,如果没有看到这的画我可能想不起来,但是看到这样的画,我就想找到更多这样的画,但又不想贸然去找一个组合,很可能什么都找不到会觉得很失望。...不知道自己在说些什么。。
    pinews
        17
    pinews  
    OP
       2020-05-07 07:52:33 +08:00
    @pinews 所以我暂时先把那些感兴趣的知识点记录起来,然后看看打算去想哪个兴趣点去更适合拓展。
    pinews
        18
    pinews  
    OP
       2020-05-07 07:57:18 +08:00
    就想一个知识地图,全局来看,看看哪里长时间不关注,可能需要学习吗,放大详细了看,看看哪里知识不够完备,专业。这样好做规划。
    foam
        19
    foam  
       2020-05-07 08:27:28 +08:00 via Android
    #16 扫雷?
    yvestang
        20
    yvestang  
       2020-05-07 08:34:37 +08:00
    图数据库适合你,定义好 schema 即可,推荐下 janusgraph (重)或者百度的 hugegraph 或者社区版本的 neo4j
    noqwerty
        21
    noqwerty  
       2020-05-07 08:40:53 +08:00
    @pinews #16 建议了解一下 X-Y 问题,对大家帮你找到合适的答案很有帮助: https://coolshell.cn/articles/10804.html
    CrazyMoon
        22
    CrazyMoon  
       2020-05-07 08:43:09 +08:00
    在实践中,A 的好友是 B 不等于 B 的好友是 A,所以通常都是 2 条记录
    jswh
        23
    jswh  
       2020-05-07 09:37:18 +08:00
    知识图谱了解一下
    epson3333
        24
    epson3333  
       2020-05-07 09:48:04 +08:00
    @CrazyMoon 加多个字段表示到底是 A->B,A<-B 还是 A<-->B
    u6pM63mMZ34z32cE
        25
    u6pM63mMZ34z32cE  
       2020-05-07 10:20:06 +08:00
    路过问一下, 亲戚关系数据库怎么设计?
    比如叔侄关系, 通过叔叔可以查到侄子, 通过侄子可以查到叔叔
    imn1
        26
    imn1  
       2020-05-07 10:34:15 +08:00
    这个,更多是算法问题,而不是存储问题
    NoKey
        27
    NoKey  
       2020-05-07 10:55:12 +08:00
    如果用简单的方式存在 mysql 里
    看看可以这样存不
    关键字段 人物,朋友
    每个人的好友关系,记录每个人自己的
    比如 a 有朋友 b,c,那就两条记录 a-b a-c
    然后 b 有朋友 x,y 那就记录 b-x b-y
    在代码里自己去提取组合。
    NoKey
        28
    NoKey  
       2020-05-07 10:58:53 +08:00
    @mebtte 叔叔,是妈妈那边的吧,爸爸这边的应该是伯伯?通过侄子,查找他的 mather id,找到他的妈妈,跟他妈妈有相同父 id 的男性,就是叔叔?这里面要是涉及到后妈什么的,估计还得有额外字段来标示一下。
    tctc4869
        29
    tctc4869  
       2020-05-07 11:14:16 +08:00
    用户好友关系特征适合用文档数据库弄么?把一个用户的好友 id 和用户自己与该好友关系的相关字段存在文档内部的某个子文档里?
    @lihongming
    coosir
        30
    coosir  
       2020-05-07 11:17:44 +08:00
    @NoKey 你这个亲戚关系也太混乱了吧……舅舅是哪边的?
    CrazyMoon
        31
    CrazyMoon  
       2020-05-07 11:23:52 +08:00
    @epson3333 #24 来个对非对称关系的需求,比如楼上说的叔侄关系,1 条又难了。。
    zxcslove
        32
    zxcslove  
       2020-05-07 11:25:36 +08:00
    @mebtte 新增成员时更新关系,达到一定界限比如出了五服为止
    NoKey
        33
    NoKey  
       2020-05-07 11:44:05 +08:00
    @coosir 😂,突然发现好像搞错了,意思表达了就可以了。。。
    namelosw
        34
    namelosw  
       2020-05-07 11:44:41 +08:00
    RDBMS 就是递归关联,不用 CTE 不能一口气拿出来,很别扭,另外你说的 OR 和两条都行,取决于你的需求是有向还是无向
    如果图数据库直接存取就行
    如果 KV 或者 Document 就是一个大 document 存关系,然后另外的地方存 node 信息

    如果高级点可以研究一下 Prolog 或者 Datomic/Datalog
    epson3333
        35
    epson3333  
       2020-05-07 11:44:47 +08:00
    @CrazyMoon 加多个字段表明亲戚关系不行嘛
    telun
        36
    telun  
       2020-05-07 11:56:44 +08:00
    @pinews 与曾今的想法似曾相识,好比一首歌,有的人听到觉得伤感,有的人听到想到爱情,有的人听到想到孤单,这其中的 tag 貌似没关系,又貌似有关系。哈哈。感谢楼主提出话题。
    hantsy
        37
    hantsy  
       2020-05-07 12:19:25 +08:00
    最好是用 Neo4j 之类图形数据,好友关联路径比较容易查询,比 Linkedin 那种。
    lihongming
        38
    lihongming  
       2020-05-07 12:55:35 +08:00 via iPhone
    @tctc4869 没问题啊,文档也是 nosql,根据业务特征合理设计即可
    pythonee
        39
    pythonee  
       2020-05-07 20:53:37 +08:00
    学习了,以前微博饭否时代,这是 nosql 的典型场景吧
    DJQTDJ
        40
    DJQTDJ  
       2020-06-09 17:59:04 +08:00
    话说主键是我,外键是朋友,这不就成了?
    一对多关系
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1066 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 23:24 · PVG 07:24 · LAX 15:24 · JFK 18:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.