1.3 术语和缩略语#
此处请填入文档中的专业术语及解释。
序号 | 术语/缩略语 | 全称和说明 |
---|---|---|
1 | Sequence(序列) | sequence(序列)用来产生序列号。 |
2 | rac模式数据库(集群) | 多个instance(又称实例或节点)对应一个oracle database即称为rac模式数据库。 |
3 | exclusive模式数据库 | 只有一个instance(又称实例或节点)对应一个oracle database即称为exclusive模式数据库。 |
2、简介#
本规范主要对数据库sequence的命名、操作方法、使用方法以及管理方法等规范做出定义。
3、技术规范 #
3.1创建sequence应遵循的设计要求#
3.1.1 要求所有的sequence的循环模式和maxvalue都必须遵循以下规则。
3.1.1.1主键sequence必须设定为NOCYCLE,maxvalue设定为不小于99999999999999999999(20个9),且不小于主键字段 number位数。
3.1.1.2非主键字段sequence必须设定为CYCLE,maxvalue长度与实际需要使用的数字位数一致,不能截取sequence值,且对sequence 值只能进行左补位。
例如:某一varchar2(12)类型的字段,需要使用一个长度为4位的sequence。该字段值的写入可能为yyyymmdd+4位seqno。该4为seqno必须左补0,如从0001开始。
seqno 的位数不能小于数据处理周期,需要提前做好预估。
3.1.2 要求所有的sequence都使用cache选项,cache值最低为40。
采用缓存(cache)技术,是为了减少对产生sequence值的等待,所有sequence的cache值最低为40。
附:sequence cache测试数据和结论
cache 20 :并发40左右出现enq: SQ - contention 等待事件;在并发大于8以后,平均获取sequence nextval 值时间降低到0.003以下。
cache 30 :并发45左右出现enq: SQ - contention 等待事件;在并发大于18以后,平均获取sequence nextval 值时间降低到0.003以下。
cache 40 :并发50左右出现enq: SQ - contention 等待事件。在并发大于22以后,平均获取sequence nextval 值时间降低到0.003以下。
测试过程中,发现随着并发的增大,seq的获取sql 执行效率逐渐降低,由于并发超过50的应用并不多,因此SEQUENCE cache 设定为40 可以满足绝大部分平安的应用。
3.1.3 创建sequence时,必须指定minvalue、maxvalue、start with、increment by、cache的值。
maxvalue的值要求设为全为9的数字,例如:maxvalue 999999 而不要设成maxvalue 911111。
修改start with值的方法请参考本文档后面的附录。
3.1.4 所有sequence使用noorder选项。
尤其在rac模式数据库中,不使用noorder会增加节点之间数据交换,从而引发性能问题。
3.1.5 Sequence的nextval值获取,必须直接使用select seq_name.nextval from dual 方式获取,不要额外进行一次配置表信息查询。
3.1.6禁止使用通过公共package来获取sequence值。
在历史规范内,要求配置 sequence 配置表,因此获取sequence值 会调用 形如下面的procedure, 在每次获取sequence 值,都要额外进行一次对pub_seq_config_info 表的查询,该查询有可能造成应用的性能瓶颈,因此要禁用这种获取sqeuence 值的方式。
procedure get_seq(p_table_name pub_seq_config_info.table_name%type, p_column_name pub_seq_config_info.column_name%type, p_table_owner pub_seq_config_info.table_owner%type, p_sequence out varchar2, p_flag out varchar2, p_mes out varchar2
) is v_sqlstr varchar2(200); v_seq_name pub_seq_config_info.seq_name%type; v_is_new_created pub_seq_config_info.is_new_created%type; v_database_id ubs_sid.database_id%type; v_sequence varchar2(20);
v_cursor number; v_temp number; begin p_flag:='1'; p_mes:='成功'; select seq_name, is_new_created
into v_seq_name, v_is_new_created
from pub_seq_config_info
where table_name=upper(p_table_name) and column_name=upper(p_column_name) and table_owner=upper(p_table_owner) and rownum=1;
select database_id
into v_database_id
from ubs_sid;
if v_is_new_created='Y' then v_cursor:=sys.dbms_sql.open_cursor;
v_sqlstr:='select '||v_seq_name||'.nextval '||' from '||' dual'; dbms_sql.parse(v_cursor, v_sqlstr,1); dbms_sql.define_column(v_cursor,1,v_sequence,20); v_temp := dbms_sql.execute( v_cursor); if dbms_sql.fetch_rows(v_cursor)<>0 then dbms_sql.column_value(v_cursor,1,v_sequence); end if; dbms_sql.close_cursor(v_cursor); v_sequence:=lpad(v_database_id,2,0)||to_char(sysdate,'yyyy')||lpad(v_sequence,14,0); --生成20位的sequence
else ----老的序列 null; …………………………………………省略部分代码 end get_seq;
附录#
附录A 脚本模板和范例#
创建sequence的模板:
create sequence umdata.seq_err_log_id
minvalue 1 maxvalue 99999999999999999999 --seq长度与字段number长度相同 start with 1 increment by 1 cache 40 nocycle
noorder;
附录B 修改sequence的start with值的例子#
有两种较为典型的情况会修改SEQUENCE 的 start with
- 1 、单独的系统表进行迁移,在新库里面如果已经有了sequence,且导入的值比当前sequence 的值大,则需要修改sequence start with值。
- 2 、系统的SEQUENCE.nextval已经达到 sequence 定义的maxvalue 值,且由于字段长度原因maxvalue不能加大需要修改sequence 的start with 值
修改Sequence的Start with值的例子见下面:
例子1:修改带cache选项的sequence的start with值
修改start with值时要保证修改后的当前start with值不能与表中的已有值重复。
需要现将CACHE属性修改为NOCACHE,再从user_sequences视图中查询出sequence的next value。
SEQ_SERVICE_LINE_ID的当前选项值如下:
minvalue 1 maxvalue 99999999999999999999 start with 120 increment by 1 cache 40 nocycle
noorder;
现在要把SEQ_SERVICE_LINE_ID这个sequence的开始值修改成300,修改方法如下:
alter sequence umdata.SEQ_SERVICE_LINE_ID nocache; select 300-last_number change_num from user_sequences
where sequence_name='SEQ_SERVICE_LINE_ID' and sequence_owner='UMDATA'; alter sequence umdata.SEQ_SERVICE_LINE_ID increment by change_num; select SEQ_SERVICE_LINE_ID.nextval from dual; alter sequence SEQ_SERVICE_LINE_ID increment by 1 cache 40; --cache 后面的40为SEQ_SERVICE_LINE_ID的原来cache选项的值。 declare
LastValue integer; begin loop
select SEQ_SERVICE_LINE_ID.currval into LastValue from dual; exit when LastValue >= 300 - 1; --这里的300为我们希望修改成的开始值 select SEQ_SERVICE_LINE_ID.nextval into LastValue from dual; end loop; end; /
例子2 修改带nocache选项的sequence的start with值
修改start with值时要保证修改后的当前start with值不能与表中的已有值重复。
SEQ_SERVICE_LINE_ID D的当前选项值如下:
minvalue 1 maxvalue 99999999999999999999 start with 100 increment by 1 nocache
nocycle
noorder;
现在要把SEQ_SERVICE_LINE_ID这个sequence的开始值修改成300,修改方法如下:
select 300-last_number change_num from user_sequences
where sequence_name='SEQ_SERVICE_LINE_ID' and sequence_owner='UMDATA'; alter sequence umdata.SEQ_SERVICE_LINE_ID increment by change_num ; select SEQ_SERVICE_LINE_ID.nextval from dual; alter sequence SEQ_SERVICE_LINE_ID increment by 1 nocache; declare
LastValue integer; begin loop
select SEQ_SERVICE_LINE_ID.currval into LastValue from dual; exit when LastValue >= 300 - 1; select SEQ_SERVICE_LINE_ID.nextval into LastValue from dual; end loop; end; /