我正在建立一个庞大的IP地址数据库,其地理位置已连接(国家,城市等)。
现在,我正在使用这个简单的数据库结构:
id || ip_addr || country || city ||
我已经开始构建它了,我已经有近100万条记录了。问题是,许多地址都附加了相同的国家/地区,从数据库中取货变得非常慢。
我在想,如果我这样做:
countryTable :
countryID || countryName ||
cityTable :
cityID || cityName || countryID (for what country the city is in) ||
然后, ipTable :
id || ip_addr || countryID || cityID
它会更快地获取吗?
这种方法是否更有效(它还有其他任何好处)吗?或者我应该坚持我已经拥有的东西?
答案 0 :(得分:2)
是的,将国家和城市迁移到一个单独的表格实际上是一个标准化,是一个非常好的一步。我会更进一步规范化:一个城市位于一个国家,这意味着了解一个你也总是了解这个国家的城市。试试这个:
id || ip_addr || cityID
<强> cityTable:强>
id || cityName || countryID
<强> countryTable:强>
countryID || countryName
不需要在IP表中额外引用国家/地区。请注意,当多个城市具有相同的名称(如Warsaw (Poland),Warsaw (Indiana, US)和dozen others时,此设计不会出现问题 - 数据库中存在重复的名称,但ID不同 - 您可以识别城市通过id - 发生指向相同的名称(但在不同的国家)。
但是,我不明白为什么当唯一id
存在时,您有一个单独的ip_addr
列(前提是单个IP只附加了一个地址)?
ip_addr (ID) || cityID
请记住,IP地址可以而且应该表示为一个数字(某些数据库有内置数据库),所以这样的密钥和人工密钥一样好。
最后,通常将连续的IP范围分配给相同的区域/城市/区域。通过将一系列IP分配给位置而不是每个IP,您将节省大量空间。
答案 1 :(得分:0)
是的,规范化通常可以提高性能。虽然归一化的主要原因通常是数据一致性。但是在某些情况下,非规范化实际上会提高性能。这是在数据仓库和报告中完成的,以减少筛选和撰写查询结果所需的连接数。
这里的一个重要部分是数据库变得更小,更多数据适合RAM。
性能的另一个关键点是让索引支持您的典型查询
如果按城市名称搜索,则应在cityTable.cityName
等上设置索引。这样,数据库可以使用高效搜索找到您的数据,只需读取一些记录,而不是扫描整个数据库。