› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
cevincheung
V2EX  ›  MySQL

如何优雅的处理 Tag 的 CRUD

  •  
  •   cevincheung ·
    cevin · Oct 4, 2017 · 4849 views
    This topic created in 3282 days ago, the information mentioned may be changed or developed.

    如 Blog 的 Tag、帖子的 Tag 等多对多的存储关系。

    新增的时候

    # 看看哪些存在?
    tags = Tags.query.filter(Tags.tag_name.in_(('tag1','tagN'))).all()
    # 不存在的入库?
    # 存在的更新 relation ?
    

    修改 Blog/帖子的时候再原样处理一次?

    还有更加优雅的处理方法吗?

    6 replies  •  2017-10-04 12:05:02 +08:00
    hwding
        1
    hwding  
       Oct 4, 2017
    我也是这样的,首先处理 Tags,再保存 Blog。

    当然你需要一个 mapper 表来保存对应关系。

    只新建没有的 Tags。

    public List<Tag> saveWithMetas(String[] metas) {
    List<Tag> tags = Arrays.asList(metas)
    .parallelStream()
    .map(name -> {
    Tag thisTag = findTagByName(name);
    return thisTag == null ? new Tag().setName(name) : thisTag;
    })
    .distinct()
    .collect(Collectors.toList());
    return tagRepository.save(tags);
    }

    目前没看到更好的方案,而且多对多有一个遗孤(Orphan)的问题,不能自动清除掉没用的 Tags...
    Sight4
        2
    Sight4  
       Oct 4, 2017
    1. 部分 rmdbs/nosql 提供 insert...update...语句,例如 mysql 的 insert..on duplicate key update 或者 postgresql 的 insert...on conflict update 都支持类似的方案,插入时重复时更新或者忽略
    2. 触发器或者存储过程解决
    cevincheung
        3
    cevincheung  
    OP
       Oct 4, 2017
    @hwding #1
    有个中间表还好,每次编辑都直接删掉当前对象的所有关联然后重建。
    cevincheung
        4
    cevincheung  
    OP
       Oct 4, 2017
    @Sight4 #2 触发器存储过程会不会在后端数据库集群多 Master 情况下有问题。
    Sight4
        5
    Sight4  
       Oct 4, 2017
    @cevincheung 这个要看你多 master 的配置方式,比如说主动-被动模式下的双主不存在这个问题,这种模式下其实就相当于热备,如果是主动-主动模式的就会出现问题了,同时允许多个 master 写入是件很高风险的事情
    qiukun
        6
    qiukun  
       Oct 4, 2017
    API 纯 rest 的话是一系列 update 操作,不过也可以抽象一个 tags 资源,blog/id/tags update 即可。
    实际实现,不考虑性能就是多对多,中间表。
    考虑性能中间肯定顶一层 cache 了,读取全走 cache,写 db 的话异步写,这里有一致性的问题,如果用 redis 的话,就没有,建议用 redis,tag#{blog_id} -> set blog#{tag_id} -> set。
    其实不考虑性能也用 redis 吧,每次改 blog 的 tags 你都不知道用户是不是改过原有的 tags,都是要走中间表查一次,虽然说写起来也无非就是 blog.tags.destory blog.tags.insert (这种操作看贵 ORM 了。。)
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4181 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 10:02 · PVG 18:02 · LAX 03:02 · JFK 06:02
    ♥ Do have faith in what you're doing.