1. 程式人生 > >mysql儲存過程--建立表以及根據已有的表進行分表分庫

mysql儲存過程--建立表以及根據已有的表進行分表分庫

建立多表的儲存過程

/* -----------------------t_user分表SQL--------------------------------*/
drop PROCEDURE if exists import_user_data;
create PROCEDURE import_user_data(IN table_num int)
-- table_num 表示有多少張表
-- 匯出資料到user的分表
BEGIN
        DECLARE table_name VARCHAR(30); 
    declare table_pre varchar(20) default 't_user_'; -- 表字首
declare temp_text text default ''; declare alter_text text default ''; set @temp_table_num = table_num; -- 分了多少張表賦給一個臨時變數 while table_num > -1 DO set table_num = table_num - 1; set table_name = CONCAT(table_pre,table_num); set temp_text = CONCAT('CREATE TABLE '
,table_name,' AS SELECT * FROM t_user WHERE id%',@temp_table_num,'=',table_num);
SELECT temp_text; -- 執行SQL SET @sql_text=temp_text; PREPARE stmt FROM @sql_text; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- 建立主鍵 set
temp_text = CONCAT('ALTER TABLE ',table_name,' ADD CONSTRAINT PK_ID PRIMARY KEY (id)');
SELECT temp_text; -- 執行SQL SET @sql_text=temp_text; PREPARE stmt FROM @sql_text; EXECUTE stmt; DEALLOCATE PREPARE stmt; end while; end; -- 呼叫如下: -- set @table_num = 10; -- call import_user_data(@table_num); /* -----------------------t_user分表SQL--------------------------------*/

通用的–根據已有的表(表資料比較大時)進行分庫分表

-- 說明:此儲存過程唯一定死的就是user_id,是user_id的個位取模db_num個為資料庫字尾,user_id個位以上取模table_num為表字尾;
-- 老鐵們可根據自己專案的需要,自行改編


drop PROCEDURE if exists common_split_db_table;
CREATE PROCEDURE `common_split_db_table`(IN db_num int,IN table_num int,IN db_pre varchar(30),IN table_pre varchar(30),IN data_table_name varchar(30))
BEGIN
        -- 儲存過程說明,通用的分庫分表儲存過程
    -- db_num   分多少個數據庫 
    -- table_num  每個資料庫多少張表     
        -- db_pre 資料庫名稱字首
        -- table_pre 分表的字首
        -- data_table_name 原資料表的名稱,如: 將t_sport表的資料拆分為10資料庫,10張表,則data_table_name為 t_sport

    --  資料庫相關定義
        declare db_name varchar(30) default '';  -- 資料庫名稱  
        -- declare db_pre varchar(30) default 'hesvit_sport_';  -- 資料庫名稱字首
        declare db_sql_text text default '';
        declare db_num_tp int(10) default 0; -- 取模的基數
        --   table相關定義
        declare table_name varchar(30) default '';   -- 分表的名稱
        -- declare table_pre varchar(20) default 't_sport_'; -- 分表的字首
    declare table_sql_text text default '';
      declare table_num_tp int(10) default 0; -- 分表取模的基數


        set db_num_tp = db_num;

        -- ················進行分庫操作··············
        while db_num_tp > 0 DO
                set db_num_tp = db_num_tp - 1;

                set db_name =  CONCAT(db_pre,db_num_tp);
                -- 拼接建立資料執行的SQL
        set db_sql_text = CONCAT('create database if not exists ',db_name,' DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci');

                select db_sql_text;

                SET @sql_text=db_sql_text;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;  

                -- ················進行分表操作··············
                set table_num_tp = table_num;
                while table_num_tp > 0 DO
                        set table_num_tp = table_num_tp - 1;
                        set table_name = CONCAT(table_pre,table_num_tp);
                        -- 拼接執行的SQL
                        -- 一下SQL是根據user_id的個位取模db_num個為資料庫字尾,user_id個位以上取模table_num為表字尾
                        -- select * from t_sport where SUBSTR(user_id,1 ,LENGTH(user_id)-1)% table_num = table_num_tp and SUBSTR(user_id,LENGTH(user_id)) % db_num = db_num_tp
                        set table_sql_text = CONCAT('create table ',db_name,'.',table_name,'  AS SELECT * FROM ',data_table_name,' WHERE SUBSTR(user_id,1 ,LENGTH(user_id)-1)%'
                        ,table_num,'=',table_num_tp,' and SUBSTR(user_id,LENGTH(user_id)) %',db_num,' = ',db_num_tp);


                        select table_sql_text;

                        SET @sql_text_1=table_sql_text;
                        PREPARE stmt FROM @sql_text_1;
                        EXECUTE stmt;
                        DEALLOCATE PREPARE stmt;

                        -- 給各個sport的分表新增主鍵
                        set table_sql_text = CONCAT('ALTER TABLE ',db_name,'.',table_name,' ADD CONSTRAINT PK_ID PRIMARY KEY (id)');
                        -- 執行SQL
                        SET @sql_text_1=table_sql_text;
                        PREPARE stmt FROM @sql_text_1;
                        EXECUTE stmt;
                        DEALLOCATE PREPARE stmt;
                end while;

    end while;

end


set @db_num = 5;
set @table_num = 20;
set @db_pre = 'hesvit_db_';
set @table_pre = 't_sport_';
set @data_table_name = 't_sport1';
call common_split_db_table(@db_num,@table_num,@db_pre,@table_pre,@data_table_name);

運用到遊標插入表資料

我的理解,遊標就相當於一個集合,再從遊標中迭代資料

CREATE DEFINER=`root`@`%` PROCEDURE `create_data_item_reason`()
BEGIN
        DECLARE text_sql text;  -- 執行的SQL語句
        DECLARE str_1 varchar(50) DEFAULT '推送太頻繁';
        DECLARE str_2 varchar(50) DEFAULT '內容重複';
        DECLARE str_3 varchar(50) DEFAULT '不想被打擾';
        DECLARE str_4 varchar(50) DEFAULT '資料偏差';
        DECLARE str_5 varchar(50) DEFAULT '對我無作用';
        DECLARE str_6 varchar(50) DEFAULT '其他';
        DECLARE str_7 varchar(50) DEFAULT '-1';
        DECLARE t_date_time datetime;

        DECLARE temp_id int(11) default 0;
        DECLARE temp_name varchar(50) default '';

        DECLARE cur_end int(11) default 1;
        -- 定義一個遊標
        declare cur_reson cursor for select id,name from t_message_item;
        DECLARE EXIT HANDLER FOR NOT FOUND SET cur_end = 0;
        -- 開啟遊標
        open cur_reson;

        set t_date_time = SYSDATE();
    while cur_end > 0 DO
                -- 迭代遊標
                fetch cur_reson into temp_id,temp_name;
                select temp_id,temp_name;
                -- 1
                set text_sql = CONCAT('insert into t_message_item_reason (item_id,reason,remark,create_user_id,create_time,update_user_id,update_time) values (',temp_id,',','''',str_1,'''',',');              
                set text_sql = CONCAT(text_sql,'''','','''',',1,','''',t_date_time,'''',',1,','''',t_date_time,'''',')');   
                select text_sql;    

                SET @sql_text = text_sql;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
        -- 2
                set text_sql = CONCAT('insert into t_message_item_reason (item_id,reason,remark,create_user_id,create_time,update_user_id,update_time) values (',temp_id,',','''',str_2,'''',',');              
                set text_sql = CONCAT(text_sql,'''','','''',',1,','''',t_date_time,'''',',1,','''',t_date_time,'''',')');   
                select text_sql;    

                SET @sql_text = text_sql;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
                -- 3
                set text_sql = CONCAT('insert into t_message_item_reason (item_id,reason,remark,create_user_id,create_time,update_user_id,update_time) values (',temp_id,',','''',str_3,'''',',');              
                set text_sql = CONCAT(text_sql,'''','','''',',1,','''',t_date_time,'''',',1,','''',t_date_time,'''',')');   
                select text_sql;    

                SET @sql_text = text_sql;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
-- 4
                set text_sql = CONCAT('insert into t_message_item_reason (item_id,reason,remark,create_user_id,create_time,update_user_id,update_time) values (',temp_id,',','''',str_4,'''',',');              
                set text_sql = CONCAT(text_sql,'''','','''',',1,','''',t_date_time,'''',',1,','''',t_date_time,'''',')');   
                select text_sql;    

                SET @sql_text = text_sql;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
-- 5
                set text_sql = CONCAT('insert into t_message_item_reason (item_id,reason,remark,create_user_id,create_time,update_user_id,update_time) values (',temp_id,',','''',str_5,'''',',');              
                set text_sql = CONCAT(text_sql,'''','','''',',1,','''',t_date_time,'''',',1,','''',t_date_time,'''',')');   
                select text_sql;    

                SET @sql_text = text_sql;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
                -- 6
                set text_sql = CONCAT('insert into t_message_item_reason (item_id,reason,remark,create_user_id,create_time,update_user_id,update_time) values (',temp_id,',','''',str_6,'''',',');              
                set text_sql = CONCAT(text_sql,'''','','''',',1,','''',t_date_time,'''',',1,','''',t_date_time,'''',')');   
                select text_sql;    

                SET @sql_text = text_sql;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
-- 7
                set text_sql = CONCAT('insert into t_message_item_reason (item_id,reason,remark,create_user_id,create_time,update_user_id,update_time) values (',temp_id,',','''',str_7,'''',',');              
                set text_sql = CONCAT(text_sql,'''','','''',',1,','''',t_date_time,'''',',1,','''',t_date_time,'''',')');   
                select text_sql;    

                SET @sql_text = text_sql;
                PREPARE stmt FROM @sql_text;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
        end while;
        -- 關閉遊標
        close cur_reson; 
end