1.1. 前言
作为公司的DB一个职责就是和开发沟通,并给出一些编写SQL的建议。但是沟通容易需要达成一致却是比较困难的。基本上在系统中对数据库的查询疯狂的使用到join进行。夸张的一条语句格式化后竟然有100多行,其中个总子查询中套子查询,join中套join(能写出这种SQL的也算的上是“大神”了 ^_^),这种语句我再之前的MySQL数据库中是重来没碰到过的(当然,在Oracle中还是时不时的会有)。然而这些语句竟然还是执行的比较多的。因此当访问上来的时候应用程序和数据库慢的更乌龟一样,CPU也在报警。严重影响到了系统。解析了一下SQL大部分时间都是花在SQL解析上面。不知道的人,总是说这CPU真垃圾,需要增加CPU(你好多钱哦,用MySQL和用Oracle一样)。解决办法就是将这些SQL进行拆解成简单的SQL。运行起来就顺利了。借着这件事。和开发负责人将类似的SQL都找出来,一并优化了。
之后我的建议是,能不能在系统中之后的开发不用join。原因是:不用jion之后能对系统的扩展和二次开发有帮助。重要的是能为能提高系统和数据库的并发。
程序员的接口总是那么的统一和一致:这样我们的开发量会大大提高,会影响进度。这时候我有什么好说的呢?毕竟公司的命脉就在与产品,产品都出不了。那不就值糟糕了。于是只能是默默的达成尽量不写复杂SQL。
1.2. 疑问
真的写简单的SQL就会降低开发效率么?真的就会增加工作量么?
1.3. 证明
本着拥有一点点开发经验,来打破他们说的会增加工作量,会降低开发效率。
1.4. 说明
一下代码都是使用Python来实现。
为了阅读的分层次我使用5个章节来说明我的代码。
1.5. 数据库环境构建
本示例使用了4个表如下表:
表名 | 备注 |
user | 用户表 |
orders | 订单表 |
order_good | 订单商品表 |
coupon | 券表 |
以下是创建表和表数据的SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
-- 创建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
1.6. Join查询拆解
在一般的时候大家都认为使用jion能在数据库找到自己想要到记录,如下面我们需要查询订单的相关信息:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
--
--
--
--
--
--
--
--
--
--
查找订单信息
--
--
--
--
--
--
--
--
--
--
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条简单的语句。如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
--
--
--
--
--
--
--
--
--
--
--
--
分
查找订单信息
--
--
--
--
--
--
--
--
--
--
--
--
--
通过
用户
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
)
;
|
这时候就有人会说了将语句给查分了的结构都还不是最终结果。这里我只能说确实是这样。最终结果我们需要在应用程序中将他拼凑出来。
昵称:HH
QQ:275258836
ttlsa群交流沟通(QQ群②:6690706 QQ群③:168085569 QQ群④:415230207(新) 微信公众号:ttlsacom)
感觉本文内容不错,读后有收获?
逛逛衣服店,鼓励作者写出更好文章。
转载请注明:成长的对话 » 会用JOIN,却不懂编程的“程序员”(1)