一條SQL完成跨數據庫實例Join查詢
隨着業務復雜程度的提高、數據規模的增長,越來越多的公司選擇對其在線業務數據庫進行垂直或水平拆分,甚至選擇不同的數據庫類型以滿足其業務需求。原本在同一數據庫實例里就能實現的SQL查詢,現在需要跨多個數據庫實例才能完成。業務的數據被“散落”在各個地方,如何方便地對這些數據進行匯總關聯查詢,已經成為困擾用戶的一大難題。
針對這類問題,傳統的解決方案需要用戶提前將所有實例的數據提前匯集到匯總庫進行查詢分析。這種方案不僅無法滿足查詢時效性,且用戶還需要承擔數據匯集的鏈路穩定性風險及數據冗余的經濟成本。
為了解決跨數據庫實例及時查詢的難題,阿里雲DMS(數據管理)推出了跨數據庫實例查詢服務。
DMS跨數據庫查詢
跨實例查詢服務支持通過標准SQL進行跨同異構數據庫的實時查詢。除了關系型數據庫MySQL、SQLServer、PostgreSQL,還支持Redis。同時,跨實例查詢服務還支持跨地域、跨雲及線下IDC自建數據庫及跨雲廠商數據庫實例間的數據實時查詢,被廣泛應用於多地域部署業務的全局數據查詢場景。
本文以MySQL及Redis為例,介紹如何通過一條SQL輕松完成跨數據庫實例的查詢。
通過標准SQL查詢Redis
跨實例查詢服務支持通過SQL查詢Redis中的任意key,同時支持跨key之間的join查詢。在進行SQL查詢前,您需要先在跨實例查詢服務中,創建Redis實例的DBLink。接下來簡單介紹創建DBLink及進行SQL查詢的流程。
創建DBLink
在跨實例查詢服務的控制台,創建DBLink,配置Redis實例的連接信息。
當完成DBLink創建后,需要使用這個DBLink編寫查詢SQL。
通過SQL查詢Key
跨實例查詢服務提供WEB SQL命令窗口,可以直接在命令窗口中,通過標准的SQL進行Key查詢。具體支持的SQL命令可以參考使用文檔。
對於每一個redis的database, DMS會自動創建6張表,分別如下:
all: 存儲所有的key
string: 存儲數據類型為string的可以
hash:存儲數據類型為hash的key
list: 存儲數據類型為list的key
set:存儲數據類型為set的key
zset:存儲數據類型為score set的key
每張表的表結構如下:
列名 | 類型 | 說明 |
---|---|---|
Key | Varchar | Redis中的key名 |
Index | Varchar | 當數據類型為list/zset時,為各個元素的index;當數據類型為hash時,改字段為hash中的key名稱 |
Value | Varchar | Key的value值 |
Score | Double | 表示SortedSet的分值,其他數據類型為null |
Expire_time | Bigint | 跟redis的ttl命令一致,表示數據離過期的剩余秒數 |
Data_type | Varchar | 這個key的數據類型 |
此處,我們通過通過如下的select語句查詢all表中的前5個key。
select * from redis_test.db0.all limit 5;
跨MySQL&Redis Join查詢
日前接到某游戲客戶跨MySQL及Redis查詢的需求。該客戶將用戶積分排行榜存儲在redis myzset中,而將用戶元信息維護在MySQL user 表中。用戶的某個簡單訴求是:在游戲APP中能實時刷新用戶的積分排行榜。
數據結構
通過redis score set存儲用戶積分情況,存儲用戶ID及score, key的名稱為user_scrore, value為用戶ID, score為用戶積分。樣例數據如下表:
key | value | score |
---|---|---|
user_score | 100 | 10 |
user_score | 200 | 35 |
user_score | 300 | 45 |
通過MyQL User表存儲用戶的基本信息,包括user_id, user_name,province, city, gmt_create等,其中:
User_id 為用戶ID, User_name 為用戶名
Province 為用戶所屬省份, city 為用戶所屬市
Gmt_create 為用戶第一次登陸游戲APP的時間
樣例數據如下表:
User_id | User_name | province | city | Gmt_create |
---|---|---|---|---|
100 | 張三 | 浙江 | 杭州 | 2018-11-11 11:11:11 |
200 | 李四 | 廣東省 | 深圳 | 2018-10-11 12:11:01 |
關聯查詢
通過如下SQL,可方便得查詢用戶的積分排行榜。
select user.user_name,zset.score from redis_test.db0.zset as zset join mysql.db0.user as user where
user.user_id=zset.value and zset.key='user_score' order by zset.score desc;
這個SQL將redis中的用戶ID跟MySQL中的user_id進行關聯,且只查詢存儲用戶積分的key。