sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur skapar man en PostgreSQL-partitionerad sekvens?

Jag tror inte att det finns ett enkelt sätt som är lika enkelt som vanliga sekvenser, eftersom:

  1. En sekvens lagrar endast en nummerström (nästa värde, etc.). Du vill ha en för varje partition.
  2. Sekvenser har speciell hantering som kringgår den aktuella transaktionen (för att undvika tävlingstillståndet). Det är svårt att replikera detta på SQL- eller PL/pgSQL-nivå utan att använda knep som dblink.
  3. DEFAULT kolumnegenskapen kan använda ett enkelt uttryck eller ett funktionsanrop som nextval('myseq'); men den kan inte referera till andra kolumner för att informera funktionen från vilken ström värdet ska komma.

Du kan göra något som fungerar, men du kommer förmodligen inte att tycka att det är enkelt. Åtgärda ovanstående problem i sin tur:

  1. Använd en tabell för att lagra nästa värde för alla partitioner, med ett schema som multiseq (partition_id, next_val) .
  2. Skriv en multinextval(seq_table, partition_id) funktion som gör något i stil med följande:

    1. Skapa en ny transaktion oberoende av den aktuella transaktionen (ett sätt att göra detta är genom dblink; jag tror att vissa andra serverspråk kan göra det lättare).
    2. Lås tabellen som nämns i seq_table .
    3. Uppdatera raden där partitions-id är partition_id , med ett ökat värde. (Eller infoga en ny rad med värde 2 om det inte finns någon befintlig.)
    4. Beslut den transaktionen och returnera det tidigare lagrade ID:t (eller 1).
  3. Skapa en infogningstrigger i din projekttabell som använder ett anrop till multinextval('projects_table', NEW.Project_ID) för infogningar.

Jag har inte använt hela denna plan själv, men jag har provat något liknande för varje steg individuellt. Exempel på multinextval funktion och utlösaren kan tillhandahållas om du vill försöka detta...




  1. Hur kan jag dra en lista med ID:n från en SQL-tabell som en kommaseparerad värdesträng?

  2. SQL Server Internals:Plan Caching Pt. I – Återanvändning av planer

  3. TIMESTAMPADD() Exempel – MySQL

  4. Fråga efter antalet distinkta värden i ett rullande datumintervall