› 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
changrui0608
V2EX  ›  MySQL

新手求指教,查询一对多/多对多关系,映射到编程语言的对象,常规操作是怎样的?

  •  
  •   changrui0608 · Jun 14, 2018 · 4483 views
    This topic created in 3028 days ago, the information mentioned may be changed or developed.
    比如最简单的模型吧,博客有文章 post 和标签 tag,是多对多关系;
    数据库 schema 设计中,一般通过 id 的互相引用;
    编程语言中,通常表现为一个 Post 对象,有一个 Tags 数组属性,里边是多个 Tag 的内容;

    问题就是,不用 ORM 纯手写 SQL 的话,怎么做到一次查询数据库,转换到 Post 对象,并填充 Tags 属性的?

    看过一些 ORM 的实际 SQL 日志,一般会是用 LEFT JOIN,但 LEFT JOIN 的话,比如一个 Post 有多个 Tag,那么查询结果中一个含有 N 个 Tag 的 Post 就会重复出现 N 次。

    虽然是可以手动编程排除重复 Post 并依次处理 Tag,但是感觉极为蛋疼,复杂度也不低,所以想请教下,这种情况下的常规操作是怎样的?
    9 replies  •  2018-06-15 08:48:18 +08:00
    alexsunxl
        1
    alexsunxl  
       Jun 14, 2018
    典型的想得太多, 做得太少, 哈哈哈
    别纠结这些了, 最后还是看场景看业务看历史
    这种东西没有最佳实践的,只能说相对较合适,
    至于怎么是合适,那还是多积累吧
    changrui0608
        2
    changrui0608  
    OP
       Jun 14, 2018
    @alexsunxl
    兄弟,我不是做的太少,我是做到这儿了不知道怎么办才来问的,你这话就和没说一样啊...
    infreboot
        3
    infreboot  
       Jun 14, 2018
    你可以换种方式,多查几次。别想着一条 SQL 查出来。。以前我也是想一条查出来,结果发现是为难自己
    DavidNineRoc
        4
    DavidNineRoc  
       Jun 14, 2018   ❤️ 1
    看了一下 lv 的 SQL

    ## 先查询 posts 表
    select * from posts where xxxx
    ## 连接查询关联关系
    SELECT
    `tags`.*,
    `post_tag`.`post_id` AS `pivot_post_id`,
    `post_tag`.`tag_id` AS `pivot_tag_id`
    FROM
    `tags`
    INNER JOIN `post_tag` ON `tags`.`id` = `post_tag`.`tag_id`
    WHERE
    `post_tag`.`post_id` IN (## 这里是 posts 表查询的数据 ## )
    ##
    然后将第二次查询的数据按照 pivot_post_id 分组,循环一遍 posts 查询出的数据,直接按 pivot_post_id 组设置为单个 posts 的属性。
    AlphaTr
        5
    AlphaTr  
       Jun 14, 2018
    关系型数据库一次查询返回就会出现「 N 个 Tag 的 Post 就会重复出现 N 次」这种情况。一种方式就是你说的,手动编程排重;另一种方式就是多次查询。或者可以直接上非关系型数据库;
    changrui0608
        6
    changrui0608  
    OP
       Jun 14, 2018
    @DavidNineRoc 多谢,查了一下午似乎是这种方法最合适,顺便 lv 全程是什么
    cxbig
        7
    cxbig  
       Jun 14, 2018 via iPhone
    关键词:ORM eager loading
    抓 SQL 看看人家怎么处理的就明白了
    Foolt
        8
    Foolt  
       Jun 14, 2018
    MySQL 去重关键字 DISTINCT 了解一下
    DavidNineRoc
        9
    DavidNineRoc  
       Jun 15, 2018
    @changrui0608 laravel
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5042 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 07:25 · PVG 15:25 · LAX 00:25 · JFK 03:25
    ♥ Do have faith in what you're doing.