用户输入的数据库规范化

时间:2011-09-15 15:44:08

标签: mysql sql database normalization

我开发了一个mysql数据库,其中包含每个用户的国家,城市和职业。 虽然我可以使用“国家/地区”表格然后将国家/地区的ID插入用户表格,但我仍然需要为其他两个表格寻找完美的方法。

问题在于每个用户的城市和职业都来自输入字段,这意味着用户可以键入“NYC”或“纽约”或“纽约市”以及每个城镇的数百万个其他组合,示例

忽略这个问题是个好主意,创建一个自己的“城镇”表,其中包含用户插入的所有城镇,然后将城镇条目的ID放入用户表中,或者更适合使用VARCHAR用户表中的列“town”并没有规范化有关此关系的数据库? 我想在用户个人资料页面上显示三个表格中的数据。

我担心规范化,因为我不希望在我的数据库中有太多冗余数据,因为它占用了大量空间,如果我使用varchar索引而不是整数索引,查询会更慢(例如据我所知):

由于

3 个答案:

答案 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的引用。您想知道完全用户(声称)属于哪个邮政编码。原因包括:

  1. 零售税(无论亚马逊如何发挥作用)。
  2. 送货地址(例如,华盛顿和纽约都有Bellevue。邮政编码不同。)
  3. 社交映射。如果您将其存储为“用户输入”城市,您将无法(轻松)分析数据以找出彼此靠近的用户,更不用说在同一个城市。
  4. 关于地址验证,还有许多其他事情可以做,包括地理位置,但这是一个基本设计,可以帮助您满足大部分需求(并防止大多数可能的'无效'异常)