0

我正在建立一个巨大的 IP 地址数据库,并附上它们的地理位置(国家、城市等)。

现在,我正在使用这个简单的数据库结构:

id || ip_addr || country || city ||

我已经开始构建它,并且已经拥有近 100 万条记录。问题是,许多地址都附加了相同的国家/地区,从数据库中获取数据变得非常慢。

我在想,如果我这样做:

国家表

countryID || countryName ||

城市表

cityID || cityName || countryID (for what country the city is in) ||

然后,ipTable

id || ip_addr || countryID || cityID

它会使获取更快吗?

这种方法是否更有效(它还有其他好处)吗?还是我应该坚持我已经拥有的?

4

2 回答 2

2

是的,将国家和城市移到单独的表中,实际上是一种常态化,是非常好的一步。我会更进一步规范化:一个城市位于一个国家,这意味着了解一个城市你也总是了解这个国家。因此试试这个:

id || ip_addr || cityID

城市表:

id || cityName || countryID

国家表:

countryID || countryName

不需要在 IP 表中额外提及国家/地区。请注意,当几个城市具有相同的名称,例如华沙(波兰)华沙(印第安纳州,美国)其他十几个城市时,这种设计没有问题- 数据库中有重复的名称但 id 不同 - 并且您通过 id 识别城市 -碰巧指向相同的名称(但在不同的国家/地区)。

但是我不明白为什么存在id唯一的时候你有一个单独的列ip_addr(假设一个 IP 只附加一个地址)?

ip_addr (ID) || cityID

请记住,IP 地址可以并且应该表示为数字(某些数据库具有内置数据库),因此这样的密钥与人工密钥一样好。

最后,通常将连续范围的 IP 分配给同一地区/城市/地区。通过为位置分配一系列 IP 而不是每个 IP,您将节省大量空间。

于 2012-06-16T15:03:15.867 回答
0

是的,标准化通常会提高性能。尽管规范化的主要原因通常是数据一致性。然而,在某些情况下,非规范化实际上可以提高性能。这是在数据仓库和报告中完成的,以减少过滤和组合查询结果所需的连接数量。

这里的一个重要部分是数据库变得更小,更多的数据可以放入 RAM。

性能的另一个关键点是拥有支持典型查询的索引。
如果您按城市名称搜索,您应该有一个索引cityTable.cityName,等等。这样数据库可以使用有效的搜索找到您的数据,只需读取几条记录,而不是扫描整个数据库。

于 2012-06-16T18:07:26.040 回答