Hur långa är dina strängar?
Om de är relativt korta (t.ex. engelska ord; avg_len=5) och du har databaslagring över, prova detta tillvägagångssätt:
- För varje ord som du vill lagra i tabellen, ta istället alla möjliga suffix av det ordet. Du fortsätter med andra ord att ta bort den första karaktären tills ingenting finns kvar. Till exempel ordet
value
ger:value
alue
lue
ue
e
- Lagra varje av dessa suffix i databasen.
- Du kan nu söka efter delsträngar med
LIKE 'alu%'
(som kommer att hitta 'alu' som en del av 'värde').
Genom att lagra alla suffix har du tagit bort behovet av det ledande jokertecken (som gör att ett index kan användas för snabb uppslagning), på bekostnad av lagringsutrymme.
Lagringskostnad
Antalet tecken som krävs för att lagra ett ord blir word_len*word_len / 2
, d.v.s. kvadratisk i ordlängden, per ord. Här är ökningsfaktorn för olika ordstorlekar:
- 3-bokstavsord:
(3*3/2) / 3 = 1.5
- 5-bokstavsord:
(5*5/2) / 5 = 2.5
- 7-bokstavsord:
(7*7/2) / 7 = 3.5
- 12-bokstavsord:
(12*12/2) / 12 = 6
Antalet rader som krävs för att lagra ett ord ökar från 1 till word_len
. Var uppmärksam på detta overhead. Ytterligare kolumner bör hållas till ett minimum för att undvika lagring av stora mängder redundant data. Till exempel bör ett sidnummer som ordet ursprungligen hittades på vara bra (tänk osignerad smallint), men omfattande metadata om ordet bör lagras i en separat tabell per ord, snarare än för varje suffix.
Överväganden
Det finns en avvägning där vi delar "ord" (eller fragment). Som ett verkligt exempel:vad gör vi med bindestreck? Lagrar vi adjektivet five-letter
som ett eller två ord?
Avvägningen är som följer:
- Allt som är uppdelat kan inte hittas som ett enda element. Om vi lagrar
five
ochletter
separat, söker efterfive-letter
ellerfiveletter
kommer att misslyckas. - Allt som inte är delas upp kommer att ta mer lagringsutrymme. Kom ihåg att lagringskravet ökar kvadratiskt i ordlängden.
För enkelhetens skull kanske du vill ta bort bindestrecket och lagra fiveletter
. Ordet kan nu hittas genom att söka på five
, letter
och fiveletter
. (Om du också tar bort bindestreck från en sökfråga kan användare fortfarande hitta fiveletter
.)
Slutligen finns det sätt att lagra suffixarrayer som inte medför mycket overhead, men jag är ännu inte säker på om de översätts bra till databaser.