Method2 (M2) (正規化) Table2a UserProfile->UserID,LocationsID Table2b Locations-> LocationsID, City, State, Country
都市、州、および国を ID 番号に置き換えました。場合によっては、これが適切な設計上の決定になることもありますが、常に適切な設計上の決定とは限りません。そしてそれは正規化とは何の関係もありません。(「ID 番号を使用しました」通常形などはありません。)
国際標準がある場合、通常はそれを使用するのが理にかなっています。ISO 3166-1を参照してください。3 文字のコードの方がわかりやすいかもしれません。
-- Untested code.
create table countries (
iso_country_code char(2) not null,
country_name varchar(35) not null,
primary key (iso_country_code),
unique (country_name)
);
create table states (
state_code char(2) not null, -- application-dependent, consider ISO 3166-2
state_abbrev varchar(7) not null,
state_name varchar(35) not null,
iso_country_code char(2) not null,
primary key (state_code, iso_country_code),
unique (state_abbrev, iso_country_code),
unique (state_name, iso_country_code),
foreign key (iso_country_code) references countries (iso_country_code)
);
create table cities (
city_name varchar(35) not null,
state_code char(2) not null,
iso_country_code char(2) not null,
primary key (city_name, state_code, iso_country_code),
foreign key (state_code, iso_country_code)
references states (state_code, iso_country_code)
);
create table UserProfile (
UserID integer not null,
city_name varchar(35) not null,
state_code char(2) not null,
iso_country_code char(2) not null,
primary key (UserID),
foreign key (city_name, state_code, iso_country_code)
references cities (city_name, state_code, iso_country_code)
);
国、州、都市ごとにテーブルを分けると、コンボ ボックスに SELECT ステートメントを簡単に入力できます。数値の「タグ」は必要ありません。これら 3 つのテーブルはすべて重要です。非プライム属性はありません。5NFだと思います。
経験則として、行が存在するかどうかを確認するために行を検索せず、存在しない場合は挿入します。これには、データベースへの 2 回の往復が必要です。
代わりに、行を挿入し、重複している場合に発生するエラーをトラップします。とにかくエラーをトラップする必要があります。複製以外にも、挿入の成功を妨げる可能性のあるものがたくさんあります。