No PostgreSQL, as sequências são projetadas para ter lacunas pelos motivos mencionados neste post https://stackoverflow.com/questions/9984196/postgresql-gapless-sequences . Minha pergunta é: as sequências não poderiam ser feitas quase sem intervalos verificando periodicamente (digamos uma vez por dia) quais números de sequência não são usados e adicionando-os de volta à sequência a ser usada?
Suponho que atualmente o postgres implementa uma sequência como um contador que incrementa toda vez que é acessado. Em vez disso, pode ser implementado com uma lista de valores livres e um contador. A sequência funcionaria da seguinte forma:
# python style pseudo code
class Sequence:
def __init__(self):
self.free_numbers_set = []
self.counter = 0
def get_next_sequence_value(self):
if not isempty(self.free_numbers_set):
id = self.free_numbers_set.pop(0)
else:
id = self.counter
id ++
return id
def add_free_numbers(self, column):
for i in range(0:self.counter):
if not i in column:
free_numbers_set.append(i)
free_numbers_set.sort()
Toda vez que precisamos de um novo id, executamos get_next_sequence_value()
e periodicamente executamosadd_free_numbers(column)
Atualizações que abordam algumas das perguntas
- Para colunas de identidade, obter os valores atualmente usados seria trivial. Em outros casos caberia ao usuário fornecer uma lista de valores que já estão em uso.
- A interação com o MVCC precisaria ser pensada. Pode-se implementá-lo de forma que, durante a atualização dos valores ausentes, a sequência seja padronizada para apenas incrementar o contador - isso evitaria conflitos.
Acredito que esta solução poderia fornecer sequências menos esparsas que permitiriam aos usuários usar tipos de id menores (int vs bigint) sendo compatível com versões anteriores com a implementação atual.
O problema é que é impossível determinar como e onde a sequência é usada. Não precisa ser a
DEFAULT
cláusula de uma coluna que possui a sequência:nextval
pode ser chamada em qualquer lugar e usada de maneira criativa, mesmo fora do banco de dados.Mesmo se você considerar apenas o caso de uma coluna de identidade, verificar a tabela em busca de "valores ausentes" seria bastante caro e não está claro como isso deve interagir com o MVCC.
Finalmente, a maioria das solicitações de sequências sem intervalos que vejo estão solicitando valores monotonicamente crescentes, o que essa solução não forneceria.