原來MySQL的存儲過程也能夠這麼玩?

1、什麼是存儲過程?

MySQL5.0版本開始支持的存儲過程。
存儲過程(Stored Procedure)是一種在數據庫中存儲複雜程序,以便外部程序調用的一種數據庫對象。
存儲過程是爲了完成特定功能的SQL語句集,經編譯建立並保存在數據庫中,用戶可經過指定存儲過程的名字並給定參數(須要時)來調用執行。
存儲過程思想上很簡單,就是數據庫 SQL 語言層面的代碼封裝與重用。

2、存儲過程優缺點

2.1 優勢css

  1. 存儲過程可封裝,並隱藏複雜的商業邏輯。java

  2. 存儲過程能夠回傳值,並能夠接受參數。程序員

  3. 存儲過程沒法使用數據庫

  4. 存儲過程沒法使用select指定來運行,由於他是子程序,與查表,數據表或函數定義不一樣。編程

  5. 存儲過程能夠用在數據校驗,強制實行商業邏輯等。app

2.2 缺點less

  1. 存儲過程,每每定製化特定數據庫上,由於支持的編程語言不一樣。當切換到其餘廠商的數據系統時,須要重寫原有的存儲過程。編程語言

  2. 存儲過程的性能調校撰寫,受限於各類數據庫系統。ide

3、存儲過程有哪些特性

  1. 有輸入輸出參數,能夠聲明變量,有if/else, case,while等控制語句,經過編寫存儲過程,能夠實現複雜的邏輯功能。模塊化

  2. 函數的廣泛特性:模塊化,封裝,代碼複用。

  3. 速度快,只有首次執行需通過編譯和優化步驟,後續被調用能夠直接執行,省去以上步驟。

4、實戰操做

生成千萬級數據量

實現思路:首先咱們建立2張表一張表是存儲真正的數據,另外一種表建立內存表用來臨時存儲數據。咱們使用存儲過程效率會很是高。

4.1 建立內存表與普通表

#建立普通表
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT primary key comment '主鍵id',
`user_id` varchar(36) NOT NULL  comment '用戶id',
`user_name` varchar(30) NOT NULL comment '用戶名稱',
`phone` varchar(20) NOT NULL comment '手機號碼',
`lan_id` int(9) NOT NULL comment '本地網',
`region_id` int(9) NOT NULL comment '區域',
`create_time` datetime NOT NULL comment '建立時間',
 KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;#建立內存表CREATE TABLE `user_memory` (
`id` int(11) NOT NULL  PRIMARY KEY  AUTO_INCREMENT comment '主鍵id',
`user_id` varchar(36) NOT NULL  comment '用戶id',
`user_name` varchar(30) NOT NULL comment '用戶名稱',
`phone` varchar(20) NOT NULL comment '手機號碼',
`lan_id` int(9) NOT NULL comment '本地網',
`region_id` int(9) NOT NULL comment '區域',
`create_time` datetime NOT NULL comment '建立時間',
KEY `idx_user_id` (`user_id`)
) ENGINE=MEMORY DEFAULT CHARSET=utf8mb4;

4.2 建立存儲過程

4.2.1 建立生成N個隨機數函數

#生成N個隨機數字
DELIMITER $$CREATE FUNCTION randNumber(N int) RETURNS VARCHAR(255)
begin    # 定義一個默認獲取的值0-9
   declare chars_str varchar(20) default '0123456789';
   #將隨機獲取後得值保存在 return_str    DECLARE return_str varchar(255) DEFAULT '';
   # 定義一個變量用來判斷循環的參次數    DECLARE i INT DEFAULT 0;
   WHILE i < n        DO             # 使用隨機函數將 chars_str隨機獲取一個數字進行累加            SET return_str = concat(return_str, substring(chars_str, FLOOR(1 + RAND() * 10), 1));
            #變量加1
           SET i = i + 1;
       END WHILE;    #最終結果返回    RETURN return_str;END $$DELIMITER;

4.2.2 生成手機號碼

#生成隨機手機號碼
DELIMITER $$CREATE FUNCTION genePhone() RETURNS varchar(20)
BEGIN    # 定義一個變量用來保存    DECLARE head char(3);
   #定義一個變量用來保存最後生成的手機號    DECLARE phone varchar(20);
   #定義一個變量用來存儲經常使用的手機號開頭    DECLARE bodys varchar(100) default "130 131 132 133 134 135 136 137 138 139 186 187 189 151 157";
   #定義一個變量用來存儲開始截取的手機開頭    DECLARE starts int;    #隨機獲取一個手機號開頭索引    SET starts = 1 + floor(rand() * 15) * 4;
   #使用substring截取手機開頭    SET head = trim(substring(bodys, starts, 3));
   #將head與剛剛定義的存儲過程進行拼接將最終的結果發值給phone    SET phone = trim(concat(head, randNumber(8)));
   #數據返回    RETURN phone;END $$DELIMITER ;

4.2.3 生成隨機的字符串


#建立隨機字符串和隨機時間的函數DELIMITER $$CREATE FUNCTION randString(N INT) RETURNS varchar(255) CHARSET utf8mb4
DETERMINISTICBEGIN  #定義一個字符串用來存儲經常使用的字符與字母與數字 DECLARE chars_str varchar(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+}{":?<,./>?<?';
#定義一個字符串將要返回的字符串 DECLARE return_str varchar(255) DEFAULT '' ;
#定義一個用來保存每一個循環的次數 DECLARE i INT DEFAULT 0;
WHILE i < n DO   #隨機從chars_str 獲取一個字符串追加到return_str  SET return_str = concat(return_str, substring(chars_str, FLOOR(1 + RAND() * 79), 1));
 SET i = i + 1;
END WHILE;  #最終結果返回 RETURN return_str; END$$ DELIMITER;

4.2.4 向內存表中插入N條數據

# 建立插入內存表數據存儲過程   入參N是多少就插入多少條數據
DELIMITER $$CREATE PROCEDURE `add_user_memory`(IN N int)
BEGIN DECLARE i INT DEFAULT 1;
WHILE (i <= n) DO
 INSERT INTO user_memory (user_id, user_name, phone, lan_id,region_id, create_time) VALUES (uuid(), randString(20), genePhone(), FLOOR(RAND() * 1000), FLOOR(RAND() * 100), NOW());
 SET i = i + 1;
END WHILE; END $$ DELIMITER ;
#循環從內存表獲取數據插入普通表
#參數描述 n表示循環調用幾回;count表示每次插入內存表和普通表的數據量 DELIMITER $$ CREATE PROCEDURE `add_user_memory_to_outside`(IN n int, IN count int)
BEGIN DECLARE i INT DEFAULT 1;
WHILE (i <= n) DO
 CALL add_user_memory(count);
INSERT INTO user SELECT * FROM test_user_memory; delete from ser_memory;
SET i = i + 1;
END WHILE; END $$ DELIMITER ;

4.3 插入數據進行測試

#先調用存儲過程往內存表插入一萬條數據,而後再把內存表的一萬條數據插入普通表
CALL add_user_memory(10000);
#一次性把內存表的數據插入到普通表,這個過程是很快的INSERT INTO user SELECT * FROM user_memory;
#清空內存表數據delete from user_memory;
select count(1) from user
#10000
#使用 add_user_memory_to_outside 生成千萬數據量
call add_user_memory_to_outside(1000,10000)
#10010000

總結:本篇博客給你們講解了什麼是存儲過程及他能幹什麼,若是MySQL中存儲了大量數據的的話咱們根據條件進行查詢效率是很是慢的。在千萬級數據量下咱們查詢一張條查詢數據就須要3秒多的時間,每每在企業中查詢一條數據須要好幾秒的時間確定是不行的

218d701dbd1c49e987119d3ffad1de4e.jpg

最後

感謝你們看到這裏,若是本文有什麼不足之處,歡迎多多指教;若是你以爲對你有幫助,請給我點個贊。

也歡迎你們關注個人公衆號:程序員麥冬,麥冬天天都會分享java相關技術文章或行業資訊,歡迎你們關注和轉發文章!

相關文章
相關標籤/搜索