¿Qué es el símbolo tilde en MySQL?

MySQL: UTF8MB4 y Búsqueda Full-Text Avanzada

Valoración: 4.55 (5321 votos)

Al trabajar con bases de datos, especialmente en un entorno globalizado, es fundamental elegir la codificación de caracteres adecuada para asegurar que toda la información se almacene y recupere correctamente. De igual manera, entender las capacidades avanzadas de búsqueda puede transformar la forma en que interactúas con tus datos. En MySQL, dos áreas clave para considerar son la configuración del conjunto de caracteres y el uso de la búsqueda full-text en modo booleano.

La elección del conjunto de caracteres impacta directamente en la capacidad de tu base de datos para almacenar texto en diferentes idiomas, incluyendo caracteres especiales y símbolos. Por otro lado, la búsqueda full-text ofrece una forma poderosa de encontrar información relevante dentro de grandes volúmenes de texto, y su modo booleano proporciona un control granular sobre los criterios de búsqueda.

¿Qué UTF usar en MySQL?
El conjunto de caracteres recomendado para MySQL es utf8mb4 . Todas las aplicaciones nuevas deberían utilizar utf8mb4 .
Índice de Contenido

El Conjunto de Caracteres Recomendado en MySQL: UTF8MB4

Para cualquier aplicación nueva que desarrolle o para migraciones, el conjunto de caracteres recomendado para MySQL es utf8mb4. Pero, ¿por qué es tan importante y por qué se prefiere sobre otras opciones como el simple `utf8`?

Históricamente, el conjunto `utf8` en MySQL era un alias para `utf8mb3`, que soporta caracteres codificados con hasta 3 bytes. Sin embargo, el estándar UTF-8 completo puede requerir hasta 4 bytes por carácter para representar la totalidad del repertorio Unicode, incluyendo una amplia gama de caracteres menos comunes, símbolos matemáticos, musicales y, crucialmente en la actualidad, los emojis.

El uso de utf8mb4 garantiza que tu base de datos pueda almacenar y procesar correctamente todos estos caracteres de 4 bytes. Si utilizas `utf8` (`utf8mb3`) e intentas almacenar un carácter de 4 bytes, MySQL puede truncar el carácter o generar un error, lo que lleva a la pérdida de datos o a problemas de visualización. Por lo tanto, para asegurar la compatibilidad con el repertorio Unicode completo y evitar futuros problemas, utf8mb4 es la elección estándar y recomendada para todas las nuevas aplicaciones.

Profundizando en la Búsqueda Full-Text de MySQL: El Modo Booleano

MySQL ofrece la capacidad de realizar búsquedas full-text en columnas de texto indexadas. Una de las modalidades más potentes es la búsqueda full-text utilizando el modificador IN BOOLEAN MODE. Con este modificador, ciertos caracteres adquieren un significado especial al principio o al final de las palabras en la cadena de búsqueda, permitiendo un control preciso sobre qué filas deben coincidir.

En el modo booleano, la búsqueda no utiliza el umbral del 50% que se aplica a los índices de búsqueda MyISAM (excepto para índices ngram). Las búsquedas booleanas no ordenan automáticamente las filas por orden de relevancia decreciente, a menos que se utilicen operadores que afecten la relevancia (como `>` o `<` o `~`), o que se realice una búsqueda sin operadores explícitos (comportamiento por defecto).

Operadores Clave en el Modo Booleano

El modo booleano soporta varios operadores para refinar la búsqueda:

  • + (Signo Más Inicial): Indica que la palabra *debe* estar presente en cada fila retornada. InnoDB solo soporta el signo más inicial.
  • - (Signo Menos Inicial): Indica que la palabra *no debe* estar presente en ninguna de las filas retornadas. InnoDB solo soporta el signo menos inicial. Es importante notar que una búsqueda que solo contenga términos precedidos por `-` devolverá un resultado vacío, ya que solo actúa para excluir filas que de otra manera coincidirían con otros términos.
  • " (Comillas Dobles): Una frase encerrada entre comillas dobles coincide solo con filas que contengan la frase literalmente, tal como fue escrita. El motor full-text divide la frase en palabras y busca en el índice. Los caracteres no alfabéticos no necesitan coincidir exactamente; solo se requiere que las palabras sean las mismas y en el mismo orden.
  • * (Asterisco): Sirve como operador de truncamiento (o comodín). Se añade al final de la palabra afectada. Las palabras coinciden si comienzan con la palabra que precede al operador `*`. Si una palabra se especifica con el operador de truncamiento, no se elimina de una consulta booleana, incluso si es demasiado corta o una stopword.
  • > y < (Signos Mayor y Menor que): Estos operadores se utilizan para cambiar la contribución de una palabra al valor de relevancia asignado a una fila. El operador `>` aumenta la contribución, y el operador `<` la disminuye.
  • ~ (Tilde): Un tilde inicial actúa como un operador de negación suave. Causa que la contribución de la palabra a la relevancia de la fila sea negativa. Esto es útil para marcar palabras de 'ruido'. Una fila que contenga dicha palabra se clasifica más bajo que otras, pero no se excluye por completo, como lo haría con el operador `-`. Es una forma más suave de indicar que una palabra es indeseada pero no un criterio de exclusión estricto.
  • @distance (Operador de Proximidad): Este operador funciona solo en tablas InnoDB. Prueba si dos o más palabras comienzan dentro de una distancia especificada entre sí, medida en palabras. La frase de búsqueda se especifica entre comillas dobles inmediatamente antes del operador `@distance`, por ejemplo: MATCH(col1) AGAINST('"palabra1 palabra2" @5' IN BOOLEAN MODE). InnoDB full-text search no soporta el uso del símbolo `@` directamente en búsquedas booleanas sin el operador de distancia.
  • Comportamiento por Defecto: Si una palabra no se especifica con `+` ni `-`, la palabra es opcional, pero las filas que la contienen se clasifican más alto. Esto imita el comportamiento de MATCH() AGAINST() sin el modificador IN BOOLEAN MODE.

Diferencias entre Motores (InnoDB vs. MyISAM)

Existen diferencias importantes en la implementación de la búsqueda full-text en modo booleano entre los motores de almacenamiento InnoDB y MyISAM:

  • Requisitos de Índice: Las tablas InnoDB requieren un índice FULLTEXT en todas las columnas de la expresión MATCH() para realizar consultas booleanas. Las consultas booleanas contra un índice MyISAM pueden funcionar incluso sin un índice FULLTEXT, aunque sería muy lento.
  • Soporte de Operadores: InnoDB full-text search no soporta el uso de un signo más inicial con comodín (`+*`), una combinación de signo más y menos (`+-`), o combinaciones de signo más y menos iniciales (+-apple). Estas consultas inválidas devuelven un error de sintaxis. InnoDB solo soporta signos más o menos iniciales (ej: `+apple`, `-apple`), no finales (ej: `apple+`, `apple-`). El uso de múltiples operadores en una sola palabra (ej: `++apple`) también devuelve un error de sintaxis en InnoDB, mientras que MyISAM procesa la misma búsqueda ignorando todos los operadores excepto el adyacente a la palabra.
  • Stopwords y Longitud Mínima/Máxima: La lista de stopwords se aplica, controlada por las configuraciones relevantes para cada motor (`innodb_ft_enable_stopword`, etc. para InnoDB; `ft_stopword_file` para MyISAM). Los parámetros de longitud mínima y máxima de palabra no se aplican a índices `FULLTEXT` creados con el analizador `ngram`; el tamaño del token `ngram` se define por la opción `ngram_token_size`. Para índices con el analizador incorporado o el plugin MeCab, se aplican `innodb_ft_min_token_size` y `innodb_ft_max_token_size` para InnoDB, y `ft_min_word_len` y `ft_max_word_len` para MyISAM. Si una palabra se trunca (`*`), no se elimina de la consulta booleana, incluso si es demasiado corta o una stopword (determinado por las configuraciones de longitud mínima).
  • Ordenación: Las búsquedas booleanas no ordenan automáticamente por relevancia decreciente.

Cálculo de Relevancia en InnoDB Boolean Mode

La búsqueda full-text de InnoDB se basa en algoritmos como BM25 y TF-IDF (Term Frequency-Inverse Document Frequency) para clasificar la relevancia de un documento para una consulta. La ponderación TF-IDF se basa en la frecuencia con la que una palabra aparece en un documento, compensada por la frecuencia con la que la palabra aparece en todos los documentos de la colección.

El valor de Term Frequency (TF) es el número de veces que una palabra aparece en un documento.

El valor de Inverse Document Frequency (IDF) de una palabra se calcula utilizando la fórmula:

IDF = log10( total_records / matching_records )

Donde total_records es el número total de registros en la colección, y matching_records es el número de registros en los que aparece el término de búsqueda.

Cuando un documento contiene una palabra varias veces, el valor IDF se multiplica por el valor TF (TF * IDF).

Utilizando los valores TF e IDF, la clasificación de relevancia (rank) para un documento se calcula con la fórmula:

rank = TF * IDF * IDF

Para una búsqueda de varias palabras, el valor de relevancia es la suma de los valores de relevancia para cada palabra.

Consideremos un ejemplo proporcionado por la documentación, buscando 'database' en una tabla con 8 registros, donde 'database' aparece en 3 de ellos. Un registro particular (ID 6) contiene el término 6 veces.

¿Cuál es la diferencia entre UTF-8 y UTF8mb4?
La diferencia entre UTF8 y UTF8mb4 es que el primero solo puede almacenar caracteres de 3 bytes, mientras que el segundo puede almacenar caracteres de 4 bytes. En términos Unicode, UTF8 solo puede almacenar caracteres en el plano multilingüe básico, mientras que UTF8mb4 puede almacenar cualquier carácter Unicode.7 abr 2020

total_records = 8

matching_records = 3

TF (para el registro ID 6) = 6

IDF = log10(8 / 3) ≈ 0.4259687

rank (para el registro ID 6) = 6 * 0.4259687 * 0.4259687 ≈ 1.088696

Para una búsqueda de múltiples palabras como 'mysql tutorial', si 'mysql' aparece en 6 registros y 'tutorial' en 2, y un registro particular (ID 1) tiene 'mysql' una vez y 'tutorial' dos veces:

IDF('mysql') = log10(8 / 6) ≈ 0.1249387

IDF('tutorial') = log10(8 / 2) ≈ 0.60206

TF('mysql' en ID 1) = 1

TF('tutorial' en ID 1) = 2

rank('mysql' en ID 1) = 1 * 0.1249387 * 0.1249387 ≈ 0.0156097

rank('tutorial' en ID 1) = 2 * 0.60206 * 0.60206 ≈ 0.724952

rank total (ID 1) = rank('mysql') + rank('tutorial') ≈ 0.0156097 + 0.724952 ≈ 0.7405617

Las pequeñas diferencias en los valores de relevancia mostrados por la consulta SELECT ... MATCH ... AGAINST y los cálculos manuales se deben a diferencias internas en cómo se realizan las conversiones entre tipos numéricos y las decisiones de precisión/redondeo.

Ejemplos de Cadenas de Búsqueda Booleanas

Para ilustrar el uso de los operadores:

  • "palabras exactas": Busca la frase literal "palabras exactas".
  • apple*: Busca palabras que comiencen con "apple", como "apple", "apples", "applesauce".
  • +apple +(turnover strudel): Busca filas que contengan "apple" y "turnover", o "apple" y "strudel".
  • +apple ~macintosh: Busca filas que contengan "apple", pero si también contienen "macintosh", se clasifican más bajo.
  • +apple -macintosh: Busca filas que contengan "apple" pero *no* "macintosh".
  • +apple >macintosh: Busca filas que contengan "apple", pero clasifica más alto las filas que también contienen "macintosh".
  • apple macintosh: Busca filas que contengan al menos una de las dos palabras (comportamiento por defecto).

Tabla Comparativa de Operadores Booleanos

OperadorDescripciónEfecto en RelevanciaEfecto en CoincidenciaNotas (InnoDB)
+Presencia RequeridaAumentaDebe estar presenteSolo inicial
-Presencia ExcluidaN/A (Excluye)No debe estar presenteSolo inicial, solo excluye de coincidencias existentes
" "Frase ExactaAumentaDebe contener la secuencia exacta de palabras
*Truncamiento/ComodínVaríaCoincide si la palabra comienza con el prefijoSe aplica incluso si es stopword o corta
>Aumentar ContribuciónIncrementa significativamenteOpcional (por defecto)
<Disminuir ContribuciónDecrementa significativamenteOpcional (por defecto)
~Negación Suave (Tilde)Decrementa ligeramente (negativo)OpcionalFila no excluida, solo clasificada más bajo
@distanceProximidadAumentaLas palabras deben estar dentro de la distancia especificadaSolo InnoDB, se usa como "palabras" @N
(Ninguno)OpcionalAumenta si está presenteOpcionalComportamiento por defecto

Preguntas Frecuentes (FAQ)

¿Cuál es el conjunto de caracteres recomendado para MySQL?

El conjunto de caracteres recomendado para MySQL es utf8mb4. Debería utilizarse para todas las aplicaciones nuevas.

¿Por qué se recomienda utf8mb4 sobre utf8?

El conjunto `utf8` en MySQL generalmente es un alias para `utf8mb3`, que solo soporta caracteres de hasta 3 bytes. utf8mb4 soporta caracteres de hasta 4 bytes, lo que es necesario para el repertorio Unicode completo, incluyendo emojis y otros símbolos, evitando problemas de almacenamiento y visualización.

¿Qué significa el símbolo tilde (~) en una búsqueda full-text en MySQL?

En el modo booleano de la búsqueda full-text, un tilde inicial (~) actúa como un operador de negación suave. Indica que la presencia de la palabra disminuye la relevancia de la fila, clasificándola más bajo, pero no la excluye completamente del resultado, a diferencia del operador `-`.

¿InnoDB y MyISAM se comportan igual en la búsqueda full-text booleana?

No, existen diferencias. InnoDB requiere un índice FULLTEXT en todas las columnas de la expresión MATCH(), mientras que MyISAM puede funcionar sin él (aunque lentamente). InnoDB tiene restricciones en el uso de algunos operadores como `+*`, `+-`, operadores finales, y múltiples operadores. El cálculo de relevancia también difiere.

¿Cómo se calcula la relevancia en InnoDB full-text boolean mode?

La relevancia se calcula utilizando una variación del sistema de ponderación TF-IDF (Term Frequency-Inverse Document Frequency). Se basa en la frecuencia de la palabra en el documento (TF) y su frecuencia en la colección total (IDF), utilizando la fórmula rank = TF * IDF * IDF para una palabra, y la suma de los rangos individuales para múltiples palabras.

¿Las búsquedas booleanas en MySQL ordenan los resultados por relevancia automáticamente?

No, a diferencia del modo natural, las búsquedas en IN BOOLEAN MODE no ordenan automáticamente por relevancia decreciente, a menos que se utilicen operadores que afecten la relevancia o se dependa del comportamiento por defecto para palabras sin operadores `+` o `-`.

¿Puedo usar operadores de truncamiento (*) con stopwords o palabras cortas en modo booleano?

Sí, si una palabra se especifica con el operador de truncamiento (`*`), no se elimina de la consulta booleana, incluso si es una stopword o más corta que la longitud mínima configurada.

Conclusión

La correcta configuración del conjunto de caracteres a utf8mb4 es un paso esencial para asegurar la integridad y compatibilidad global de tus datos en MySQL. Combinado con un entendimiento profundo de las capacidades de la búsqueda full-text en modo booleano, incluyendo el uso de operadores como el tilde para refinar la relevancia, puedes construir aplicaciones de base de datos más robustas y sistemas de búsqueda más precisos y potentes.

Si quieres conocer otros artículos parecidos a MySQL: UTF8MB4 y Búsqueda Full-Text Avanzada puedes visitar la categoría Bases de datos.

Ivan

Soy un entusiasta de la tecnología con especialización en bases de datos, particularmente en MySQL. A través de mis tutoriales detallados, busco desmitificar los conceptos complejos y proporcionar soluciones prácticas a los desafíos cotidianos relacionados con la gestión de datos

Aprende mas sobre MySQL

Subir