- A+
1.1. 前言
之前的文章应该已经是彻彻底底的证明的拆分join带来的好处是极大的,并且基本已经打破了一些人的谣言。那(“装饰器”+“拆分JOIN”)就这些能耐了吗?答案是否定的。让我们来看一下基本上在每个项目中都是要做的。
1.2. 场景
随着项目的发展需要对业务进行切割。如将“商品管理”和“订单管理”进行分开。这里的分开是在“程序”和“数据库”同事切分。这时候商品数据和订单数据都不是在同一个库因此要做到跨库查询。
大多的项目说到要项目切割的时候,那基本上就是一个噩梦。基本上就是需要对项目进行重构,重新开放了。就想我再公司说,这个表已经过大,需要拆分,程序员总是说:“这个改动太大”一样。一看改动太大的原因是因为,他们的代码中对数据库的操作充满的join,因此,他们说的改动太大这是肯定的。
1.3. 装饰器完成跨库表查询
我们现在模拟券表(coupon)在test1数据库中。数据为:
1 2 3 4 5 6 7 8 |
SELECT * FROM coupon; +-----------+----------+-----------+ | coupon_id | order_id | name | +-----------+----------+-----------+ | 1 | 1 | coupon_7 | | 2 | 3 | coupon_9 | | 3 | 5 | coupon_11 | +-----------+----------+-----------+ |
和之前一样我们,使用的是(“装饰器”+“拆分JOIN”)的方法。
1.4. 实现程序
这里我们在创建一个装饰器方法use_db,这个方法可以传入一个参数conn:
conn:数据库的链接。
之后我们在get_coupon_info方法上面添加一个annotation:@use_db(conn=conn1),其中conn1代表数据库test1的链接。这样之后查找券的信息就是在test1中查找的了。
代码如下:
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 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#!/usr/bin/env python # -*- coding:utf-8 -*- import pandas as pd import mysql.connector import sys reload(sys) sys.setdefaultencoding('utf-8') conf = { 'host' : '127.0.0.1', 'port' : '3306', 'database' : 'test', 'user' : 'root', 'password' : 'root' } conn = mysql.connector.connect(**conf) conf1 = { 'host' : '127.0.0.1', 'port' : '3306', 'database' : 'test1', 'user' : 'root', 'password' : 'root' } conn1 = mysql.connector.connect(**conf1) def use_db(conn=None): ''' 选择使用的db conn ''' def _use_db(func): def __use_db(*args, **kargs): func_info = func(*args, conn=conn) return func_info return __use_db return _use_db def get_user_info(user_ids, conn=None): ''' 通过user_id获得用户信息 ''' user_sql = ''' SELECT user_id, name FROM user WHERE user_id IN({user_ids}); '''.format(user_ids = ','.join(user_ids)) user_info = pd.read_sql(user_sql, conn) return user_info def get_order_info(user_ids, conn=None): ''' 通过 用户ID 获得订单信息 ''' order_sql = ''' SELECT user_id, order_id, num FROM orders WHERE user_id IN({user_ids}); '''.format(user_ids = ','.join(user_ids)) order_info = pd.read_sql(order_sql, conn) return order_info def get_order_good_info(order_ids, conn=None): ''' 通过上面获得的 订单ID 获得订单商品信息。 ''' order_good_sql = ''' SELECT order_id, good_name FROM order_good WHERE order_id IN ({ids}); '''.format(ids = ','.join(order_ids)) order_good_info = pd.read_sql(order_good_sql, conn) return order_good_info @use_db(conn=conn1) def get_coupon_info(order_ids, conn=None): ''' 通过 订单ID 获得券信息 ''' coupon_sql = ''' SELECT order_id, name FROM coupon WHERE order_id IN({ids}); '''.format(ids = ','.join(order_ids)) coupon_info = pd.read_sql(coupon_sql, conn) return coupon_info def join_data(func_name, col_name): ''' 添加能通过订单ID查找出来的信息 ''' def _join_data(func): def __join_data(*args, **kargs): func_info = func(*args, **kargs) ids = func_info[col_name].astype(str) info = eval(func_name)(ids, **kargs) new_order = func_info.merge(info, left_on=col_name, right_on=col_name, how='left') return new_order return __join_data return _join_data @join_data('get_coupon_info', 'order_id') @join_data('get_order_good_info', 'order_id') @join_data('get_order_info', 'user_id') def get_order_detail(user_id, conn=None): ''' 拼凑获得订单信息 ''' user_ids = [str(user_id)] return get_user_info(user_ids, conn=conn) if __name__ == '__main__': print get_order_detail(10, conn=conn) conn.close() |
输出结果:
1 2 3 4 5 6 7 8 9 10 11 |
user_id name_x order_id num good_name name_y 0 10 HH 1 11111 order_good_1 coupon_7 1 10 HH 1 11111 order_good_2 coupon_7 2 10 HH 2 22222 order_good_3 NaN 3 10 HH 2 22222 order_good_4 NaN 4 10 HH 3 33333 order_good_5 coupon_9 5 10 HH 3 33333 order_good_6 coupon_9 6 10 HH 4 44444 order_good_7 NaN 7 10 HH 4 44444 order_good_8 NaN 8 10 HH 5 55555 order_good_9 coupon_11 9 10 HH 5 55555 order_good_10 coupon_11 |
从上面可以看到最后一列的券的信息,就是从test1库的coupon表关联来的。
1.5. 总结
通过系列文章的介绍我们知道拆分jion将会给我们带来各种的好处。
通过查分jion之后我们会看到系统现象是,应用程序的CPU利用率会上去。而数据库的CPU会下来,这也是我们想要的结果。如果一个应用程序CPU太高了你可以扩展多个应用程序。这中架构也是我们想要的。如果是使用JION那数据库的CPU上去了。我们将会很难扩展,并且扩展的成本、人力和物力将会是层倍的增加都不止。
到了这里,如果你还是觉得jion比拆分jion的效率高,代码量大的话。我只能说对不起了:我只是一个不称职的DBA,一个不懂得写复杂SQL的DBA。
以上乃个人观点。如果有得罪到大神们的地方,在这里我对你们说对不起,请原谅小菜鸟我的无知。当然,我更喜欢的是交朋友。有什么问题或不好的请多多指教。
昵称:HH
QQ:275258836
ttlsa群交流沟通(QQ群②:6690706 QQ群③:168085569 QQ群④:415230207(新) 微信公众号:ttlsacom)
感觉本文内容不错,读后有收获?

08/10/2016 下午 3:01 沙发
想问一下如果原来是多表联合查询得到分页的结果,那你以那个表作为基准取出需要分页的条数呢?