通用分表存储过程

使用创建分表存储过程

Java代码  

  1. set @field_list ='  
  2.   `syslog_id` int(11) NOT NULL AUTO_INCREMENT,  
  3.   `create_user` varchar(32) DEFAULT NULL,  
  4.   PRIMARY KEY (`syslog_id`)  
  5. ';    
  6. call branch_table('test', @field_list, 4, 2);  

创建分表存储过程

Java代码  

  1. DROP PROCEDURE IF EXISTS `branch_table`;  
  2. CREATE PROCEDURE `branch_table`(  
  3.     IN     p_table_name   VARCHAR(200),       
  4.     IN     p_field_list   VARCHAR(2048),   
  5.     IN     p_branch_size  INT,                        
  6.     in     p_lpad         INT  
  7. )  
  8. BEGIN  
  9.     /*定义变量*/  
  10.     DECLARE m_begin_row INT DEFAULT 0;  
  11.       
  12.     WHILE m_begin_row<p_branch_size DO    
  13.         /*构造语句*/     
  14.         SET @MAIN_STRING = CONCAT('CREATE TABLE ', p_table_name, '_', LPAD(m_begin_row, p_lpad, 0), '(', p_field_list ,')ENGINE=InnoDB DEFAULT CHARSET=utf8;');  
  15.        
  16.         /*预处理*/  
  17.         PREPARE main_stmt FROM @MAIN_STRING;  
  18.         EXECUTE main_stmt;  
  19.         SET m_begin_row=m_begin_row+1;  
  20.     END WHILE;  
  21. END;  

 前期没有分表数据量太大后期拆表用的MySQL存储过程

简单的办法是直接写
--假设根据user_id分表,分成64张

Java代码  

  1. insert into table_new_0000 select * from table_old where mod(user_id,64)=0;    
  2. insert into table_new_0001 select * from table_old where mod(user_id,64)=1;  

一共64条sql,OK 搞定。但是这个一张表被全表扫描了64次,做的无用功比较多,而且导致停机时间比较长

创建分表

Java代码  

  1. delimeter //  
  2. --- 全量脚本:  
  3. CREATE PROCEDURE  sp_xf_move_item()    
  4. begin    
  5. declare v_exit int default 0;    
  6. declare v_spid bigint;    
  7. declare v_id bigint;    
  8. declare i int default 0;    
  9. declare c_table int;  
  10. --定义游标(要分拆的表,定义一个数量的截止时间)  
  11.   
  12. declare c_ids cursor for select id,user_id from item_records_0000 where gmt_modified < '2010-8-25 00:00:00';    
  13. declare  continue handler for not found set v_exit=1;    
  14. open c_ids;    
  15. repeat    
  16. --将需要的值装入变量  
  17.   
  18. fetch c_ids into v_id,v_spid;    
  19. if v_exit = 0 then    
  20. set @vv_id = v_id;    
  21. --根据取模字段获取数据存在的表  
  22.   
  23. select mod(v_spid,64) into c_table;    
  24. --组装动态sql  
  25. SET @SQL_CONTEXT =    
  26. CONCAT('insert into item_record_',    
  27. LPAD(c_table, 4, 0),    
  28. ' select * from item_records_0000 where id = ?');    
  29.    
  30. PREPARE STMT FROM @SQL_CONTEXT;    
  31. --执行sql    
  32. EXECUTE STMT using @vv_id;    
  33. DEALLOCATE PREPARE STMT;    
  34. end if;    
  35. set ii=i+1;    
  36.    
  37. --100条提交一次,以提高效率,记得执行存储过程前设置auto_commit  
  38.   
  39. if mod(i,100)=0 then commit;    
  40. end if;    
  41. until v_exit=1   
  42. end repeat;    
  43. close c_ids;    
  44. commit;    
  45. end;    
  46. //   

set auto_commit=0;  
call sp_xf_move_item(); 

添加数据

Java代码  

  1. #### 增量脚本 ######    
  2. CREATE PROCEDURE sp_xf_add_item()    
  3. begin    
  4. declare v_exit int default 0;    
  5. declare v_spid bigint;    
  6. declare v_id bigint;    
  7. declare i int default 0;    
  8. declare c_table int;    
  9. declare c_ids cursor for select id,supplier_id from item_records_0000 where gmt_modified >= '2010-8-25 00:00:00';    
  10. declare  continue handler for not found set v_exit=1;    
  11. open c_ids;    
  12. repeat    
  13.    
  14. fetch c_ids into v_id,v_spid;    
  15. if v_exit = 0 then    
  16. set @vv_id = v_id;    
  17. set @v_row=0;    
  18. select mod(v_spid,64) into c_table;    
  19.    
  20. --判断数据是否已经存在  
  21.   
  22. SET @SQL_C =    
  23. CONCAT('select count(*) into @v_row from item_record_',    
  24. LPAD(c_table, 4, 0),    
  25. ' where id = ?');    
  26.    
  27. PREPARE STMT_C FROM @SQL_C;    
  28. EXECUTE STMT_C using @vv_id;    
  29. DEALLOCATE PREPARE STMT_C;                           
  30.    
  31. SET @SQL_INSERT =    
  32. CONCAT('insert into bbc_item_record_',    
  33. LPAD(c_table, 4, 0),    
  34. ' select * from item_records_0000 where id = ?');    
  35.    
  36. PREPARE STMT_I FROM @SQL_INSERT;             
  37.    
  38. SET @SQL_DELETE =    
  39. CONCAT('DELETE FROM bbc_item_record_',    
  40. LPAD(c_table, 4, 0),    
  41. ' where id = ?');    
  42. PREPARE STMT_D FROM @SQL_DELETE;         
  43. --如果数据已经存在,则先delete在insert               
  44.   
  45. if @v_row>0 then     
  46.    
  47. EXECUTE STMT_D using @vv_id;    
  48. DEALLOCATE PREPARE STMT_D;    
  49.    
  50. end if;    
  51. EXECUTE STMT_I using @vv_id;    
  52. DEALLOCATE PREPARE STMT_I;           
  53.    
  54. end if;    
  55. set ii=i+1;    
  56. if mod(i,100)=0 then commit;    
  57. end if;    
  58. until v_exit=1   
  59. end repeat;    
  60. close c_ids;    
  61. commit;    
  62. end;    
  63. //    

 call sp_xf_add_item()

时间: 2024-08-28 13:33:48

通用分表存储过程的相关文章

通用合并表存储过程 循环变量与字符连接

存储过程循环变量与字符连接 Java代码   mysql> DELIMITER $$   mysql> drop PROCEDURE sp_test_switch$$   Query OK, 0 rows affected (0.01 sec)      mysql> CREATE PROCEDURE sp_test_switch()       -> BEGIN       ->  declare a int;       ->  declare b varchar(

新闻数据库分表案例

Netkiller MySQL 手札 MySQL MariaDB... Mr. Neo Chan, 陈景峰(BG7NYT) 中国广东省深圳市龙华新区民治街道溪山美地518131+86 13113668890+86 755 29812080<netkiller@msn.com> 文档始创于2010-11-18 版权 2011, 2012, 2013 Netkiller(Neo Chan). All rights reserved. 版权声明 转载请与作者联系,转载时请务必标明文章原始出处和作者信

如此高效通用的分页存储过程是带有sql注入漏洞的

存储过程|分页 在google中搜索"分页存储过程"会出来好多结果,是大家常用的分页存储过程,今天我却要说它是有漏洞的,而且漏洞无法通过修改存储过程进行补救,如果你觉得我错了,请读下去也许你会改变看法.通常大家都会认为存储过程可以避免sql注入的漏洞,这适用于一般的存储过程,而对于通用分页存储过程是不适合的,请看下面的代码和分析! 一般的通用的分页存储过程代码如下: 通用分页存储过程CREATE PROCEDURE pagination@tblName varchar(255), --

Mysql第八天 分区与分表

分区表 主要提供如下的特性,或者适合如此场景: 数据量非常大, 或者只有表中最后的部分有热点数据,其他均为历史数据 分区表数据更容易维护,可以对独立的分区删除等操作 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备. 可以避免一些特殊瓶颈,比如InnoDB的单个索引的互斥访问 可以备份和恢复独立的分区 创建分区表 通常有这么几种分法,因为主键或者是唯一约束键必须有一部分包含在分区键中,所以一般要不无主键,要不就按照自增主键的id进行范围分区,要不就把分区字段和主键一起作为联合主

mysql —— 分表分区(1)

面对当今大数据存储,设想当mysql中一个表的总记录超过1000W,会出现性能的大幅度下降吗? 答案是肯定的,一个表的总记录超过1000W,在操作系统层面检索也是效率非常低的 解决方案: 目前针对海量数据的优化有两种方法: 1.大表拆小表的方式(主要有分表和分区两者技术) (1)分表技术 垂直分割 优势:降低高并发情况下,对于表的锁定. 不足:对于单表来说,随着数据库的记录增多,读写压力将进一步增大. 水平分割 如果单表的IO压力大,可以考虑用水平分割,其原理就是通过hash算法,将一张表分为N

透明的分库分表方案

问题提出 随着应用规模的不断扩大,单机数据库就慢慢无法满足应用的需要了,这主要表现在如下方面: 存量数据越来越大,查询速度越来越慢 访问并发越来越大,磁盘IO.网络IO.CPU都慢慢成为瓶颈 事务数越来越多,事务冲突越来越严重,导致TPS越来越少 这个时候,有的人采用了换商用数据库的方案比如Oracle,然后用Oracle的RAC方式进行水平扩展.但是带来的缺点也比较明显,第一是成本太高,一般人吃不消:第二,管理复杂度较单节点有非常大的提升,风险及管理成本也相应增加:第三,对人员的水平要求更高,

分库 分区 分表-数据库大表是分库,分区,还是分表?

问题描述 数据库大表是分库,分区,还是分表? 10C 数据库大表是分库,分区,还是分表?数据库大表是分库,分区,还是分表?数据库大表是分库,分区,还是分表? 解决方案 要根据实际情况来,有的数据读的多,写的少,有的数据写的多读的少,有的数据查询多,读写都少.不同情况有不同的措施. 解决方案二: 大表首先是分区.降低文件io,然后再对应数据的分表 解决方案三: 1.当数据库压力很大时分区集群,比如有成千上完客户端同一时间频繁访问数据库,每个字段内容又很大时,比如网站的文章库 2.当有大量陈年数据在

数据库分表后,并发环境下,生成全局id生成的几种方式

最近一个项目由于数据量变大,需要进行数据分表.数据存储在淘宝的tddl上.分表后,原先的自增id就不能使用了.tddl对java支持很好,分表后无需考虑全局id的问题.但是这个项目使用的是php进行开发,必须自己生成全局id.以下列出几种分表方案,仅当抛砖引玉. 方法1:使用CAS(compare and swap) 其实这里并不是严格的CAS,而是使用了比较交换原子操作的思想. 生成思路如下: 每次生成全局id时,先从sequence表中获取当前的全局最大id.然后在获取的全局id上做加1操作

ThinkPHP处理海量数据分表机制详细代码及说明

  应用ThinkPHP内置的分表算法处理百万级用户数据. 数据表: house_member_0 house_member_1 house_member_2 house_member_3 模型中 class MemberModel extends AdvModel { protected $partition = array('field'=>'username','type'=>'id','num'=>'4'); public function getDao($data=array(