Should mailing addresses with city, state, and zip code be normalized? I am currently concerned with US addresses only.I have shown a normalized tables along with an ERD, and a non-normalized table at the bottom of this post. Please provide rational for your answer.
Note that To Normalize or Not To Normalize is related to this topic, but is different.
Thank you
CREATE TABLE IF NOT EXISTS states (
id CHAR(2) NOT NULL ,
name VARCHAR(45) NULL DEFAULT NULL ,
PRIMARY KEY (id) ,
INDEX states_name (name ASC) )
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS cities (
id INT UNSIGNED NOT NULL AUTO_INCREMENT ,
name VARCHAR(45) NOT NULL ,
states_id CHAR(2) NOT NULL ,
PRIMARY KEY (id) ,
INDEX fk_zipcodes_states1_idx (states_id ASC) ,
UNIQUE INDEX makeUnique (states_id ASC, name ASC) ,
INDEX cities_name (name ASC) ,
CONSTRAINT fk_zipcodes_states1
FOREIGN KEY (states_id )
REFERENCES states (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
PACK_KEYS = 0
ROW_FORMAT = DEFAULT;
CREATE TABLE IF NOT EXISTS zipcode_types (
id INT UNSIGNED NOT NULL AUTO_INCREMENT ,
name VARCHAR(45) NULL DEFAULT NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB
PACK_KEYS = 0
ROW_FORMAT = DEFAULT;
CREATE TABLE IF NOT EXISTS counties (
id INT UNSIGNED NOT NULL AUTO_INCREMENT ,
name VARCHAR(45) NOT NULL ,
PRIMARY KEY (id) ,
INDEX counties_name (name ASC) )
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS timezones (
id CHAR(4) NOT NULL ,
name VARCHAR(45) NOT NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB
PACK_KEYS = 0
ROW_FORMAT = DEFAULT;
CREATE TABLE IF NOT EXISTS zipcodes (
id CHAR(5) NOT NULL ,
longitude DECIMAL(9,6) NOT NULL ,
latitude DECIMAL(9,6) NOT NULL ,
zipcode_types_id INT UNSIGNED NOT NULL ,
counties_id INT UNSIGNED NOT NULL ,
timezones_id CHAR(4) NOT NULL ,
PRIMARY KEY (id) ,
INDEX fk_zipcodes_zipcode_types1_idx (zipcode_types_id ASC) ,
INDEX fk_zipcodes_counties1_idx (counties_id ASC) ,
INDEX fk_zipcodes_timezones1_idx (timezones_id ASC) ,
CONSTRAINT fk_zipcodes_zipcode_types1
FOREIGN KEY (zipcode_types_id )
REFERENCES zipcode_types (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_zipcodes_counties1
FOREIGN KEY (counties_id )
REFERENCES counties (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_zipcodes_timezones1
FOREIGN KEY (timezones_id )
REFERENCES timezones (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS cities_has_zipcodes (
cities_id INT UNSIGNED NOT NULL ,
zipcodes_id CHAR(5) NOT NULL ,
PRIMARY KEY (cities_id, zipcodes_id) ,
INDEX fk_cities_has_zipcodes_zipcodes1_idx (zipcodes_id ASC) ,
INDEX fk_cities_has_zipcodes_cities1_idx (cities_id ASC) ,
CONSTRAINT fk_cities_has_zipcodes_cities1
FOREIGN KEY (cities_id )
REFERENCES cities (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_cities_has_zipcodes_zipcodes1
FOREIGN KEY (zipcodes_id )
REFERENCES zipcodes (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS someRecord (
id INT UNSIGNED NOT NULL AUTO_INCREMENT ,
data VARCHAR(45) NULL ,
address VARCHAR(45) NULL ,
cities_id INT UNSIGNED NOT NULL ,
zipcodes_id CHAR(5) NOT NULL ,
PRIMARY KEY (id) ,
INDEX fk_someRecord_cities1_idx (cities_id ASC) ,
INDEX fk_someRecord_zipcodes1_idx (zipcodes_id ASC) ,
CONSTRAINT fk_someRecord_cities1
FOREIGN KEY (cities_id )
REFERENCES cities (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT fk_someRecord_zipcodes1
FOREIGN KEY (zipcodes_id )
REFERENCES zipcodes (id )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
Example of data in a single table
CREATE TABLE IF NOT EXISTS otherRecord (
id INT UNSIGNED NOT NULL AUTO_INCREMENT ,
data VARCHAR(45) NULL ,
address VARCHAR(45) NULL ,
city VARCHAR(45) NULL ,
state VARCHAR(45) NULL ,
zipcode VARCHAR(45) NULL ,
county VARCHAR(45) NULL ,
longitude DECIMAL(9,6) NULL ,
latitude DECIMAL(9,6) NULL ,
timezone VARCHAR(45) NULL ,
PRIMARY KEY (id) )
ENGINE = InnoDB;