Question

I'm trying to generate a sorted GUID as a primary key in Oracle. In SQL Server I could use one of the following to sort the rows physically

  1. By clustered primary key as a unique identifier.
  2. By NEWSEQUENTIALID.

I have searched for an Oracle equivalent but failed to find a solution. I know about Is there a way to create an auto-incrementing Guid Primary Key in an Oracle database?, but there's no indication whether SYS_GUID() is sorted.

How could I create a sequential primary key in Oracle?

Was it helpful?

Solution

If you want to create a GUID then SYS_GUID() is what you should be using, you can create this in a table as per the linked question. It's unclear from the documentation whether SYS_GUID() is incrementing. It might be but that's not really a statement that imparts trust.

The next part of your question (and some comments) keeps asking about clustered primary keys. This concept does not exist in the same way in Oracle as it does in SQL Server and Sybase. Oracle does have indexed organized tables (IOT) ...

... a table stored in a variation of a B-tree index structure... rows are stored in an index defined on the primary key for the table. Each index entry in the B-tree also stores the non-key column values. Thus, the index is the data, and the data is the index.

There are plenty of uses for IOTs but it's worth bearing in mind you're altering the physical structure of the database on the disk for "performance reasons". You're doing the ultimate of all premature optimizations using something that has both negative and positive aspects. Read the documentation and be sure that this is what you want to do.

I would generally use an IOT only when you don't care about DML performance but when you do a lot of range scans, or you need to order by the primary key. You create an IOT in the same way as you would an ordinary table, but because everything you want is now part of the table everything goes in your table definition:

create table test_table (
   id raw(32) default sys_guid()
 , a_col varchar2(50)
 , constraint pk_my_iot primary key (id)
   ) organization index;

It's worth noting that even with an IOT you must use an explicit ORDER BY in order to guarantee returned order. However, because of the way this is stored Oracle can table a few short cuts:

select *
  from ( select * 
           from test_table 
           order by id )
 where rownum < 2

SQL Fiddle.

As with everything, test, don't assume that this is the structure you want.

OTHER TIPS

Oracle has as SYS_GUID() function, which generates a 16-byte RAW datatype. But, I'm not sure what you mean by "sorted GUID". Can you elaborate?

Do you mean you need each generated GUID to sort "after" the previously generated GUID? I looked at the SYS_GUID() function, and it seems to generate GUIDs in sorted order, but looking at the documentation, I don't see anything that says that is guaranteed.

If I understand your question correctly, I'm not sure it's possible.

You may be able to use SYS_GUID() and prepend a sequence, to get your desired sort order?

Can you explain more about your use case?

Adding the following in response to comment:

Ok, now I think I understand. What I think you want, is something called an IOT, or Index Organized Table, in Oracle. It's a table that has an index strucure, and all data is clustered, or grouped by the primary key. More information is available here: http://docs.oracle.com/cd/E16655_01/server.121/e17633/indexiot.htm#CNCPT721

I think that should do what you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top