Method2 (M2)(Normalized) Table2a UserProfile->UserID,LocationsID Table2b Locations-> LocationsID, City, State, Country
您已将城市、州和国家/地区替换为 ID 号。虽然在某些情况下这可能是一个好的设计决策,但它并不总是一个好的设计决策。它与规范化无关。(没有“我使用了身份证号”这样的正常形式。)
当有国际标准时,使用它通常是有意义的。参见ISO 3166-1。三字母代码可能更有意义。
-- 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 语句填充组合框变得容易。他们不需要数字“标签”。这三个表都是关键;它们没有非主要属性。我认为他们在 5NF 中。
根据经验,不要搜索一行来查看它是否存在,如果不存在则插入。这需要两次往返数据库。
相反,只需插入该行,并捕获重复的错误。无论如何,您都必须捕获错误——除了重复之外,还有很多事情可以阻止插入成功。