3

By address I only mean normal address like country, state, city, district, street, building where the address can be efficiently referenced in other tables like people so that we can select people in the same city or so on? Thx.

miken32
  • 42,008
  • 16
  • 111
  • 154
hetaoblog
  • 1,990
  • 5
  • 26
  • 34
  • 1
    possible duplicate of [Best practices for storing postal addresses in a database (RDBMS)?](http://stackoverflow.com/questions/310540/best-practices-for-storing-postal-addresses-in-a-database-rdbms) – Tony Andrews May 24 '11 at 11:43

4 Answers4

6

In my experience, you need country, state, city, zip, address.

Only the first three/four are convenient to filter users. Enum fields are very suitable for the first two. The next two are ideally validated using APIs -- this will spare you the hassle of needing to maintain a list of valid values.

I've yet to run into any system (though I assume a post office would need it, along with geolocation) that needs the address part to be chunked in individual pieces of data for more precise filtering -- plus, each user has his own way of entering the latter.

Keep in mind that some countries have no state; that others have no zip codes; and that zip code formats vary widely from a country to the next.

Also keep in mind that, even when a user can have multiple addresses in your system, the last thing you want is to tie multiple users to the same address_id. They're usually better placed as details of the users (or their company), or as 1-n related details towards the latter; never n-n. When not, UI issues quickly creep in, and someone will invariably edit the address of user B by mistake, because the latter happens to share it with user A.

Denis de Bernardy
  • 75,850
  • 13
  • 131
  • 154
4

Here is one extended database structure for address representation,
Advantages with this approach
1. You can add city, country, state later on.
2. it supports edting of city country or state.
3. City is mapped to State and similarely state is mapped to Country. So you will just be storing city in an addrss. You are not needed to store state and country in each address, thus reducing redundancy.
4. You can generate a list of State whenever user chooses a country. Similarely you can generate a list of city when user chooses a state.

Address
   id            INT        PK    AUTO_INCREMENT
   street        VARCHAR    
   city_fk       INT        FK    
   Zip_code      VARCHAR
City
   id            INT        PK    AUTO_INCREMENT
   name          VARCHAR
   state_fk      INT        FK
State
   id            INT        PK    AUTO_INCREMENT
   name          VARCHAR
   country_fk    INT        Fk
Country
   id            INT        PK    AUTO_INCREMENT
   name          VARCHAR

user
   id            INT        PK    AUTO_INCREMENT
   # other details
user_address_mapping                              # So that user can have multiple address
   id            INT        PK    AUTO_INCREMENT
   user_fk       INT        FK                    # Link to user
   address_fk    INT        FK                    # Foreign key to address

EDIT: (Thanks to @Denis comment)
Or If your contry does not have states (Or you want a generic solution) here is the structure.

Address
   id            INT        PK    AUTO_INCREMENT
   street        VARCHAR    
   city_fk       INT        FK    
   state_fk      INT        FK
   country_fk    INT        FK
   Zip_code      VARCHAR
City
   id            INT        PK    AUTO_INCREMENT
   name          VARCHAR
State
   id            INT        PK    AUTO_INCREMENT
   name          VARCHAR
Country
   id            INT        PK    AUTO_INCREMENT
   name          VARCHAR

user
   id            INT        PK    AUTO_INCREMENT
   # other details
user_address_mapping                              # So that user can have multiple address
   id            INT        PK    AUTO_INCREMENT
   user_fk       INT        FK                    # Link to user
   address_fk    INT        FK                    # Foreign key to address
   # Here user_fk & address_fk should be composite unique key, so that users can not share an address.
Rahul Prasad
  • 8,074
  • 8
  • 43
  • 49
  • 1
    So... when a country has no state, it can't have cities either? :-) – Denis de Bernardy May 24 '11 at 11:31
  • You can have single state with the same name as country, See I am genius :P :) – Rahul Prasad May 24 '11 at 11:40
  • for solution 1, if we need to search by people in the country, there will be many joins to reach the country table from user, will this become inefficient? meanwhile, when we use or mapping, the codes is really long like USEROBJECT.ADDRESS.CITY.STATE.COUNTRY, looks a bit inconvenient – hetaoblog May 25 '11 at 04:40
  • for solution 2, normally we will have some cascade dropdown lists, the 1st will be country, the 2nd will be state, it can not reflect this relationship, usually when user select the country, we should display those states. so i'm wondering how we can efficiently and elegantly solve above problems? thx – hetaoblog May 25 '11 at 04:46
  • @hetaoblog: Use first solution, If a country does not has any states, just add a dummy state (same as country name). Cache the data of city, state, country (which are not likely to be changes but frequently needed) in database (Query cache) or in server (using APC/memcached etc). Once cached, you wont need many joins thus making queries faster. – Rahul Prasad May 26 '11 at 05:17
1

Well depend on how you want to normalize the db, (warehouse or transactions)

Example 1: unnormalized, everything in one table

table name: user

attribute: userid, username, country

sql to retrieve:

 select username from user where country="USA"

Example 2: normalized, everything in separate table

table name: user attribute: userid, user name, countryID

table name: country attribute: countryID, country name

sql to retrieve:

 select username from user inner join country where country="USA"

You need to know what the db is used for to determine the "efficient" way.

Will
  • 900
  • 10
  • 20
0

"country", "zip code", "state", "city", "street" and "building" fields will be able to cover almost all addresses in this world as shown below:

*****************************************************************
Type            Field name    Displayed name in your form         
*****************************************************************
INT             id (PK)
VARCHAR(100)    country       Country            
VARCHAR(100)    zip_code      Zip code
VARCHAR(100)    state         State, province or prefecture
VARCHAR(100)    city          City
VARCHAR(100)    street        Street address
VARCHAR(100)    building      Apt, office, suite, etc. (Optional)
*****************************************************************
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129