一、前言
近幾個月項(xiàng)目中數(shù)據(jù)庫開始分庫了,把一個原本60多張表的數(shù)據(jù)庫分成了6個部分,每個部分有自己業(yè)務(wù)之內(nèi)的表,整個數(shù)據(jù)庫只是物理分開,邏輯依然是鏈接的,通過mycat這個數(shù)據(jù)庫中間件對整個數(shù)據(jù)庫進(jìn)行路由轉(zhuǎn)發(fā)。但是分庫后隨之而來的問題之一就是跨庫join,可以說網(wǎng)上的解決方案已經(jīng)爛大街了。但是小編還是覺得有必要總結(jié)分析一下。
二、數(shù)據(jù)庫結(jié)構(gòu)示例
為了公司數(shù)據(jù)保密,小編建立兩個新的數(shù)據(jù)庫,來做這個實(shí)驗(yàn)。
數(shù)據(jù)庫db1?
只有一個t_student表,表中有db2中的t_school表的外鍵
數(shù)據(jù)庫db2
只有t_school表
三、如何進(jìn)行跨庫連表查詢呢?
就上面的考慮來看,我想要查詢到這個學(xué)生的信息和所在學(xué)校的信息,如果t_student和t_school在一個庫中,就可以通過join進(jìn)行查詢:
但是,現(xiàn)在兩張表不在一個數(shù)據(jù)庫中,如何解決呢?有沒有跨庫查詢SQL Join的語句呢?
解決方案】
3.1 開啟FEDERATED引擎
Mysql的常見的引擎類型有MyIsam,InnoDB等。并且我們可以通過show engines;命令來查看,數(shù)據(jù)庫支持的所有的引擎。
如果要想實(shí)現(xiàn)跨庫Join查詢,我們可以使用FEDERATED引擎來實(shí)現(xiàn)。但是默認(rèn)情況下,F(xiàn)EDERATED引擎是關(guān)閉的,所以就需要我們?nèi)y.cnf的配置文件中進(jìn)行相關(guān)的配置。
在my.cnf 文件中添加federated,然后重啟啟動mysql服務(wù)
my.cnf:
重啟mysql服務(wù)
3.2 建立鏈接表
限制:
1.本地結(jié)構(gòu)字段可以是遠(yuǎn)程表的部分字段,字段必須相同
2.不支持事務(wù)
3.不支持表結(jié)構(gòu)修改
建表語句格式:
CREATE TABLE xxx(...) ENGINE=FEDERATED CONNECTION='mysql://[name]:[password]@[location]:[port]/[db-name]/[table-name]'
說明:?
name:遠(yuǎn)程數(shù)據(jù)庫賬號?
password:遠(yuǎn)程數(shù)據(jù)庫密碼?
location:遠(yuǎn)程數(shù)據(jù)庫Ip地址?
port:數(shù)據(jù)庫端口?
db-name:數(shù)據(jù)庫名字?
table-name:表名
【例子】?
建立鏈接t_school表:
CREATE TABLE `t_school` (
`id` varchar(22) NOT NULL,
`school_name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 COMMENT='學(xué)校表-鏈接表' CONNECTION='mysql://root:root@192.168.22.177:3306/db2/t_school';
經(jīng)過這些步驟,我們就把另外一個庫的表,鏈接到了我們操作的庫上了。這樣就可以使用JOIN等語句,間接進(jìn)行跨庫操作啦
四、一些操作
4.1 更新本地鏈接表
update t_school set school_name ='langfang' where id ='1'
對本地進(jìn)行更新操作,本地和遠(yuǎn)程數(shù)據(jù)庫都改變了。
4.2 增加字段
alter table t_school add column idtest INT DEFAULT 0;
錯誤:federated存儲引擎不支持alter table 操作
4.3 刪除表
刪除表
drop table t_school;
刪除本地表對遠(yuǎn)程表無影響
五、小結(jié)
數(shù)據(jù)庫的操作還是有很多的,有問題就解決問題,操作就是這樣。加油!