Come mantenere un invariante ricorsiva in un database MySQL?

voti
1

Ho un albero codificato in un database MySQL come bordi:

CREATE TABLE items (
    num INT,
    tot INT,
    PRIMARY KEY (num)
    );
CREATE TABLE tree (
    orig INT,
    term INT
    FOREIGN KEY (orig,term) REFERENCES items (num,num)
    )

Per ogni foglia nella struttura, items.totè fissato da qualcuno. Per i nodi interni, items.totdeve essere la somma di esso per bambini. L'esecuzione del seguente query più volte avrebbe generato il risultato desiderato.

UPDATE items SET tot = (
    SELECT SUM(b.tot) FROM
        tree JOIN items AS b
        ON tree.term = b.num 
        WHERE tree.orig=items.num)
    WHERE EXISTS 
        (SELECT * FROM tree WHERE orig=items.num)

(Notare che questo in realtà non funziona, ma non è questo il punto)

Si supponga che il database esiste e l'invariante sono già soddisfatti.

La domanda è:

Qual è il modo più pratico per aggiornare il DB, pur mantenendo questo requisito? Gli aggiornamenti possono spostare i nodi intorno o modificare il valore di totsu nodi foglia. Si può presumere che i nodi foglia rimarranno come nodi foglia, i nodi interni rimarranno come nodi interni e il tutto rimarrà come un albero corretta.

Alcuni pensieri che ho avuto:

  • Invalidazione completa, dopo ogni aggiornamento, ricalcolare tutto (Um ... No)
  • Impostare un trigger sulla tabella degli elementi di aggiornare il genitore di qualsiasi riga che viene aggiornato
    • Questo sarebbe ricorsiva (aggiornamenti attivare gli aggiornamenti, aggiornamenti di trigger, ...)
    • Non funziona, MySQL non può aggiornare la tabella che ha dato il via il grilletto
  • Impostare un trigger per programmare un aggiornamento del genitore di qualsiasi riga che viene aggiornato
    • Questo sarebbe iterativo (ottenere un elemento da programma, elaborarla orari più articoli)
    • Ciò che prende il via questo? Trust Codice cliente per farlo bene?
    • Un vantaggio è che se gli aggiornamenti sono ordinate correttamente un minor numero di somme devono essere computer. Ma che l'ordinazione è una complicazione e di essa la propria.

Una soluzione ideale sarebbe generalizzare ad altri invarianti aggregazione

FWIW so che questo è un po 'in mare, ma sto facendo questo per divertimento (Fun:. Verb, Trovare l'impossibile per farlo :-)

È pubblicato 21/08/2008 alle 15:20
fonte dall'utente
In altre lingue...                            


2 risposte

voti
1

Non sono sicuro di aver capito correttamente la tua domanda, ma questo potrebbe funzionare mio prendere su alberi in SQL .

Collegato posta metodo descritto di immagazzinare albero nel database - PostgreSQL in questo caso - ma il metodo è abbastanza chiara, in modo che possono essere adottati facilmente per qualsiasi database.

Con questo metodo si può facilmente aggiornare tutti i nodi dipendono modificato nodo K con circa N semplici seleziona query dove N è distanza K dal nodo radice.

Spero che il vostro albero non è veramente profondo :).

In bocca al lupo!

Risposto il 21/08/2008 a 20:36
fonte dall'utente

voti
1

Il problema riscontrato è chiara, la ricorsione in SQL. È necessario ottenere il genitore del genitore ... della foglia e gli aggiornamenti è totale (sia sottraendo il vecchio e aggiungendo il nuovo, o il ricalcolo). Avete bisogno di una qualche forma di identificazione per vedere la struttura dell'albero, e afferrare tutti una nodi bambini e un elenco dei genitori / percorso di una foglia di aggiornare.

Questo metodo aggiunge spazio costante (2 colonne al vostro tavolo --ma è necessario un solo tavolo, altrimenti si può fare un join più tardi). Ho suonato in giro con una struttura poco fa che ha utilizzato un formato gerarchico utilizzando 'sinistra' e le colonne 'giuste' (ovviamente non quei nomi), calcolato da un attraversamento di pre-ordine e un attraversamento post-ordine, rispettivamente, preoccupazione --Non questi non hanno bisogno di essere ricalcolati ogni volta.

Ti farò dare un'occhiata a una pagina con questo metodo in mysql invece di continuare questa discussione in caso non vi piace questo metodo come una risposta. Ma se ti piace, posta / modifica e mi prendo un po 'di tempo e chiarire.

Risposto il 22/08/2008 a 01:14
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more