2009-04-29 15 views
7

Ofrezco una opción de búsqueda para mis usuarios. Pueden buscar el nombre de la ciudad. El problema es que los nombres de mi ciudad que he almacenado son cosas como "Saint Louis". Pero quiero encontrar Saint Louis incluso si el usuario escribe "St. Louis" o "St Louis". ¿Alguna sugerencia sobre cómo podría crear una tabla de búsqueda para tener eso en cuenta de alguna manera?Pregunta sobre el diseño de la tabla

+1

Qué base de datos está utilizando? – Jeremy

+0

Lo sentimos, SQL Server de .Net: este es un servicio web, por lo que la consulta se me pasa, no consigo recogerla del usuario. –

Respuesta

5

Crear dos tablas.

Uno contiene todo sobre una ciudad.

Uno contiene un grupo de nombres para las ciudades, y una asociación de claves foráneas con el ID de la primera tabla. Entonces tienes una relación uno a muchos entre ciudad y ciudad_nombres.

Ahora el único problema es distinguir el nombre, para cada ciudad, que es el nombre preferido. Podemos hacerlo de varias maneras: 1) la primera tabla podría tener un fk en la segunda tabla, que se aferra a la identificación del nombre preferido. Esto crea una dependencia circular, sin embargo. Así que mejor, 2) simplemente agrega una columna boolean/bit a la segunda tabla, is_preffered.

create table city (id not null primary key, other columns) ; 

create table city_name (
id not null primary key, 
city_id int references city(id), 
name varchar(80), 
is_preferred bool 
) ; 

luego a que todos los nombres, con el nombre preferido en primer lugar:

select name from city_names where city_id = ? 
    order by is_preffered desc, name; 

Esto tiene una ventaja adicional: si usted no cubre cada ciudad y pueblo, se puede utilizar la segunda tabla de mapa de ciudades/pueblos/condados que no cubren a las principales ciudades que haces:

insert into city_name(city_id, name) values 
($id-for-New-York-City, 'New York'), 
($id-for-New-York-City, 'Manhattan'), 
($id-for-New-York-City, 'Big Apple'), 
($id-for-New-York-City, 'Brooklyn'); 
+0

No entiendo por qué necesitaría un nombre "preferido"; quiero decir, si escriben en Nueva York, lo igualaré de inmediato. Si escriben en Manhattan, y enlaza con Nueva York, ¿por qué me importaría la ID de ciudad preferida? –

+0

Puede que no; en ese caso, déjalo fuera. Estaba pensando en no poner el nombre en la ciudad en absoluto, en cuyo caso nos gustaría una forma de mostrar el nombre "canónico" en, por ejemplo, los informes. – tpdi

+0

Fui con esta respuesta y funciona como un encanto hasta el momento. Mi consulta realiza una combinación externa con la tabla de alias, y la cláusula where tiene "WHERE (venue.city = 'st louis' O alias.city_slang = 'st louis')" y uní las tablas en cityname = city_canonical. Estas columnas ESTARÁN cambiando de nombre pronto. –

1

Es posible que desee buscar en un motor de búsqueda de texto completo con más funciones, como Apache Lucene/Solr o Sphinx, que puede admitir este tipo de mapeo de cadenas de forma nativa.

1

Veo una serie de formas posibles de lidiar con esto. Uno es un algoritmo de búsqueda soundex que coincide con la similitud de las cadenas en inglés. Además, esto se admite de forma nativa en algunas bases de datos como PostgreSQL.

Otro enfoque puede consistir simplemente en ofrecer a sus usuarios una funcionalidad de autocompletar en la que, a medida que escriben una serie de sugerencias. De esta forma, los usuarios elegirán el nombre de la ciudad de búsqueda deseada de forma intuitiva.

3

Lo que me gustaría hacer es, crear una tabla de taquigrafía a la normalidad, eso sería asignar cualquier palabra ambigua a una sola constante deletreando tu usar en tu mesa principal. Puede incluir errores ortográficos y errores tipográficos comunes.

Antes de consultar la solicitud del usuario, convierta todas las palabras a la forma normal utilizando esta tabla.

Así, en su caso en la tabla shorthand-to-normal tendremos

______________ 
| short|normal | 
|______|_______| 
|St |Saint | 
|St. |Saint | 
+0

Me preguntaba sobre esto. Entonces, dividiría la entrada en espacios (y "."). Luego haría una búsqueda de su primer término "st" y recuperaría "saint" - luego usaría eso en mi consulta real de la tabla de la ciudad ... hmmm ... podría funcionar. ¡Gracias! –

1

Como criterio general, se puede normalizar los procedimientos tanto al insertar y en la búsqueda de ellos.

Las reglas de normalización podrían ser:

Saint => St 
St. => St 

etc.

Los nombres normalizados a continuación deben coincidir.

+0

Pensé en eso, pero no estoy seguro de poder identificar todas las posibilidades. St es solo uno. ¿Qué hay de KC, MO para Kansas City, Missouri? ATL para Atlanta? Sin embargo, creo que voy a tener que hacer esto, pero en una estructura de tabla como lo sugirieron otros. –

+0

Sí, tendrá que tener algún "diccionario" para su normalización de todos modos. Estaba escribiendo mi respuesta al mismo tiempo que Elazar Leibovich, por lo que ambas son bastante similares en lo que sugieren. – Lucero

0

En mi humilde opinión, me gustaría dejar la base de datos solo y en su lugar tener una lista desplegable de ciudades en su aplicación. Más fácil, más limpio y no requiere mucho más.

+0

La pieza que estoy escribiendo está en .Net con SQL Server, y es simplemente un servicio web para admitir una aplicación de iPhone. El caso es que vamos a dejar que escriban en cualquier ciudad de cualquier país del mundo. No quiero tener un menú desplegable con todo eso. Sería inutilizable. –

+0

Ok. Solo asumí que era una aplicación común. – DForck42

0

Me gusta la opción en la primera respuesta.

Otra idea sería tener una columna para etiquetas para esa ciudad que los usuarios puedan actualizar.

decir

la ciudad de Nueva York es el nombre oficial.

Las etiquetas para esta ciudad serían numerables (Manhattan, NY, NYC, la ciudad, gran manzana ..) e.t.c. pero no querrías toda esa basura en tu tabla principal de Ciudades o crear tablas secundarias asignadas y tienes que hacer uniones. Así que simplemente meta en columnas y búsquelo según el término de búsqueda, pero luego devuelva el nombre correcto si se encuentra.

0

Usted puede utilizar el construido en propiedades SQL FTS para las entradas de tesauro. Esto le permite agregar un mapa de palabras personalizado dentro de la búsqueda de texto completo. De esta forma, puede mantener todo dentro de FTS en lugar de combinar FTS y otras consultas.

No

seguro de la versión de SQL está utilizando como su differant entre 2005/8 por lo que es un buen paso a paso para 2005/8 aquí http://arcanecode.com/2008/05/28/creating-custom-thesaurus-entries-in-sql-server-2005-and-2008-full-text-search/

+0

Eso es interesante. No tengo acceso al registro en este caso, pero gracias por la sugerencia. Pude ver que esto es útil en otras circunstancias. –

+0

Si está en sql 2008, los sinónimo también funcionarían; y no necesitan el hack de registro. Dependiendo de su idioma, el archivo xml está aquí $ SQL_Server_Install_Path \ Microsoft SQL Server \ MSSQL.1 \ MSSQL \ FTData. Puede configurar sus ciudades en el archivo como esto Nueva York Gran Manzana y cargue de nuevo usando EXEC sys.sp_fulltext_load_thesaurus_file 1033 a continuación, debe ser capaz de probar seleccionar * de mitabla donde contiene (*, 'gran Manzana'). (http://www.simple-talk.com/sql/learn-sql-server/understanding-full-text-indexing-in-sql-server/) – u07ch

+0

pps 1033 = página de códigos relevante para su región (tenía un espacio límite) – u07ch