项目是用oralce 10g + tomcat +jsp的
其中,有订单流水号,如年月日+7位流水号。以前做的东西里边因为订单少,就每次都去数据库取一次最后的订单号,再来生成新的订单好。但是现在这个项目里,每天的订单可能10W左右,而且下单时间比较集中。那该去怎么处理这个订单流水号?
还有就是,要对用户的所有操作,主要是查看/购买商品,点击/购买广告产品的记录。做这种操作轨迹记录,该怎么设计表,以及如何做查询优化,现在已有20W用户操作 麻烦路过的大哥大姐帮帮忙,指点下小弟先谢谢了
其中,有订单流水号,如年月日+7位流水号。以前做的东西里边因为订单少,就每次都去数据库取一次最后的订单号,再来生成新的订单好。但是现在这个项目里,每天的订单可能10W左右,而且下单时间比较集中。那该去怎么处理这个订单流水号?
还有就是,要对用户的所有操作,主要是查看/购买商品,点击/购买广告产品的记录。做这种操作轨迹记录,该怎么设计表,以及如何做查询优化,现在已有20W用户操作 麻烦路过的大哥大姐帮帮忙,指点下小弟先谢谢了
每次需要新的流水号时,就用当前的日期去获取当天的流水号再补充0到7位,用了一个就把该表的流水号+1,相当于建立了一个动态的sequence。
第二个 应该是需要前台操作才能统计的吧 估计会要设计表格插入数据统计
20w每天产生100-200w数据很正常啊那就
你最终目的应该是要统计每个商品的 点击量 销售量吧
那就每天统计好 点击量 销售量 然后清掉 数据记录表
个人意见 一起学习
CREATE SEQUENCE order_id_seq INCREMENT BY 1 START WITH 1 MAXVALUE 9999999 CYCLE CACHE 10;SET SERVEROUTPUT ON
DECLARE
order_id VARCHAR(17); -- 订单流水号
BEGIN
SELECT to_char(SYSDATE,'YYYYMMDD')||LPAD( to_char(order_id_seq.nextval),7,'0') INTO order_id FROM dual;
DBMS_OUTPUT.PUT_LINE('当前流水号是:'||order_id);
END;
/---------------- 若订单流水号是数值型的话:(Oracle 10g) -----------------
CREATE SEQUENCE order_id_seq INCREMENT BY 1 START WITH 1 MAXVALUE 9999999 CYCLE CACHE 10;SET SERVEROUTPUT ON
DECLARE
order_id NUMBER(18,0); -- 订单流水号
BEGIN
SELECT to_number(to_char(SYSDATE,'YYYYMMDD')||LPAD( to_char(order_id_seq.nextval),7,'0')) INTO order_id FROM dual;
DBMS_OUTPUT.PUT_LINE('当前流水号是:'||order_id);
END;
/
---------------- 若订单流水号是字符串型的话:(Oracle 11g) -----------------
CREATE SEQUENCE order_id_seq INCREMENT BY 1 START WITH 1 MAXVALUE 9999999 CYCLE CACHE 10;SET SERVEROUTPUT ON
DECLARE
order_id VARCHAR(17); -- 订单流水号
BEGIN
order_id := to_char(SYSDATE,'YYYYMMDD')||LPAD( to_char(order_id_seq.nextval),7,'0');
DBMS_OUTPUT.PUT_LINE('当前流水号是:'||order_id);
END;
/---------------- 若订单流水号是数值型的话:(Oracle 11g) -----------------
CREATE SEQUENCE order_id_seq INCREMENT BY 1 START WITH 1 MAXVALUE 9999999 CYCLE CACHE 10;SET SERVEROUTPUT ON
DECLARE
order_id NUMBER(18,0); -- 订单流水号
BEGIN
order_id := to_number(to_char(SYSDATE,'YYYYMMDD')||LPAD( to_char(order_id_seq.nextval),7,'0'));
DBMS_OUTPUT.PUT_LINE('当前流水号是:'||order_id);
END;
/
每天10W,性能没问题
--创建流水号表
create table T_SERIALNO
(
CURDAT VARCHAR2(10) not null,
SERIALNUM NUMBER(8) not null
);--创建函数
CREATE OR REPLACE FUNCTION GetSerialNo RETURN VARCHAR2 IS
v_DateStr VARCHAR2(10); --系统日期对应的字符串
v_SerialNum NUMBER(7); --流水序号
BEGIN
--取系统日期生成需要的字符串
v_DateStr := TO_CHAR(SYSDATE, ('YYYYMMDD'));
--生成产生流水号的序号
BEGIN
SELECT Decode(CurDat, v_DateStr, (SerialNum + 1), 1)
INTO v_SerialNum
FROM t_SerialNo
FOR UPDATE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
v_SerialNum := 1;
INSERT INTO t_SerialNo (CurDat, SerialNum) VALUES (v_DateStr, v_SerialNum);
END; --修改流水号参数
UPDATE t_SerialNo SET CurDat = v_DateStr, SerialNum = v_SerialNum;
COMMIT;
--得到需要的流水号
RETURN v_DateStr || Lpad(v_SerialNum, 7, '0');
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RETURN NULL;
END;
/
测试结果
SQL> BEGIN
2 FOR i IN 1 .. 10 LOOP
3 dbms_output.put_line(getSerialNo());
4 END LOOP;
5 END;
6 /
201004200000001
201004200000002
201004200000003
201004200000004
201004200000005
201004200000006
201004200000007
201004200000008
201004200000009
201004200000010PL/SQL 过程已成功完成。SQL>
-- 做一个JOB,每天00:00:00的时候,重创建序列,从1开始,就OK了!
iCurID Integer; -- 游标ID
iResult Integer;
begin
iCurID:= Dbms_Sql.Open_Cursor;
Dbms_Sql.Parse(iCurID, AsSql, Dbms_Sql.V7);
iResult:= Dbms_Sql.Execute(iCurID);
Dbms_Sql.Close_Cursor(iCurID);
end;
/create or replace function GetSqlValue(AsSql in varchar2) return Integer is
iCurID Integer; -- 游标ID
iResult Integer;
iReturn Integer;
begin
iCurID:= Dbms_Sql.Open_Cursor;
Dbms_Sql.Parse(iCurID, AsSql, Dbms_Sql.V7);
Dbms_Sql.Define_Column(iCurID, 1, iReturn);
iResult:= Dbms_Sql.Execute(iCurID);
if Dbms_Sql.Fetch_Rows(iCurID) > 0 then
Dbms_Sql.Column_Value(iCurID, 1, iReturn);
else
iReturn:= -1;
end if;
--Dbms_Sql.Close_Cursor(iCurID);
Return iReturn;
exception
when Others then
--Dbms_Output.Put_Line(SqlErrm);
Return -2;
end;
/create or replace procedure GetMaxID(AdRq in Date, AnPlaces in Integer, AsOutOrderID out varchar2) is
sSql Varchar2(4000);
sSeqName Varchar2(30); -- 订单使用的Sequence名字
nPlaces Integer;
nResult Integer;
nOrderID Integer;
begin
AsOutOrderID:= '';
-- 检查
if AdRq is Null then
Return;
end if;
-- 检查流水号位数
if (Nvl(AnPlaces, 0) = 0) or (Nvl(AnPlaces, 0) < 0) then
nPlaces:= 7;
else
nPlaces:= AnPlaces;
end if;
sSeqName:= 'SEQ_ORDER' || To_Char(AdRq, 'YYYYMMDD'); select Count(1)
into nResult
from dual
where Exists (select 1
from all_Sequences
where Sequence_Name = Upper(sSeqName));
if nResult = 0 then
-- 创建Sequence
sSql:= 'create Sequence ' || sSeqName || ' INCREMENT BY 1 START WITH 1 MAXVALUE ' || Rpad(' ', nPlaces + 1, '9') || ' CYCLE CACHE 10 ';
--Dbms_output.put_line(sSql);
CreSeq(sSql);
end if;
-- 执行
sSql:= 'select ' || sSeqName || '.NextVal' || ' from Dual';
--Dbms_output.put_line(sSql);
nOrderID:= GetSqlValue(sSql);
if nOrderID <= 0 then
AsOutOrderID:= '';
else
AsOutOrderID:= To_Char(AdRq, 'YYYYMMDD') || Lpad(To_Char(nOrderID), nPlaces, '0');
end if;
--Dbms_output.Put_Line(Nvl(AsOutOrderID, 'Error'));
exception
when others then
Return;
--Dbms_output.put_line(SqlErrm);
end;
/declare
sOrderID varchar2(200);
begin
GetMaxID(sysdate, 8, sOrderID);
dbms_output.put_line(sOrderID);
end;
/
2010042000000015
PL/SQL procedure successfully completed
declare
sOrderID varchar2(200);
begin
GetMaxID(sysdate, 8, sOrderID);
dbms_output.put_line(sOrderID);
end;
/
2010042000000016
PL/SQL procedure successfully completed
begin
execute immediate
'alter sequence seq_test increment by 1 start with 1 maxvalue 9999999 nocycle';
end;SQL> variable job2 number;
SQL> begin
2 dbms_job.submit(:job2,'thispro2;',sysdate,'sysdate+5/1440');
3 end;
4 /
SQL> begin
2 dbms_job.run(:job2);
3 end;
4 /
begin
*
第 1 行出现错误:
ORA-12011: 无法执行 1 作业
ORA-06512: 在 "SYS.DBMS_IJOB", line 406
ORA-06512: 在 "SYS.DBMS_JOB", line 272
ORA-06512: 在 line 2
设置了每5分钟修改一次序列的值,但是执行job的时候就出这个问题
-- 序列只能删除,然后重建,不能用“alter”关键字修改!
-- Step 1:给scott用户授权
grant create sequence to scott;
grant drop any sequence to scott;-- Step 2:切换到scott用户
conn scott/bee56915-- Step 3:创建创建序列、创建删除序列的存储过程
CREATE SEQUENCE order_id_seq INCREMENT BY 1 START WITH 1 MAXVALUE 9999999 NOCYCLE CACHE 10;create or replace procedure del_order_id_seq_proc
IS
sqlstr1 VARCHAR2(100);
sqlstr2 VARCHAR2(100);
BEGIN
sqlstr1 := 'DROP SEQUENCE order_id_seq';
sqlstr2 := 'CREATE SEQUENCE order_id_seq INCREMENT BY 1 START WITH 1 MAXVALUE 9999999 NOCYCLE CACHE 10';
execute immediate sqlstr1;
execute immediate sqlstr2;
END;
/exec del_order_id_seq_proc;
select order_id_seq.nextval from dual;-- Step 4:定义作业名变量
variable job_drop_seq1 number;-- Step 5:每隔1分钟调用作业(这个时间,你可以自己设置)
begin
dbms_job.submit(:job_drop_seq1,'del_order_id_seq_proc;',sysdate,'sysdate+1/1440');
end;
/-- Step 5:例如:每天00:00:00调用作业
begin
dbms_job.submit(:job_drop_seq1,'del_order_id_seq_proc;',sysdate,'trunc(sysdate+1)');
end;
/
-- Step 5:查看下一个作业的执行时间(最下面的一个时间点2010-04-21 00:00:00 表示下一次的执行时间)
column next_time for a20;
select to_char(next_date,'YYYY-MM-DD HH24:MI:SS') as next_time from user_jobs;