MySQL是常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它采用表的形式存儲數(shù)據(jù)。在數(shù)據(jù)庫應(yīng)用程序中,當(dāng)數(shù)據(jù)量增大,單一表會帶來訪問效率的下降。此時我們可以通過分表的方法來提高性能。
分表,即將數(shù)據(jù)按照某種規(guī)則劃分到不同的表里。一般的規(guī)則是按照時間或者按照數(shù)據(jù)類型來分表。下面我們通過例子來演示如何按照時間分表:
-- 建立總表 CREATE TABLE `orders` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) NOT NULL, `amount` decimal(10,2) NOT NULL, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 建立按月份分表 CREATE TABLE `orders_2019_01` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) NOT NULL, `amount` decimal(10,2) NOT NULL, `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 建立觸發(fā)器 DELIMITER $$ CREATE TRIGGER orders_insert BEFORE INSERT ON orders FOR EACH ROW BEGIN DECLARE v_tablename VARCHAR(128); SET v_tablename = CONCAT('orders_', DATE_FORMAT(NEW.create_time, '%Y_%m')); SET @s = CONCAT('INSERT INTO ', v_tablename,' (`user_id`, `amount`, `create_time`)',' VALUES (', NEW.user_id,',', NEW.amount,',', 'NOW())'); PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; END$$ DELIMITER ; -- 插入數(shù)據(jù) INSERT INTO orders (`user_id`, `amount`) VALUES (1, 100);
以上例子中,我們建立了總表orders和按月份分表orders_2019_01。通過觸發(fā)器,在插入數(shù)據(jù)到總表orders時,再根據(jù)數(shù)據(jù)的創(chuàng)建時間,將數(shù)據(jù)插入對應(yīng)的分表orders_2019_01中去。
分表的方式可以提高數(shù)據(jù)庫訪問效率,但是也要注意不要分得太細,否則會帶來數(shù)據(jù)查詢的麻煩和管理的復(fù)雜性。需要根據(jù)具體的應(yīng)用場景進行合理的分表策略。