sql >> Databáze >  >> RDS >> PostgreSQL

Jak vytvořit rozdělenou sekvenci PostgreSQL?

Nevěřím, že existuje jednoduchý způsob, který by byl stejně snadný jako běžné sekvence, protože:

  1. Sekvence ukládá pouze jeden číselný proud (další hodnotu atd.). Chcete jeden pro každý oddíl.
  2. Sekvence mají speciální zpracování, které obchází aktuální transakci (aby se předešlo sporu). Je těžké to replikovat na úrovni SQL nebo PL/pgSQL bez použití triků jako dblink.
  3. Vlastnost sloupce DEFAULT může používat jednoduchý výraz nebo volání funkce jako nextval('myseq'); ale nemůže odkazovat na jiné sloupce, aby informoval funkci, ze kterého proudu by měla hodnota pocházet.

Můžete vyrobit něco, co funguje, ale pravděpodobně to nebudete myslet jednoduše. Postupné řešení výše uvedených problémů:

  1. Použijte tabulku k uložení další hodnoty pro všechny oddíly se schématem jako multiseq (partition_id, next_val) .
  2. Napište multinextval(seq_table, partition_id) funkce, která dělá něco jako následující:

    1. Vytvořte novou transakci nezávislou na aktuální transakci (jeden způsob, jak toho dosáhnout, je prostřednictvím dblink; domnívám se, že některé jiné serverové jazyky to dokážou snadněji).
    2. Zamkněte tabulku uvedenou v seq_table .
    3. Aktualizujte řádek, kde je ID oddílu partition_id , se zvýšenou hodnotou. (Nebo vložte nový řádek s hodnotou 2, pokud žádný neexistuje.)
    4. Potvrdit transakci a vrátit předchozí uložené ID (nebo 1).
  3. Vytvořte spouštěč vložení v tabulce projektů, který používá volání multinextval('projects_table', NEW.Project_ID) pro vložení.

Sám jsem nepoužil celý tento plán, ale zkoušel jsem něco podobného pro každý krok jednotlivě. Příklady multinextval Pokud se o to chcete pokusit...

, může být poskytnuta funkce a spoušť


  1. Jak vložit řetězec, který obsahuje &

  2. PostgreSQL:role nemá oprávnění se přihlásit

  3. Jak zjistím, kdy je vyplnění fulltextového indexu SQL dokončeno?

  4. Zpracování souběžného požadavku při setrvání v databázi Oracle?