会用JOIN,却不懂编程的“程序员”(1)

HH MySQL python28,81412字数 3218阅读10分43秒阅读模式

1.1. 前言

作为公司的DB一个职责就是和开发沟通,并给出一些编写SQL的建议。但是沟通容易需要达成一致却是比较困难的。基本上在系统中对数据库的查询疯狂的使用到join进行。夸张的一条语句格式化后竟然有100多行,其中个总子查询中套子查询,join中套join(能写出这种SQL的也算的上是“大神”了 ^_^),这种语句我再之前的MySQL数据库中是重来没碰到过的(当然,在Oracle中还是时不时的会有)。然而这些语句竟然还是执行的比较多的。因此当访问上来的时候应用程序和数据库慢的更乌龟一样,CPU也在报警。严重影响到了系统。解析了一下SQL大部分时间都是花在SQL解析上面。不知道的人,总是说这CPU真垃圾,需要增加CPU(你好多钱哦,用MySQL和用Oracle一样)。解决办法就是将这些SQL进行拆解成简单的SQL。运行起来就顺利了。借着这件事。和开发负责人将类似的SQL都找出来,一并优化了。

之后我的建议是,能不能在系统中之后的开发不用join。原因是:不用jion之后能对系统的扩展和二次开发有帮助。重要的是能为能提高系统和数据库的并发。文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

程序员的接口总是那么的统一和一致:这样我们的开发量会大大提高,会影响进度。这时候我有什么好说的呢?毕竟公司的命脉就在与产品,产品都出不了。那不就值糟糕了。于是只能是默默的达成尽量不写复杂SQL。文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

1.2. 疑问

真的写简单的SQL就会降低开发效率么?真的就会增加工作量么?文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

1.3. 证明

本着拥有一点点开发经验,来打破他们说的会增加工作量,会降低开发效率。文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

1.4. 说明  

一下代码都是使用Python来实现。文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

为了阅读的分层次我使用5个章节来说明我的代码。文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

1.5. 数据库环境构建

本示例使用了4个表如下表:文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

表名 备注
user 用户表
orders 订单表
order_good 订单商品表
coupon 券表

 文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

以下是创建表和表数据的SQL:文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

-- 创建test数据库
CREATE database test;
USE test;
 
 
-- 创建用户信息
CREATE TABLE `user` (
 `user_id` int(11) DEFAULT NULL,
 `name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
INSERT INTO `user` VALUES (10,'HH');
  
-- 创建订单信息
CREATE TABLE `orders` (
 `order_id` int(11) DEFAULT NULL,
 `num` int(11) DEFAULT NULL,
 `user_id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
INSERT INTO `orders` VALUES 
 (1,11111,10),
 (2,22222,10),
 (3,33333,10),
 (4,44444,10),
 (5,55555,10);

-- 创建订单商品信息
CREATE TABLE `order_good` (
 `id` int(11) DEFAULT NULL,
 `order_id` int(11) DEFAULT NULL,
 `good_name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
INSERT INTO `order_good` VALUES 
 (3,2,'order_good_3'),
 (4,2,'order_good_4'),
 (5,3,'order_good_5'),
 (6,3,'order_good_6'),
 (7,4,'order_good_7'),
 (8,4,'order_good_8'),
 (9,5,'order_good_9'),
 (10,5,'order_good_10'),
 (1,1,'order_good_1'),
 (2,1,'order_good_2');
  
-- 创建券信息
CREATE TABLE `coupon` (
 `coupon_id` int(11) DEFAULT NULL,
 `order_id` int(11) DEFAULT NULL,
 `name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
INSERT INTO `coupon` VALUES 
 (1,1,'coupon_1'),
 (2,3,'coupon_3'),
 (3,5,'coupon_5');

SQL文件(没有带DROP database):test_db文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

1.6. Join查询拆解

在一般的时候大家都认为使用jion能在数据库找到自己想要到记录,如下面我们需要查询订单的相关信息:文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

------------------
-- 查找订单信息 --
------------------
SELECT u.name AS '用户名',
 o.num    AS '订单号',
 og.good_name AS '购买的商品名称',
 c.name    AS '券名字'
FROM user AS u
 LEFT JOIN orders   AS o ON u.user_id = o.user_id
 LEFT JOIN order_good AS og ON o.order_id = og.order_id
 LEFT JOIN coupon   AS c ON o.order_id = c.order_id
WHERE u.user_id = 10;
+-----------+-----------+-----------------------+-----------+
| 用户名    | 订单号    | 购买的商品名称        | 券名字    |
+-----------+-----------+-----------------------+-----------+
| HH        |     11111 | order_good_1          | coupon_1  |
| HH        |     11111 | order_good_2          | coupon_1  |
| HH        |     33333 | order_good_5          | coupon_3  |
| HH        |     33333 | order_good_6          | coupon_3  |
| HH        |     55555 | order_good_9          | coupon_5  |
| HH        |     55555 | order_good_10         | coupon_5  |
| HH        |     22222 | order_good_3          | NULL      |
| HH        |     22222 | order_good_4          | NULL      |
| HH        |     44444 | order_good_7          | NULL      |
| HH        |     44444 | order_good_8          | NULL      |
+-----------+-----------+-----------------------+-----------+

如果将join拆分之后,就变成了4条简单的语句。如下:文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

----------------------
-- 分  查找订单信息 --
----------------------
-- 通过 用户ID 获得用户名
SELECT user_id, name FROM user WHERE user_id = 10;
 
-- 通过 用户ID 获得订单信息
SELECT order_id, num FROM orders WHERE user_id = 10;
 
-- 通过上面获得的 订单ID 获得商品订单信息。
SELECT order_id, good_name FROM order_good WHERE order_id IN (1,2,3,4,5);
 
-- 通过 订单ID 获得券信息
SELECT order_id, name FROM coupon WHERE order_id IN(1,2,3,4,5);

这时候就有人会说了将语句给查分了的结构都还不是最终结果。这里我只能说确实是这样。最终结果我们需要在应用程序中将他拼凑出来。文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

 文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

昵称:HH
QQ:275258836
ttlsa群交流沟通(QQ群②:6690706 QQ群③:168085569 QQ群④:415230207(新) 微信公众号:ttlsacom)文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

感觉本文内容不错,读后有收获?文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

逛逛衣服店,鼓励作者写出更好文章。文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/ 文章源自运维生存时间-https://www.ttlsa.com/mysql/using_join_no_programing_1/

weinxin
我的微信
微信公众号
扫一扫关注运维生存时间公众号,获取最新技术文章~
HH
  • 本文由 发表于 12/04/2016 00:16:42
  • 转载请务必保留本文链接:https://www.ttlsa.com/mysql/using_join_no_programing_1/
评论  2  访客  2
    • 阿飞的TTLSA
      阿飞的TTLSA 0

      新浪微博就是禁止使用JOIN,并发量大后JOIN绝对会拖死数据库!

      • 凉白开
        凉白开 1

        非常有道理

      评论已关闭!