Sfondo per evitare il problema XY: sto costruendo un sistema di migrazione del database che deve risolvere i vincoli delle chiavi esterne (vedi qui per lo sfondo completo). Ho bisogno di determinare quale ordine posso eseguire creare tabelle / modificare le operazioni della tabella in modo da non violare alcun vincolo di chiave esterna. Un ordinamento topologico è un punto di partenza naturale, tranne per il fatto che un database può avere vincoli circolari che un tipico algoritmo di ordinamento topologico non può gestire.
Ci sono già alcune domande in questo senso, e il suggerimento più comune che vedo qui è semplicemente rimuovere i vincoli di chiave esterna e aggiungerli separatamente in seguito. Questa non è la soluzione che sto cercando, perché così facendo si ottengono il doppio delle operazioni di modifica delle tabelle, che è particolarmente importante evitare per tabelle di grandi dimensioni. Per quanto possibile vorrei ridurre al minimo il numero totale di comandi CREATE / ALTER necessari per migrare il database, il che richiede di essere intelligente su di esso.
Ovviamente, nel caso di vincoli di chiave esterna circolare, l'unica opzione è aggiungere le chiavi esterne separatamente. Di conseguenza, l'approccio generale che sto cercando è un approccio in due parti: identificare i vincoli circolari e "interromperli" contrassegnando i vincoli di chiave esterna da aggiungere successivamente, eseguire un ordinamento topologico standard sulle restanti operazioni, aggiornare il database in ordine topologico e infine applicare eventuali vincoli in sospeso che sono stati riservati per dopo. Ho trovato molti esempi di algoritmi di ordinamento topologico e riferimenti ad algoritmi che possono aiutare a identificare i bordi da "spezzare" per abilitare un algoritmo di ordinamento topologico standard, ma senza algoritmi effettivi per quest'ultimo.
Qualsiasi direzione sarebbe apprezzata, sia per il mio problema specifico che per il problema generale.
1 mese dopo: aggiornamento
Alcune settimane in, e ho imparato che ho davvero bisogno di risolvere questo problema. Sono andato con il suggerimento generale di migrare con la chiave esterna, in particolare dato suggerimenti che migliorerà le prestazioni generali. Lo stiamo utilizzando internamente da alcune settimane.
Sfortunatamente , non è una soluzione a prova di proiettile. Si scopre che ci sono casi limite in cui MySQL genera un errore 1215 anche con la verifica di chiavi esterne. Ho sempre avuto un piano da aggiungere in un linter MySQL sulle definizioni della tabella, e questo eviterà il verificarsi di questo caso limite. Esse si verificano principalmente a seguito della modifica della struttura per correggere gli elementi causati dagli sviluppatori che non sono stati abbastanza attenti durante la creazione iniziale delle tabelle. Indipendentemente da ciò, ora so che ci sono casi in cui l'ordine conta anche quando i controlli delle transazioni sono disattivati. Mentre stiamo implementando delle soluzioni istituzionali da parte nostra per evitare questi casi, voglio che questo sia uno strumento per tutti gli altri. Altri possono imbattersi in questi stessi casi limite, il che significa che ho bisogno di implementare un corretto ordinamento topologico, e non posso farlo senza identificare e interrompere i cicli. Per essere chiari, in questo caso i cicli di interruzione significano semplicemente contrassegnare i vincoli di chiave esterna da aggiungere dopo ogni altra cosa. Non deve essere intelligente. È sufficiente identificare quando l'aggiunta di un'operazione add foreign key
al piano di migrazione comporterà un ciclo e rimandare l'operazione di aggiunta fino a dopo tutto il resto.