MySQL的跨庫join

功能需求

首先要理解原始需求是什麼,爲什麼要跨庫join。舉個簡單的例子,在日誌數據庫log_db有一份充值記錄表pay_log,裏面的用戶信息只有一個userid;而用戶的詳細信息放在主庫main_db,裏面有用戶的詳細信息表user_info,如用戶名、登錄時間、註冊時間、會員等級 等等。如果只是按用戶名查找充值記錄,那可以很簡單地分兩次查詢即可。但是更復雜的需求,比如按註冊時間排序,按會員等級統計等等,稍微複雜一點的功能,分次查詢就相當難以做到了。如果在同一個庫裏,我們可以很方便的使用join關鍵字實現這些功能,但是在不同的數據庫裏,並沒有跨庫查詢的SQL JOIN語句。那怎麼辦呢?

方案一: 字段冗餘

也就是說把一部分信息重複存放,比如 pay_log表裏除了userid字段還有user_name字段,等等。但是這隻適合加少量字段,如果把註冊、登錄時間、等級等等都字段都重複一遍,那是顯然不科學的。

方案二: 表複製和同步

也就是說把main_db裏面的user_info表複製一份到log_db中,然後設置定時任務讓這兩個表進行同步。這樣確實是可以在一個庫裏,然後可以進行 JOIN 等的複雜語句操作了。但是這兩個表的內容是重複的,未免會比較浪費空間。

方案三: 鏈接表

什麼是鏈接表呢?簡單來說,就是在log_db裏有一個user_info表,但這個表並沒有存儲數據,而是直接鏈接到了 main_db裏的user_info表。這樣的話,我們可以既無需定期同步,又可以像在同一個庫裏使用JOIN等操作。


開啓 FEDERATED 引擎

以MySQL爲例,鏈接表與常見的 MyISAM, InnoDB 等等,都是一種表的結構類型(稱之爲 存儲引擎)。使用 show engines; 命令即可看到數據庫所支持的存儲引擎,默認 FEDERATED 引擎 是關閉的,我們需要去mysql配置文件開啓它。

實現數據庫的跨庫join

開啓的方法很簡單,在windows下只需要在mysql的配置文件 my.ini 最末尾加上一句 federated ,然後重啓mysql即可。重啓後輸入 show engines;命令即可看到 FEDERATED 的 Support 變爲 YES,表示federated引擎已經開啓。


新建鏈接表(federated引擎的表)

既然是鏈接的表,那麼會有以下幾個限制:

  • 本地的表結構必須與遠程的完全一樣
  • 遠程數據庫目前僅限MySQL
  • 不支持事務
  • 不支持表結構修改

建表的語句如下

CREATE TABLE xxx(...) ENGINE=FEDERATED CONNECTION='mysql://[name]:[pass]@[location]:[port]/[db-name]/[table-name]'

當然不建議這樣自己手工從頭拼裝SQL語句,可以把mian_db的user_info表的結構導出來,然後修改最後的半句,再導進去就行啦。建表語句示例如下:

CREATE
 TABLE `user_info` (
  `userid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶id',
  `username` varchar(60) NOT NULL DEFAULT '' COMMENT '帳號',
  `level` int(11) NOT NULL DEFAULT '1' COMMENT '等級',
  `log_dt` timestamp NOT NULL DEFAULT '2016-11-30 00:00:00' COMMENT 
'最後登錄時間',
  `reg_dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '註冊時間',
  PRIMARY KEY (`userid`),
  KEY `idx_name` (`username`)
) ENGINE=FEDERATED DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT 
CONNECTION='mysql://batsing:b8a7t4@localhost:3306/main_db/user_info'  
COMMENT='用戶基本信息表-鏈接表';

經過這些步驟,我們就把另外一個庫的表,鏈接到了我們操作的庫上了。這樣就可以使用JOIN等語句,間接進行跨庫操作啦

發佈了94 篇原創文章 · 獲贊 43 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章