MySQL实现类似Oracle的序列
 
Oracle一般使用序列(Sequence)来处理主键字段,而MySQL则提供了自增长(increment)来实现类似的目的;
但在实际使用过程中发现,MySQL的自增长有诸多的弊端:不能控制步长、开始索引、是否循环等;若需要迁移
数据库,则对于主键这块,也是个头大的问题。
 
本文记录了一个模拟
Oracle序列的方案,重点是想法,代码其次。
 
Oracle序列的使用,无非是使用.nextval和.currval伪列,基本想法是:1、MySQL中新建表,用于存储序列名称和值;2、创建函数,用于获取序列表中的值;
具体如下:
表结构为
 
 
[sql] 
表结构为:  
| 
 1 
2 
3 
4 
5 
6 
7 
 | 
drop table if exists sequence;    
create table sequence (    
    seq_name        VARCHAR(50) NOT NULL,  
    current_val     INT         NOT NULL,  
    increment_val   INT         NOT NULL    DEFAULT 1,  
    PRIMARY KEY (seq_name)    
); 
 
 | 
 
 
 
 
实现currval的模拟方案
 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
 | 
[sql]   
create function currval(v_seq_name VARCHAR(50))    
returns integer   
begin   
    declare value integer;    
    set value = 0;    
    select current_value into value    
    from sequence   
    where seq_name = v_seq_name;    
    return value;    
end; 
 
 | 
 
 
 
 
[sql] 
函数使用为:select currval('MovieSeq');  
 
 
实现nextval的模拟方案
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
[sql]   
create function nextval (v_seq_name VARCHAR(50))    
return integer   
begin   
  update sequence   
  set current_val = current_val + increment_val    
  where seq_name = v_seq_name;    
  return currval(v_seq_name);    
end; 
 
 | 
 
 
 
 
[sql] 
函数使用为:select nextval('MovieSeq');  
 
增加设置值的函数
 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
 | 
[sql]   
create function setval(v_seq_name VARCHAR(50), v_new_val INTEGER)    
returns integer   
begin   
  update sequence   
  set current_val = v_new_val    
  where seq_name = v_seq_name;    
return currval(seq_name); 
 
 | 
 
 
 
 
 
同理,可以增加对步长操作的函数,在此不再叙述。
注意语法,数据库字段要对应上
 use bvboms; 
DELIMITER $$ 
create function setval(v_seq_name VARCHAR(50), v_new_val INTEGER) 
returns integer 
begin 
  update sequence 
  set current_val = v_new_val 
  where seq_name = v_seq_name; 
return currval(seq_name);
end $$
DELIMITER $$