简体   繁体   中英

Zip code based search

I have an app where shop owners can enter 10 zip codes in which they can provide services. Currently these zip codes are stored in single table column. Now what is the best and efficient way to do search based on this? Should I store all zip codes(all US zip codes) in a table and establish many to many relationship or do text search based on the current field using thinking sphinx?

A database guy's perspective . . .

Since you're talking about using Sphinx, I presume you store all 10 ZIP codes in a single row, like this.

shop_id  zip_codes
--
167      22301, 22302, 22303, 22304, 22305, 22306, 22307, 22308, 22309, 22310

You'd be far better off storing them like this, for search and for several other reasons.

shop_id  zip_codes
--
167      22301
167      22302
167      22303
167      22304
167      22305
167      22306
167      22307
167      22308
167      22309
167      22310

-- Example in SQL.
create table serviced_areas (
  shop_id integer not null references shops (shop_id), -- Table "shops" not shown.
  zip_code char(5) not null,
  primary key (shop_id, zip_code)
);

You can make a good case for stopping after making this single change.

But you can increase data integrity substantially without making any other changes to your database if your dbms supports regular expressions. With that kind of dbms support, you can guarantee that the zip_code column contains only 5 integers, no letters. (There may be other ways to guarantee 5 integers and no letters.)

A table of ZIP codes would further increase data integrity. But you could easily argue that the shop owners have a vested interest in entering valid ZIP codes in the first place, and that this isn't worth more effort on your part. ZIP codes change pretty often; don't expect a "complete" table of ZIP codes to be accurate for very long. And you need to have a well-defined procedure for dealing with both new and expired ZIP codes.

-- Example in SQL
create table zip_codes (
  zip_code char(5) primary key
);

create table serviced_areas (
  shop_id integer not null references shops (shop_id),
  zip_code char(5) not null references zip_codes (zip_code),
  primary key (shop_id, zip_code)
);

You will need the zipcodes plus latitude/longitude in your db if you're using sphinx to do geospatial search (not really, you can use a text file or xml I suppose).

By geospatial search I mean something like "Find stores within 20 miles of your location"

For flexibility and efficiency, I would pick #1 ....

"store all zip codes in a table and establish many to many relationship"

...with the assumption you also need to store other zip code data fields (City, State, county, Lat/Long, etc.). In that case your intersection would be: shop_id to zipcode_id(s). However, if you do not need/have extended ZIP Code data fields, then a single separate table with shop_id to the acutal zipcodes (not id) will be fine in my opinion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM