Modo efficiente per gestire le chiavi esterne

1

Sto costruendo uno script che controlla una vasta rete di siti per collegamenti non validi. L'idea è di contrassegnare i collegamenti che mostrano continuamente come non disponibili in modo che possano essere puliti dal team amministrativo.

Il processo di base è questo:

  • Prendi un set di pagine - circa 30K al giorno, non lo stesso 30K ogni giorno - ed estrai tutti i link dalle pagine
  • Inserisci URL univoci nella tabella dei collegamenti
  • Inserisci i record in LinksInPage contenenti il testo di ancoraggio per ciascun collegamento e il linkID associato per ciascun link
  • Verifica lo stato di ciascun collegamento utilizzando i metodi HEAD / GET e inserendo i risultati nella tabella LinkResults

Attualmente sto pianificando di costruire questa struttura di database in un database relazionale.

Tavoli:

  • Link

    • LinkID (auto inc)
    • URL (varchar)
  • LinksInPage

    • LinkID (chiave esterna a Links.LinkID)
    • AnchorText (varchar)
    • URL della pagina (varchar)
  • LinkResults

    • LinkID (chiave esterna a Links.LinkID)
    • DateOfCheck (data)
    • StatusCode (int)
    • NumFailures (int)

La mia domanda:

  • Come posso gestire in modo efficiente collegamenti non univoci in questa situazione (sono aperto a cambiare completamente il modo in cui il database è disposto)?

Ad esempio, il primo giorno se controllo example.com , inserisco un record nella tabella Links. Il secondo giorno, se ho un'altra pagina che collega anche example.com , non voglio una voce duplicata nella tabella Collegamenti, ma ho bisogno di un record in LinksInPage che punti allo stesso LinkID. A, supponendo almeno un link per pagina, collegamenti 30K giornalieri, non penso che la ricerca di un LinkID per ciascun inserto sia efficiente. Memorizzare tutto in memoria sembra anche portare a un problema in futuro con l'aumentare del numero di link.

Devo anche essere in grado di gestire il LinkID quando si inseriscono i risultati del collegamento. Ancora una volta, la ricerca del LinkID su ogni inserto sembra inefficiente.

Il piano è di costruire questo utilizzando Python.

    
posta NewGuy 21.06.2015 - 06:40
fonte

2 risposte

2

looking up the LinkID at each insert seems inefficient

Non l'hai mai provato, suppongo? Sembra un tipico caso di ottimizzazione prematura. L'utilizzo dell'indicizzazione corretta, in particolare per gli URL, dovrebbe rendere una query per un URL più o meno veloce di un INSERT nella stessa tabella (forse l'INSERT diventerà un po 'più lento dal momento che l'indice deve essere aggiornato). E quando ho capito bene, avrai bisogno di una query SELECT per INSERT. Quindi la velocità dipenderà principalmente dal tipo di database selezionato, dalla latenza di rete tra l'applicazione e il database e se si creano gli indici corretti. Il tempo di esecuzione non crescerà di un ordine di grandezza solo perché devi fare una ricerca di elementi esistenti prima di fare un INSERT.

Quindi il mio consiglio è: implementare e misurare. Se effettivamente hai un collo di bottiglia, potresti cercare ulteriori miglioramenti, come l'utilizzo di stored procedure, la messa a punto del codice o del database.

    
risposta data 21.06.2015 - 09:04
fonte
0

Poiché Doc Brown dice che unire correttamente le tabelle indicizzate è efficiente

Semplifica l'applicazione definendo le viste appropriate e gestendo le viste anziché le tabelle sottostanti

es. (Testato su SQL-SERVER, non hai specificato un RDBMS) Vedi Fiddle

CREATE VIEW URLsInPage AS
    SELECT Links.[Name], LinksInPage.[Page URL], LinksInPage.[AnchorText] 
    FROM Links
    JOIN LinksInPage ON Links.[LinkId] = LinksInPage.[LinkId]
GO

CREATE TRIGGER AddLinksInPage ON URLsInPage INSTEAD OF INSERT
AS
DECLARE @Temp INT

MERGE INTO Links USING Inserted AS New ON Links.[Name] = New.[Name]
WHEN MATCHED THEN 
    UPDATE SET @Temp = 1
WHEN NOT MATCHED THEN
    INSERT ([Name]) VALUES (New.[Name])
OUTPUT inserted.[LinkId], New.[AnchorText] , New.[Page URL] INTO LinksInPage ([LinkId], [AnchorText] , [Page URL]);
    
risposta data 21.07.2015 - 12:05
fonte

Leggi altre domande sui tag