Nie będę mówić o błędach ortograficznych. Ponieważ importujesz dane, błędy ortograficzne są lepiej obsługiwane w tabeli pomostowej.
Spójrzmy na tę nieco uproszczoną wersję.
create table stores
(
store_name varchar(50) primary key,
street_num varchar(10) not null,
street_name varchar(50) not null,
city varchar(50) not null,
state_code char(2) not null,
zip_code char(5) not null,
iso_country_code char(2) not null,
-- Depending on what kind of store you're talking about, you *could* have
-- two of them at the same address. If so, drop this constraint.
unique (street_num, street_name, city, state_code, zip_code, iso_country_code)
);
insert into stores values
('Dairy Queen #212', '232', 'N 1st St SE', 'Castroville', 'CA', '95012', 'US'),
('Dairy Queen #213', '177', 'Broadway Ave', 'Hartsdale', 'NY', '10530', 'US'),
('Dairy Queen #214', '7640', 'Vermillion St', 'Seneca Falls', 'NY', '13148', 'US'),
('Dairy Queen #215', '1014', 'Handy Rd', 'Olive Hill', 'KY', '41164', 'US'),
('Dairy Mart #101', '145', 'N 1st St SE', 'Castroville', 'CA', '95012', 'US'),
('Dairy Mart #121', '1042', 'Handy Rd', 'Olive Hill', 'KY', '41164', 'US');
Chociaż wiele osób mocno wierzy, że kod pocztowy określa miasto i stan w USA, tak nie jest. Kody pocztowe mają związek z tym, jak przewoźnicy jeżdżą swoimi trasami, a nie z geografią. Niektóre miasta przekraczają granice między państwami; trasy z pojedynczym kodem pocztowym mogą przekraczać linie stanu. Nawet Wikipedia to wie , chociaż ich przykłady mogą być nieaktualne. (Trasy dostaw stale się zmieniają.)
Mamy więc tabelę, która ma dwa klucze kandydujące,
- {store_name} i
- {numer_ulicy, nazwa_ulicy, miasto, kod_stanu, kod_zip, kod_kraju_izo}
Nie ma atrybutów niekluczowych. Myślę, że ten stół jest w 5NF. Co o tym myślisz?
Gdybym chciał zwiększyć integralność danych dla nazw ulic, mógłbym zacząć od czegoś takiego.
create table street_names
(
street_name varchar(50) not null,
city varchar(50) not null,
state_code char(2) not null,
iso_country_code char(2) not null,
primary key (street_name, city, state_code, iso_country_code)
);
insert into street_names
select distinct street_name, city, state_code, iso_country_code
from stores;
alter table stores
add constraint streets_from_street_names
foreign key (street_name, city, state_code, iso_country_code)
references street_names (street_name, city, state_code, iso_country_code);
-- I don't cascade updates or deletes, because in my experience
-- with addresses, that's almost never the right thing to do when a
-- street name changes.
Możesz (i prawdopodobnie powinieneś) powtórzyć ten proces dla nazw miast, nazw stanów (kody stanów) i nazw krajów.
Niektóre problemy z Twoim podejściem
Najwyraźniej możesz wprowadzić numer identyfikacyjny ulicy w Stanach Zjednoczonych wraz z identyfikatorem kraju dla Chorwacji. („Pełna nazwa miasta, że tak powiem, to rodzaj faktów, które prawdopodobnie chcesz przechowywać w celu zwiększenia integralności danych. Prawdopodobnie dotyczy to również „pełnej nazwy” ulicy.)
Używanie numerów identyfikacyjnych dla każdego bitu danych znacznie zwiększa liczbę wymaganych złączeń. Używanie numerów identyfikacyjnych nie ma nic wspólnego z normalizacją. Używanie numerów identyfikacyjnych bez odpowiadających im unikalnych ograniczeń w kluczach naturalnych — całkowicie powszechny błąd — pozwala na duplikowanie danych.