我们公司不让开发使用 join 包括 left join,不让用子查询,合理吗?

2020-06-03 16:47:10 +08:00
 hackingwu

我们公司规范不让开发使用 join 包括 left join,也不让用子查询,原因是为了减轻 DB 的压力,这样就导致我们一个多表联合查询的业务就要拆分多条语句,导致无效的请求和数据传输。我们业务是微服务架构。 我觉得是很不合理的。减轻了 DB parse 的压力,却带来了处理请求和数据传输的压力。 大家觉得呢?是我错了吗?

33859 次点击
所在节点    程序员
231 条回复
newtype0092
2020-06-04 12:52:49 +08:00
@dawniii 老哥你说的场景是这样的关系么?
article(id, ...)
tag(id, ...)
author(id, ...)
article_tag(id, article_id, tag_id)
article_author(id, article_id, author_id)
dawniii
2020-06-04 12:56:08 +08:00
@newtype0092 对,是这样的。
hpu423
2020-06-04 13:05:45 +08:00
大流量的项目都是这么要求的吧,赞成 join 的之前开发的应该都是小项目
qiumaoyuan
2020-06-04 13:18:49 +08:00
哈哈哈
Narcissu5
2020-06-04 13:26:31 +08:00
既然你们都是人均千万级了,给我一个不用 mongo 坚持使用 mysql 的理由,新版的 mongo 也支持 ACID 了
huijiewei
2020-06-04 13:37:26 +08:00
@dawniii 说你菜吧。SQL 都写给你了。还是看不懂?
huijiewei
2020-06-04 13:39:24 +08:00
@dawniii 明白了。你是中间关联表的多对多关系吧。那再加两条就好了。

PS: 对不起,开始没想着你用中间表关联,疏忽了
pangleon
2020-06-04 13:40:22 +08:00
@troywinter 确实。微服务这么设计就是一个服务只能访问固定的几个表。
如果真要跨表还是老老实实用视图或者 ES 吧
dawniii
2020-06-04 13:41:40 +08:00
@huijiewei 哈哈哈哈哈哈,确实看不懂,可能你用的是 mysql pro max,我用了个 mysql se
594duck
2020-06-04 13:43:38 +08:00
@magicnian 几十亿,几亿行的表稍宽一点的表 MYSQL 都撑不住,我们做物流的都是上 DRDS 的百库百表方案。更不要说如果有大数据团队还要抽数据呢。
CRVV
2020-06-04 13:43:49 +08:00
@dawniii

这种情况不叫一对多,叫多对多。
一对多应该把表做成这样,不需要中间表。
article(id, ...)
tag(id, name, article_id)
author(id, name, article_id)

这种全用中间表不带冗余字段的设计,是符合关系型数据库范式的表结构,在这种表结构上当然要用 JOIN 。
不用 JOIN 的话表就不这么设计了,比如用 PostgreSQL 的 JSONB 数组来存 tag,直接放在 article 表里面,建一个 GIN 索引。

即使是这样的表结构,不用 JOIN 当然是可以查的,只不过比用 JOIN 慢。
SELECT id FROM tag WHERE name = XXX 取出 tag_id
SELECT article_id FROM article_tag WHERE tag_id = xxx 取出 article_tag_ids

SELECT id FROM user WHERE name = XXX 取出 user_id
SELECT article_id FROM article_author WHERE author_id = xxx 取出 article_author_ids

SELECT * FROM article WHERE id IN(article_ids1) AND id IN (article_ids2)

但是,
前两个 SQL 合并成 SELECT article_id FROM tag INNER JOIN article_tag ON tag_id = id WHERE name = xxx 当然会比查两次要快。因为这个 JOIN 没有带来额外的开销。我觉得即使是 MySQL 也能正确地执行这句 SQL
后面两条也一样。

如果全都合在一起,
SELECT article.* FROM article
INNER JOIN article_tag ON article.id = article_tag.article_id
INNER JOIN tag ON tag.id = article_tag.tag_id
INNER JOIN article_author ON article.id = article_author.article_id
INNER JOIN author ON author.id = article_author.author_id
WHERE tag.name = xxx AND author.name = yyy
GROUP BY article.id

这个 SQL 也没什么问题,JOIN 仍然没有引入额外的开销,而且还比上面那 5 句好懂。
但如果用的数据库是 MySQL,这个 SQL 很有可能被用奇怪的方式来执行,那当然就慢了。
这就是很多人说不能用 JOIN 的理由。
huijiewei
2020-06-04 13:43:49 +08:00
@dawniii 关系型数据库都实现了标准 SQL 语句,看不懂标准 SQL 语句更别谈 LEFT JOIN, RIGHT JOIN ,INNER JOIN ,OUTER JOIN 了
594duck
2020-06-04 13:45:38 +08:00
这就是强上微服务的恶果,拆的太散了,根本不方便做业务了。

所以我说 90%的企业不适合上微服务,上 SOA 就足够了。
neilq
2020-06-04 13:52:29 +08:00
你的想法没问题。你们企业规范也没问题。
数据库 sql 连接性能高,还是拆分查询性能高,在不同场景各有优劣。没什么好争的。
什么大流量大数据也都是屁话,也不是一刀切不用连接的理由。大流量也不是所有业务都是大流量,都不允许用连接 ok?

这么规范完全是为了人员素质管理考虑。企业一大啊,各种各样的人都来了,这里面呢,有些人是真的水的不行。我曾经在一家单位的时候,有个业务部的小伙子写个比较复杂的查询,数据量不多,这里连接那里嵌套写个 sql,api 执行时间 6 秒,我们小组的另一个小伙子看不下去了去优化一下变成 100 毫秒,同样的用的纯 sql 。我可以明确的说,不管你们这这里这个大流量那个分库说的头头世道,都不是主要原因。主要原因就是这样的菜逼太多太多了,为了减少这种错误的上限呢,人又多,今天来需求明天就要上线,不可能天天盯着别人屁股去优化,那就业务部门一刀切,不准用,我哪怕全部 getByIds 去组装数据,一个普通的接口也跑不出 6s 的时间,就这么回事。
newmlp
2020-06-04 13:54:14 +08:00
看业务,如果数据库压力大,就应该把业务逻辑放到应用里处理
dawniii
2020-06-04 13:55:47 +08:00
@CRVV 感谢老哥的回答,老哥你说的对。其实我不是很在意一对多还是多对多,就是想说用 mysql 设计成这样的关系,当查询条件涉及到多个表的字段,不用 join 就没法实现我想要的功能。而不是一刀切的不能用 join,不能用 join 的话,肯定就不会这么设计,直接用 nosql 了。
xy2020
2020-06-04 13:55:47 +08:00
技术水平高的人认为合理,水平低的认为不合理
开发经验丰富的人认为合理,经验欠缺的认为不合理

至于为什么,自己琢磨吧。
goodboy95
2020-06-04 14:05:15 +08:00
@huijiewei ……我的回复专门把“分页”强调出来,结果你还真在这全表查呢……
最下面两个 sql 可能会各查出几万条数据,然后在代码里一波 union,手动分页……这画面还是挺美的
goodboy95
2020-06-04 14:05:51 +08:00
@xy2020 有点意思哦,让你下这个结论的数据源麻烦透露一下
goodboy95
2020-06-04 14:09:56 +08:00
@xy2020 说真的,楼上有两个人跟你一样,在这企图用所谓“技术能力”来压人。这种话谁不会说?换我我也会,“技术水平高的要么直接上 NoSql,既然上了 Sql 就一定是需要 Sql 的特性。技术水平低的才会用 Sql 不干 Sql 事。”

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/678312

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX