Я не собираюсь говорить с орфографическими ошибками. Поскольку вы импортируете данные, орфографические ошибки лучше обрабатываются в промежуточной таблице.
Давайте посмотрим на эту слегка упрощенную версию.
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');
Хотя многие люди твердо уверены, что почтовый индекс определяет город и штат в США, это не так. Почтовые индексы связаны с тем, как курьеры управляют своими маршрутами, а не с географией. Некоторые города пересекают границы между штатами; Маршруты с одним почтовым индексом могут пересекать государственные границы. Даже Википедия знает это , хотя их примеры могут быть устаревшими. (Маршруты доставки меняются постоянно.)
Итак, у нас есть таблица с двумя ключами-кандидатами,
- {store_name} и
- {street_num, street_name, city, state_code, zip_code, iso_country_code}
У него нет неключевых атрибутов. Я думаю, что эта таблица в 5NF. Что ты думаешь?
Если бы я хотел повысить целостность данных для названий улиц, я мог бы начать с чего-то вроде этого.
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.
Вы можете (и, вероятно, должны) повторить этот процесс для названий городов, названий штатов (кодов штатов) и названий стран.
Некоторые проблемы с вашим подходом
Вы, очевидно, можете ввести номер идентификатора улицы для улицы, которая находится в США, вместе с идентификатором страны для Хорватии. («Полное название» города, так сказать, это тот факт, который вы, вероятно, хотите сохранить, чтобы повысить целостность данных. Это, вероятно, также относится к «полному названию» улицы.)
Использование идентификационных номеров для каждого бита данных значительно увеличивает количество требуемых объединений. Использование идентификационных номеров не имеет ничего общего с нормализацией. Использование идентификационных номеров без соответствующих уникальных ограничений на естественные ключи - совершенно распространенная ошибка - позволяет дублировать данные.