Domanda

Recentemente ho lavorato su alcune funzionalità di ricerca del database e volevo ottenere alcune informazioni come le parole medi per documento (ad esempio campo di testo nel database). L'unica cosa che ho trovato finora (senza elaborazione nella lingua scelta al di fuori del DB) è:

SELECT AVG(LENGTH(content) - LENGTH(REPLACE(content, ' ', '')) + 1)
FROM documents

Questo sembra funzionare * ma non avete altri suggerimenti? Attualmente sto usando MySQL 4 (la speranza di passare alla versione 5 per questa applicazione a breve), ma sono interessati a soluzioni generali anche.

Grazie!

* Posso immaginare che questo è un modo piuttosto ruvido per determinare questo in quanto non tiene conto HTML nel contenuto e simili pure. Va bene per questo particolare progetto, ma ancora una volta ci sono modi migliori?

Aggiornamento: Per definire ciò che intendo per "migliore": o più accurato, si esibisce in modo più efficiente, o è più "corretto" (di facile manutenzione, buone prassi, ecc). Per il contenuto che ho a disposizione, l'interrogazione di cui sopra è abbastanza veloce ed è accurata per questo progetto, ma potrebbe essere necessario qualcosa di simile in futuro (così ho chiesto).

È stato utile?

Soluzione

Le funzionalità di gestione del testo di MySQL non sono abbastanza buoni per quello che vuoi. Una funzione memorizzata è un'opzione, ma sarà probabilmente lento. La cosa migliore per elaborare i dati all'interno di MySQL è quello di aggiungere un utente definito funzione . Se avete intenzione di costruire una nuova versione di MySQL in ogni caso, si potrebbe anche aggiungere un funzione nativa .

Il modo "corretto" è quello di elaborare i dati al di fuori del DB dal DB sono per l'archiviazione, non è l'elaborazione, e qualsiasi elaborazione pesante potrebbe mettere troppo di un carico sulle DBMS. Inoltre, calcolando il conteggio delle parole al di fuori di MySQL rende più facile cambiare la definizione di ciò che conta come una parola. Come su come conservare il conteggio delle parole nel DB e l'aggiornamento quando un documento viene modificato?

Esempio funzione memorizzata:

DELIMITER $$
CREATE FUNCTION wordcount(str LONGTEXT)
       RETURNS INT
       DETERMINISTIC
       SQL SECURITY INVOKER
       NO SQL
  BEGIN
    DECLARE wordCnt, idx, maxIdx INT DEFAULT 0;
    DECLARE currChar, prevChar BOOL DEFAULT 0;
    SET maxIdx=char_length(str);
    SET idx = 1;
    WHILE idx <= maxIdx DO
        SET currChar=SUBSTRING(str, idx, 1) RLIKE '[[:alnum:]]';
        IF NOT prevChar AND currChar THEN
            SET wordCnt=wordCnt+1;
        END IF;
        SET prevChar=currChar;
        SET idx=idx+1;
    END WHILE;
    RETURN wordCnt;
  END
$$
DELIMITER ;

Altri suggerimenti

Questo è un bel po 'più veloce, anche se solo un po' meno preciso. Ho trovato 4% luce sul conteggio, che è OK per gli scenari di "stima".

SELECT
    ROUND (   
        (
            CHAR_LENGTH(content) - CHAR_LENGTH(REPLACE (content, " ", "")) 
        ) 
        / CHAR_LENGTH(" ")        
    ) AS count    
FROM documents

È possibile utilizzare l'UDF word_count() da https://github.com/spachev/mysql_udf_bundle . Ho portato la logica della risposta accettata con una differenza che il mio codice supporta solo set di caratteri latin1. La logica avrebbe bisogno di essere rielaborato per supportare altri set di caratteri. Inoltre, entrambe le implementazioni considerano sempre un carattere non alfanumerico di essere un delimitatore, che non sempre desiderabile -. Per esempio "Il libro di maestro" è considerato come tre parole di entrambe le implementazioni

La versione UDF è, naturalmente, molto più velocemente. Fate un rapido test ho provato sia su un set di dati da Project Guttenberg che consiste di 9751 record per un totale di circa 3 GB. L'UDF ha fatto tutto di loro in 18 secondi, mentre la funzione memorizzata ha preso 63 secondi per elaborare solo 30 record (che UDF fa in 0,05 secondi). Così l'UDF è di circa 1000 volte più veloce in questo caso.

FSU battere qualsiasi altro metodo di velocità che non comporta la modifica MySQL codice sorgente. Questo è perché ha accesso ai byte di stringa in memoria e può operare direttamente su byte, senza che debbano essere spostati. E 'anche compilato in codice macchina e viene eseguito direttamente sulla CPU.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top