Tengo una base de datos en la que estoy almacenando más de 1000000 nombres en mysql. Ahora la tarea de mi aplicación es un poco típica. No solo busco nombres en la base de datos, sino que también encuentro nombres similares. Supongamos que el nombre se ingresa como christian
, luego la aplicación mostrará nombres sugeridos como christine
, chris
, etc. ¿Cuál es la forma óptima de hacerlo, sin utilizar la cláusula like
? Las sugerencias serán solo sobre los cambios en la última parte del nombre.Forma óptima de encontrar un valor similar en una tabla grande
Respuesta
Si quieres también nombres similares (por sonido) algo así como SOUNDEX()
podría ayudar: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_soundex
De lo contrario … LIKE 'chri%'
parece para mí no es una mala idea?
Si realmente quiere solo los primeros caracteres sin LIKE
puede usar SUBSTRING()
.
Desearía poder votar esta vez dos veces. Por supuesto, si usa SUBSTRING() para comparar solo los primeros caracteres, LIKE xyz% parece hacer lo mismo. Pero SOUNDEX() ... es una gran sugerencia y me recuerda a los módulos Lingua :: EN :: SimilarNames, Text :: Soundex y Lingua :: EN :: NameLookup CPAN para Perl (lo que no ayudaría porque requiere que el conjunto de datos sea importado primero). – DavidO
usando SUBSTRING() requerirá un escaneo completo de la tabla. LIKE será más rápido en este caso. SOUNDEX() es una buena sugerencia, pero debe almacenarse como un campo indexado por separado para que la búsqueda sea rápida. –
Podría usar una expersión regular, creo. No estoy de acuerdo, pero hay una función llamada REGEXP que puedes poner en una cláusula WHERE. Mire here
'REGEXP' es útil para consultas más complejas, pero será mucho más lento que' LIKE'. – glortho
¡Me imaginé que (nunca lo usé) era solo para proponer algo diferente de "ME GUSTA"! –
Like
es generalmente una buena solución, pero otra forma de mejorar el rendimiento para esto podría ser crear un índice de columna parcial y luego enviar consultas en la misma longitud que su prefijo. Consulte el MySQL documentation con respecto a col_name(length)
.
Puede usar SOUNDS LIKE, creo que debería ser bastante rápido también.
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#operator_sounds-like
kalyoncu, esto probablemente hará un buen trabajo, pero requerirá una exploración de tabla completa como SOUNDEX(). –
Si puede crear un campo adicional, puede evitar eso. Con cada inserción inserta Soundex en ese campo y en el tiempo de búsqueda será bastante rápido. También puedes construir un índice en ese campo. Hmm, creo que esta es una mejor respuesta que la anterior. –
También puede convertir una cadena de soundex en un número y está en formato C#### si no recuerdo mal. Donde C es entre 1-26, entonces un número de 6 dígitos como máximo. –
utilizando como en el lado izquierdo se fija no requerirá un recorrido de tabla. Supongo que esta es la razón por la que no desea utilizar LIKE: SELECT * FROM table WHERE name LIKE CONCAT(?, "%")
es rápido y no requerirá un escaneo de tabla para encontrar filas. El CONCAT le permite usar consultas preparadas con% de sintaxis.
También podría hacer algo como:
SELECT * from table WHERE name < 'christian' LIMIT 20
y
SELECT * FROM table WHERE name > 'christian' LIMIT 20
encontrar vecinos en la lista ordenada.
Puede usar la función metaphone() de php para generar el código de metafonía para cada nombre y almacenarlos junto con los nombres.
<?php
print "chris" . "\t" . metaphone("chris") . "\n";
print "christian" . "\t" . metaphone("christian") . "\n";
print "christine" . "\t" . metaphone("christine") . "\n";
# prints:
# chris XRS
# christine XRSTN
# christian XRSXN
continuación, puede utilizar un algoritmo de distancia levenshtein (ya sea en php [http://php.net/manual/en/function.levenshtein.php] o MySQL [http://www.artfulsoftware.com /infotree/queries.php#552]) para calcular la distancia entre los metacódigos. En mi prueba a continuación, una distancia de 2 o menos parecía indicar el nivel de similitud que está buscando.
<?php
$names = array(
array('mike',metaphone('mike')),
array('chris',metaphone('chris')),
array('chrstian',metaphone('christian')),
array('christine',metaphone('christine')),
array('michelle',metaphone('chris')),
array('mick',metaphone('mick')),
array('john',metaphone('john')),
array('joseph',metaphone('joseph'))
);
foreach ($names as $name) {
_compare($name);
}
function _compare($n) {
global $names;
$name = $n[0];
$meta = $n[1];
foreach ($names as $cname) {
printf("The distance between $name and {$cname[0]} is %d\n",
levenshtein($meta, $cname[1]));
}
}
- 1. Encontrar el valor más grande en un diccionario
- 2. ¿Cómo encontrar la orden de procesamiento óptima?
- 3. Comparación de matrices de objetos, forma óptima
- 4. 'Caché' de una tabla grande en ASP.NET
- 5. Encontrar el valor "exótico" en una tabla MySQL
- 6. ¿Cómo manejar una tabla grande en MySQL?
- 7. Encontrar el valor máximo en la columna de la tabla
- 8. ¿Cómo encontrar un fragmento de código similar?
- 9. ¿Forma óptima de enviar correo con SmtpClient?
- 10. Consulta similar a una forma en T-SQL
- 11. ¿La forma óptima de comparar cadenas en Javascript?
- 12. ¿Hay alguna forma de encontrar una tabla en un archivo DBML en Visual Studio 2008?
- 13. Eliminar duplicados de una tabla grande
- 14. ¿Cómo extraigo un bit de forma más óptima?
- 15. Mantener una tabla grande de valores únicos en MySQL
- 16. Forma óptima de unir tres tablas en SQLite
- 17. En Ruby, ¿cuál es la forma más limpia de obtener el índice del valor más grande en una matriz?
- 18. Solución óptima para una gran cantidad de solicitudes en una tabla de base de datos
- 19. consulta para encontrar el primer y el segundo valor más grande de un grupo
- 20. ¿Qué tan grande es demasiado grande para una tabla MySQL?
- 21. Forma más eficiente de encontrar si una lista grande contiene una cadena específica (Python)
- 22. Seleccione un valor escalar de una tabla
- 23. Cómo obtener la segunda entrada más grande o la tercera más grande de una tabla
- 24. manera eficiente para encontrar la clave más grande en un diccionario con valor distinto de cero
- 25. Cómo estructurar una tabla extremadamente grande
- 26. Pivote de salida similar a una tabla en R?
- 27. Comprobando si un archivo CSV grande (1m filas) tiene los mismos datos que una tabla MySQL
- 28. ¿Cómo puedo encontrar el valor más grande en una columna en postgres sql?
- 29. ¿La forma más rápida de encontrar la cadena más similar a una entrada?
- 30. Encontrar una imagen pequeña en una más grande
¿Por qué no quieres usar la cláusula 'like'? – Geoffroy
Considera cambiar a Postgres. Permite hacer esto usando [diccionarios de búsqueda de texto] (http://www.postgresql.org/docs/9.0/static/textsearch-dictionaries.html) –
¿Puede agregar un nuevo campo? de ser así, verifique mi comentario adicional en mi respuesta. –