我开发了一个mysql数据库,其中包含每个用户的国家,城市和职业。 虽然我可以使用“国家/地区”表格然后将国家/地区的ID插入用户表格,但我仍然需要为其他两个表格寻找完美的方法。
问题在于每个用户的城市和职业都来自输入字段,这意味着用户可以键入“NYC”或“纽约”或“纽约市”以及每个城镇的数百万个其他组合,示例
忽略这个问题是个好主意,创建一个自己的“城镇”表,其中包含用户插入的所有城镇,然后将城镇条目的ID放入用户表中,或者更适合使用VARCHAR用户表中的列“town”并没有规范化有关此关系的数据库? 我想在用户个人资料页面上显示三个表格中的数据。
我担心规范化,因为我不希望在我的数据库中有太多冗余数据,因为它占用了大量空间,如果我使用varchar索引而不是整数索引,查询会更慢(例如据我所知):
由于
答案 0 :(得分:3)
我们遇到了这个问题。我们的解决方案是收集人们使用的各种同义词和包含错字的版本,并将它们明确地映射到已知的规范城市名称。这允许在99%的情况下从用户输入中正确猜出名称。
对于剩余的1%,我们创建了一个新的城市条目,并将其标记为非规范。我们定期查看非规范条目。对于可识别的已知城市,我们将非规范条目重新映射到规范(更新链接记录的FK并添加同义词)。对于一个真正新的城市名称,我们不知道我们将创建的条目保持为规范。
所以我们有这样的事情:
table city(
id integer primary key,
name varchar not null, -- the canonical name
...
);
table city_synonym(
name varchar primary key, -- we want unique index
city_id integer foreign key references(city.id)
);
答案 1 :(得分:0)
通常,数据规范化可以帮助您处理数据并保持简单。如果规范化模式不符合您的需求,您也可以使用非规范化数据。所以这取决于你想要使用的查询。
在没有创建单独的表的情况下,组城市没有很好的解决方案,您可以将每个城市的所有名称保留在单个ID中。因此,最好有3个表:user(user_id,city_id),city(city_id,正确的名称),city_alias(alias_id,city_id,name)。
答案 2 :(得分:0)
最好将数据存储在标准化设计中,其中包含实际,政府认可的城市名称。
@Varela建议该城市的“别名”可能会在这种情况下运作良好。但你必须按照“你输入'Now Yerk'的方式回复一条消息。你或许是指'纽约'吗?”。实际上,你想要得到这些修正......
当然,您应该实际存储的不是城市,而是邮政/邮政编码。表格设计如下:
State:
Id State
============
AL Alabama
NY New York
City:
Id State_Id City
========================
1 NY New York
2 NY Buffalo
Zip_Code:
Id Code City_Id
=========================
1 00001-0001 1
然后只要有地址,就存储对Zip_Code.Id
的引用。您想知道完全用户(声称)属于哪个邮政编码。原因包括:
关于地址验证,还有许多其他事情可以做,包括地理位置,但这是一个基本设计,可以帮助您满足大部分需求(并防止大多数可能的'无效'异常)