如何将数据集A规范化为数据集B?

时间:2013-07-11 17:47:25

标签: dictionary location dataset mapping normalization

我有两个位置数据数据集;一个是创建的数据集,其中包含世界上每个城市的列表,另一个是来自用户输入的位置数据。

我想将所有用户输入数据映射到完整数据集。例如,用户输入数据可能有多行:

  • 旧金山
  • San Fran
  • SF

我想将所有这些行映射到旧金山,它位于完整的数据集中。

您会推荐哪些程序,方法,工具等?我想到了正则表达式,但我不知道如何自动化它以便能够搜索所有不同的城市。

澄清:计算机将无法知道SF之类的东西是否应该代表旧金山,这取决于人类的判断。一般来说,我正在寻求有关如何解决此问题的帮助。我不知道如何将一组映射到另一组,这就是我坚持的部分

1 个答案:

答案 0 :(得分:0)

抱歉,我花了这么长时间才回来 - 我自私地去那里度假!如果你还在努力:

好的,基础知识。假设您有一个名为“place”的表和一个名为“city”的字段。您可以使用“like”运算符对第一个很多字符进行简单匹配。

select <whatever> from place where city like 'San Fran%';

你可能想忽略大小写,所以“san fran”将与旧金山相提并论。在那种情况下:

select <whatever> from place where upper(city) like upper('San Fran%');

当然,在现实生活中,你不会硬编码“San Fran”,它将是一个运行时参数。

在城市上创建一个索引,这将非常快。如果使用“upper”使其不区分大小写,则在upper(city)上创建索引。

好的,所以你也想处理另一个案例:缩写,比如旧金山的“SF”。

您没有说出您正在使用的SQL的风格。如果它支持函数,您可以编写一个函数,从任何名称形成缩写。该函数可以使用子字符串扫描名称的字符(或者您的SQL具有的任何等价物 - 我认为这些函数不是很标准),查找空格,然后拉出第一个字符,然后是空格后面的每个字符,然后回来。假设您将此函数称为“abbreviate()”。然后查询将是:

select <whatever> from place where upper(city) like concat(@city,'%') or abbreviate(city) = @city;

(以上是MS SQL Server中的内容,其中参数的名称以“@”开头。)

然后,您将在上部(城市)和缩写(城市)上创建索引以保持快速。

如果你想比这更灵活,那么,我认为没有办法考虑你想要处理的每一个案例。就像你希望用户能够输入“frisco”并找到旧金山或“拉斯维加斯”来获得拉斯维加斯一样,你可以在城市名称的任何地方搜索输入的字符串,即“像'frisco%'这样的城市” ”。但是有两个大问题。一,我认为你会得到很多虚假的命中,其中许多可能对用户来说相当神秘。喜欢“san”类型,不仅可以获得“旧金山”和“圣地亚哥”,还可以获得“加州千橡市”。 (请参阅thouSANd中的“san”)。二,当LIKE子句以通配符开头时,SQL无法使用索引,因此这样的搜索意味着每次都要进行全文扫描。如果你希望在用户输入“大苹果”时进入“Beantown”或纽约时找到波士顿,那么你就处于一个完全不同的领域。

如果你想要各种各样的变体,我想你需要一个昵称表。在这种情况下,我会创建一个“地方”表,其中不包含地点的名称。然后创建一个place_name表,其中包含您要接受的名称的所有变体。在place_name和place之间创建多对一关系。在place_name中包含一个字段,用于标识哪个是“主要名称”。然后查询变为:

select n2.name, p.place_id, <whatever>
from place_name n 
join place p on n.place_id=p.place_id
join place_name n2 on n2.place_id=n.place_id and n2.is_primary=1
where n.name like concat(@name,'%') or abbrev(n.name)=@name;

对于只有一个名称的地方,该地方只有一个place_name记录。

我说要将所有名称放在place_name表中,而不仅仅是替换名称,这样您只需搜索一个表而不是两个表来查找该位置。它简化了人类阅读器和数据库引擎的查询。