日期:2014-05-17  浏览次数:20881 次

遇到了两个问题,路过的帮下忙,谢谢
项目是用oralce 10g + tomcat +jsp的
  其中,有订单流水号,如年月日+7位流水号。以前做的东西里边因为订单少,就每次都去数据库取一次最后的订单号,再来生成新的订单好。但是现在这个项目里,每天的订单可能10W左右,而且下单时间比较集中。那该去怎么处理这个订单流水号?
  还有就是,要对用户的所有操作,主要是查看/购买商品,点击/购买广告产品的记录。做这种操作轨迹记录,该怎么设计表,以及如何做查询优化,现在已有20W用户操作。。。

  麻烦路过的大哥大姐帮帮忙,指点下。。。小弟先谢谢了

------解决方案--------------------
增加一个每日流水号的表,字段两个,一个是日期,一个是流水号(数值),先插入两年的记录,流水号都初始化为1。
每次需要新的流水号时,就用当前的日期去获取当天的流水号再补充0到7位,用了一个就把该表的流水号+1,相当于建立了一个动态的sequence。

------解决方案--------------------
用SEQUENCE吧 把SEQUENCE常驻在cache中 就不会丢失
第二个 应该是需要前台操作才能统计的吧 估计会要设计表格插入数据统计
20w每天产生100-200w数据很正常啊那就
你最终目的应该是要统计每个商品的 点击量 销售量吧
那就每天统计好 点击量 销售量 然后清掉 数据记录表
个人意见 一起学习
------解决方案--------------------
SQL code
---------------- 若订单流水号是字符串型的话:(Oracle 10g)  -----------------
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;
/

------解决方案--------------------
使用for update强制串行,每天从1开始,生成唯一流水号
每天10W,性能没问题
SQL code
--创建流水号表
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 code
Set Serveroutput on

create or replace procedure CreSeq(AsSql in varchar2) is
  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,