Вопрос, конечно, зачем вам случайный идентификатор?
Один случай, когда я столкнулся с аналогичным требованием, касался идентификаторов клиентов веб-приложения: клиент идентифицирует себя с помощью своего идентификатора клиента (хранящегося в cookie-файле), поэтому приходится грубо пытаться угадать идентификатор другого клиента (поскольку это позволило бы похитить его данные).
Решение, с которым я пошел, состояло в том, чтобы объединить последовательный int32 со случайным int32, чтобы получить int64, который я использовал в качестве идентификатора клиента. В PostgreSQL:
CREATE FUNCTION lift(integer, integer) returns bigint AS $$
SELECT ($1::bigint << 31) + $2
$$ LANGUAGE SQL;
CREATE FUNCTION random_pos_int() RETURNS integer AS $$
select floor((lift(1,0) - 1)*random())::integer
$$ LANGUAGE sql;
ALTER TABLE client ALTER COLUMN id SET DEFAULT
lift((nextval('client_id_seq'::regclass))::integer, random_pos_int());
Сгенерированные идентификаторы являются «наполовину» случайными, в то время как другая «половина» гарантирует, что вы не можете получить один и тот же идентификатор дважды:
select lift(1, random_pos_int()); => 3108167398
select lift(2, random_pos_int()); => 4673906795
select lift(3, random_pos_int()); => 7414644984
...