2010-02-15 75 views
2

我试图查看是否存在某些东西来创建一个具有分区逻辑的序列。 我需要依赖于其他主键的前一个序列号:Oracle分区序列

id_person sequence id 
     1 | 1 
     1 | 2 
     2 | 1 
     3 | 1 
     1 | 3 

这样的顺序必须依靠id_person分区。在oracle上是否有这样的东西,或者我必须在应用程序级别自己实现它?

谢谢。


嗨具有建立这个PLSQL包一个函数和过程:

PROCEDURE INIT_SEQUENCE(NAME varchar2, pkColumnNameList PARTITIONED_SEQUENCE_PK_COLUMN); 
FUNCTION GET_NEXT_SEQUENCE_VALUE(NAME varchar2, pkPartitionColValue PARTITIONED_SEQUENCE_COL_VALUE) RETURN NUMBER; 

INIT_SEQUENCE - 获得输入的序列关联的名称和列名的列表,被固定的主键的一部分该序列例如:'ID_PERSON'

该过程的工作是创建将根据pkColumnNameList列管理序列增量的表。

GET_NEXT_SEQUENCE_VALUE-获得序列的名称来增加和pkColumnNameList主键的值和使下一个步骤: 1)动态地创建SQL工作 2)dbms_lock.allocate_unique();锁定表格 3)检查表格中是否存在表格中的记录,用于输入 中的pk值4)如果存在记录更新记录在序列列中具有max + 1 5)如果不存在记录插入在序列栏中输入1的新记录 6)返回新的ID;

我想收到有关此先谢谢了评论...

+0

你能详细说明什么是序列号列吗? – FerranB 2010-02-15 15:59:39

+1

有多少人的身份证你会有1-10或100,000的......有没有差距?如果只有少数人ID会制作n个序列 - 也就是说,如果允许有空位。不关注并发问题的人们,显然这不是一个严肃的应用程序,有数百个并发连接插入到这个表中。是吗? – 2010-02-15 16:53:04

+1

那里有点讽刺,但总的来说我很认真。人们在询问您期望插入多少插件之前就会开始关注并发性。如果您每小时有10个插页,wtf会关心吗? – 2010-02-15 23:37:30

回答

0

恐怕你必须做这样的:

INSERT INTO t 
(
    id_person, 
    sequence_id 
) 
VALUES 
( 
    <your_person_id>, 
    (SELECT 1 + NVL(MAX(sequence_id), 0) 
    FROM t 
    WHERE t.id_person = <your_person_id> 
) 
) 
+0

感谢这个想法,我试图实现一个包pl-sql来制作这种序列 – Macdeveloper 2010-02-15 12:11:16

+1

您需要处理2个用户同时尝试插入的情况 - 一个会因PK违反。 – 2010-02-15 13:03:56

+0

为什么不只是使用正常的序列,而不是依赖于人?如果需要,您仍然可以向客户端应用程序呈现依赖于人员的订单号。 – 2010-02-15 14:00:26

4

是实际需求的二次序列没有空隙?如果是这样,你就有一个巨大的序列化/可伸缩性问题。

如果您需要为人类消费呈现无间隙序列,那么您可以使用实际的序列(或时间戳)作为Nick Pierpont建议并保留可扩展性,您可以使用分析函数。

数据集(T1):

ID_PERSON SEQUENCE_ID 
---------- ----------- 
     1   1 
     2   2 
     3   3 
     1   4 
     1   5 
     1   6 
     2   7 
     3   8 
     1   9 

SQL:

select * 
    from 
    (select id_person, 
      sequence_id as orig_sequence_id,   
      rank() 
      over (partition by id_person 
        order by sequence_id) 
      as new_sequence_id 
    from t1 
) 
order by id_person, new_sequence_id; 

结果:

ID_PERSON ORIG_SEQUENCE_ID NEW_SEQUENCE_ID 
---------- ---------------- --------------- 
     1    1    1 
     1    4    2 
     1    5    3 
     1    6    4 
     1    9    5 
     2    2    1 
     2    7    2 
     3    3    1 
     3    8    2 
+0

+1,很好的解决方案。避免存储二级序列及其伴随的维护/性能问题。 – DCookie 2010-02-15 18:54:49

+1

巨人? GIANT系列化问题......每天插入10条记录?这个数字从哪里来?我做了它,就像你必须确定是否有真正的并发问题一样。他可能会也可能不会有并发问题。 – 2010-02-15 23:36:38

+1

@Stephanie Page:介绍序列化的设计不会扩展。无论是玩具应用还是最终,序列化都会咬住使用“select max(column)+ 1”“pattern”的设计。远不容易引入序列化。 – 2010-02-16 04:00:43

0

你要找的是不是一个sequence,如Oracle文档要求: “序列发生器提供了一系列连续的数字”

您正在寻找一个计算字段取决于另一个,在这种情况下,主键。正如其他建议你需要在你的代码中添加逻辑。这意味着在procedureinsert句子。

+0

我已经创建了一个管理这种od序列的olsql包,并使用dbms_lock来执行对concurncy的控制。每一种序列都有一个表cor计算。在这一天晚些时候,我会在这篇文章中发布代码,我想'共享这个想法,看看它是否设计得很好 – Macdeveloper 2010-02-16 07:25:48