7

A given location (city), can have a name and also other aliases by which it can be known. I need to model this in a database.

Search can be executed using either city or any of its alias:

For e.g.

City:

  • name: Los Angeles
  • alias: LA

When specifying the search criterion, I can either specify LA or Los Angeles, and it should return the same result (e.g. Hollywood).

I was thinking of doing it using One-To-Many relation where 1 city can have many aliases, and many aliases can map to one city.

When doing a search, I use a join of city and cityAlias table to find the correct city.

Is there a better way to deal with this?

Image

EDIT: (For anyone who runs into the same problem/requirements and happen to comes to this page) Please see my answer as well, since I ended up using that, but the marked answer helps you identify unique cities.

brainydexter
  • 19,826
  • 28
  • 77
  • 115
  • 2
    I think you're pretty much on the right track, bar any SQL trickery that I am unfamiliar with. I would have done it the way you suggest. – Dervall Feb 08 '12 at 07:08
  • I know I'm coming to this after more than 5 years :) but how did you deal with deletion (if it was a valid use case)? i.e. deleting a city vs deleting an alias. Did you handle this in the application code? (I have a similar case) – A. B Oct 16 '17 at 19:45

3 Answers3

6

The only thing I can add to your solution is that you can try first looking for the exact match in the city tables and if there isn't any, then joining with the alias one. That way you might skip some joins that are quite expensive.

Another thing to notice is that this double table solution might have trouble with duplicated entries. I'm not talking about same aliases for different cities (this can be checked with a unique column), but aliases matching city names. Example of these "duplicate entries" followed by detailed explanation:

Cities

ID | Name
---------
1  | Los Angeles
2  | New York

Aliases

ID | CityId | Name
------------------
1  | 1      | LA
2  | 2      | NY
3  | 2      | Los Angeles

I know this should not happen... but you know Moore's laws :) These cross-table-duplicates might give you trouble in a lookup table (I imagine you're using them as a look up to "guess" what City has actually tried to select the user when he/she wrote "LA"). But if the user wrote "Los Angeles", you'll have to decide whether to prioritize the City or the Alias. I know the example I provided is a bit silly but as a non-american citizen I can't provide better examples. But there are many cities out there with many aliases for each one... I wouldn't take a chance :)

Checking first the city table will give the city priority over an equaled named alias for other city. Or you can check whether an alias to a city is already present as a city name before inserting it.

That's all I can think of :)

Mosty Mostacho
  • 42,742
  • 16
  • 96
  • 123
  • Thanks for the insight. I didn't understand what you meant there by `trouble with duplicated entries`. Can you elaborate a bit more on that ? – brainydexter Feb 08 '12 at 07:34
  • I added a detailed explanation about those duplicate entries. Hope that helps – Mosty Mostacho Feb 08 '12 at 07:48
  • Thanks, that helped. I was discussing this with someone else, and another thing came up to solve what you said.. At the time of adding a city, also create an alias in the alias table with the same cityName. That ways, one only needs to search in alias table. As for duplicate entries, I guess I will give both the options to the user, to select which one to use. – brainydexter Feb 08 '12 at 09:08
  • Also, please see my answer which emphasizes on duplicate entries. – brainydexter Feb 08 '12 at 09:37
0

Some notes:

The DestinationAlias table does not need a surrogate key. The (idDestination, alias) (or the reverse) can serve as a PRIMARY KEY.

To eliminate the duplication of the (common) names in both tables and the problems that might occur, you can remove the name column from the Destination table and add a DestinationDefaultAlias table, having a 1:1 relationship with DestinationAlias (and an implied 1:1 relationship with Destination):

CREATE TABLE DestinationDefaultAlias
( idDestination
, alias
, PRIMARY KEY (idDestination)
, FOREIGN KEY (idDestination, alias)
    REFERENCES DestinationAlias (idDestination, alias)
) 

When you want to find the default name, you join Destination with DestinationDefaultAlias. To search all aliases, you join with DestinationAlias.

ypercubeᵀᴹ
  • 113,259
  • 19
  • 174
  • 235
0

Assumption:

  • La Aguardia is a random city name
  • LA is an alias of La Aguardia
  • Los Angeles is an alias of New York

  • For every city added, add the city name itself as an entry to the alias table, so we only have to search on alias table.

City table:

cityId  |   Name
    1   |   Los Angeles
    2   |   New York
    3   |   La Aguardia

Alias table:

cityId  |   AliasName
    1   |   Los Angeles
    1   |   LA
    2   |   New York
    2   |   NY
    2   |   Los Angeles
    3   |   La Aguardia
    3   |   LA

Use case 1:

Search for LA: yields (cityID) => [1, 3] =unique> [Los Angeles, La Aguardia]

Use case 2:

Search for Los Angeles: yields (cityID) => [1, 2] =unique> [Los Angeles, New York]

Use case 3:

Search for New York: yields (cityID) => [2,2] =unique> [New York]

brainydexter
  • 19,826
  • 28
  • 77
  • 115
  • 1
    This smells like a suggest box :) So you're actually allowing duplicates to display to the user. If that is the case this is great. My solution is actually intended to not allow duplicate results by: applying a UNIQUE index on the alias and by looking first in the city table (for example, if looking for "Los Angeles" the city table will match first). Now if you're allowed to return more than one result, go ahead with this one, but make sure you have an alias for each city in the table and bear that in mind when adding new ones :) – Mosty Mostacho Feb 08 '12 at 09:51
  • 1
    I'm not specifically developing this for a suggestion box, but yes, I think it will be used in that functionality as well :) As for duplicates, I thought about what you said, (particularly use case1 here), and thought it'd be best to let the user choose which one he wants. Later on, if I have to identify a unique city for a given alias, I think I will definitely edit my query to what you said. – brainydexter Feb 08 '12 at 09:56