unique varchar (NNN) con un indice nel database e il relativo overhead

1

Ho visto l'url in questo modo

domain.com/some-article-title-which-can-be-very-long

molte volte. Non c'è alcun ID incorporato in esso. Pertanto, in un db deve essere definito come "unique article_url varchar (NNN)"

Anche se è un bene per il SEO, non ha troppo overhead per un database: c'è un indice su "article_url" ed è molto lungo.

O c'è un trucco per quanto riguarda un db di cui non sono a conoscenza?

    
posta Rakori 03.12.2017 - 12:10
fonte

2 risposte

2

Il tuo URL è una chiave primaria?

Se si desidera utilizzare un URL lungo come ID univoco per una tabella, sarà necessario utilizzare tale ID anche in altre tabelle. I join rischiano di diventare meno efficienti.

Se questo è il caso, suggerirei vivamente di conservare una singola copia dell'URL e aggiungere un ID aggiuntivo (un numero sequenziale o alcuni codice hash dell'URL ).

Nota: anche PostgreSQL da tempo usa un hash join per ottimizzare i join che coinvolgono stringhe di grandi dimensioni, ma questo potrebbe essere inefficiente nel tuo caso. L'ID extra evita completamente questo problema.

Ti preoccupi di determinare l'unicità di un url che non è una chiave primaria?

Qui l'indice univoco è solo la strada da percorrere.

In alternativa, puoi mantenere accanto all'URL una colonna con il codice hash dell'URL: hash_code sono buoni indicatori di unicità. Ma non sono perfetti, e penso che le differenze di prestazioni sarebbero importanti solo se tu avessi url che sono nella gamma dei kilobyte.

Sei preoccupato per lo spazio di archiviazione?

L'URL potrebbe essere enorme in teoria, ma in pratica è limitato a circa 2000 caratteri . Questo dovrebbe in ogni caso adattarsi alle dimensioni varchar consentite da PostgreSQL.

Non dovresti preoccuparti delle dimensioni, poiché la documentazione di PostgreSQL ricorda:

Long strings are compressed by the system automatically, so the physical requirement on disk might be less. Very long values are also stored in background tables so that they do not interfere with rapid access to shorter column values. In any case, the longest possible character string that can be stored is about 1 GB.

    
risposta data 03.12.2017 - 17:25
fonte
1

Hai espresso la preoccupazione che l'indice su quella colonna sia molto lungo, il che significa che è lo spazio occupato dall'indice, che ti preoccupa.

In una situazione simile su un database Oracle, abbiamo sostituito l'indice normale con uno basato sulla funzione, prendendo i primi 20 caratteri del valore della colonna: abbiamo indicizzato SUBSTR20 (COLUMN) invece di COLUMN, con SUBSTR20 come utente- funzione definita.

Questo ha notevolmente aiutato a ridurre la dimensione dell'indice, ma abbiamo dovuto riscrivere tutte le query in

WHERE 
    SUBSTR20(COLUMN) = SUBSTR20('abcdefghijklmnopqrstuvwxyz') 
AND 
    COLUMN = 'abcdefghijklmnopqrstuvwxyz'

per fare in modo che il database utilizzi l'indice (prima parte) e controlli i risultati anche per la corrispondenza dei caratteri rimanenti (seconda parte).

E gestire correttamente i confronti LIKE è diventato una sfida non banale.

Le prestazioni delle query che abbiamo riscontrato erano buone (paragonabili all'indice a colonna intera), poiché la selezione principale è stata effettuata dall'indice di sottostringa.

Quindi, questa soluzione riduce il consumo di spazio, ma arriva al costo di query SQL più complesse.

Naturalmente, il presupposto è che i primi 20 caratteri siano abbastanza significativi da ridurre il risultato impostato a pochi candidati (il che era vero nel nostro caso).

Per generalizzare questo approccio, sei naturalmente libero di fare ciò che vuoi nella funzione di indicizzazione, ad es. calcola qualche valore di hash.

    
risposta data 03.12.2017 - 16:35
fonte