【问题标题】:Best data-structure/db/binary-format for holding hierarchic elements保存分层元素的最佳数据结构/数据库/二进制格式
【发布时间】:2017-05-22 16:34:49
【问题描述】:

我有以下层次实体:

Country, City, Street.
Every country has cities, every city has streets.

我为我想运行的东西写了伪代码:

handle_country_before(country)
for city in country:
    handle_city_before(city)
    for street in city:
        handle_street_before(street)
        handle_street_after(street)
    handle_city_after(city)
handle_country_after(country)

我尝试了以下方法:

document(noSql) 方法:

我以扁平方式保存了所有数据:

{
    country : { 
        # Country "x1" info corresponding with the street
    },
    city : {
        # City "y1" info corresponding with the street
    },
    street : {
        # street info...
    }
}

{
    country : { 
        # Country "x1" info corresponding with the street
    },
    city : {
        # City "y1" info corresponding with the street
    },
    street : {
        # street info...
    }
}

{
    country : { 
        # Country "x1" info corresponding with the street
    },
    city : {
        # City "y1" info corresponding with the street
    },
    street : {
        # street info...
    }
}

{
    country : { 
        # Country "x1" info corresponding with the street
    },
    city : {
        # City "y2" info corresponding with the street
    },
    street : {
        # street info...
    }
}

{
    country : { 
        # Country "x1" info corresponding with the street
    },
    city : {
        # City "y2" info corresponding with the street
    },
    street : {
        # street info...
    }
}

使用这种方法,我不得不使用下面的伪代码:

    last_country = 0
    last_city = 0
    last_street = 0
    for element in elements:
        if element.country.id != last_country_id:
            if (0 != last_country) :
                handle_country_after(last_country)
            handle_country_before(element.country)
        if element.city.id != city:
            if (0 != last_city) :
                handle_country_after(last_city)
            handle_country_before(element.city)     
        if element.street.id != street:
            if (0 != last_street) :
                handle_country_after(last_street)
            handle_country_before(element.street)           

缺点:我觉得这种方式有点矫枉过正,使用扁平结构不适合我的情况,而且速度非常慢,空间效率低。

SQL 方法:

我将每个实体保存在一个表中:Country、City、Street 并使用以下代码对其进行迭代:

    country_cursor = query('select * from countries')
    for country in country_cursor:
        handle_country_before(country)
        city_cursor = query('select * from cities where parent_country_ref=%s' % (country.id))
        for city in city_cursor:
            street_cursor = query('select * from streets where parent_city_ref=%s' % (city.id))
            ...
            ...
        ...
        handle_country_after(country)

一开始,它看起来是最好的方法。但是随着我添加更多元数据表并且必须使用 JOIN 语句,它变得越来越慢,然后我尝试使用物化视图来加快速度,但得到的结果与使用文档相同。

自定义格式方法:

我尝试以我自己的二进制序列化格式保存信息:

<number of countries>[1st-country-data]<number of citieis>[1nd-city-data]<number of streets>[1st-street-data][2nd-street-data][3rd-street...]...

缺点:这无法扩展,我无法更新信息,我无法获取特定的城市/街道,每次搜索都是 O(n)。

我正在寻找的是一种序列化格式/数据库,它将是:

  1. 能够为现有元素添加/更新字段

  2. 高效的速度、空间和内存

  3. 符合 C 标准(无 CPP)

【问题讨论】:

  • But as I added more metadata tables and had to use JOIN statements it became increasingly slower 为什么要添加更多元数据?为什么需要加入?你用过索引吗?
  • @Lashane,假设每个城市都有一个市长,我还想在迭代时得到该城市的现任市长。我必须做城市和市长的笛卡尔积并选择与城市匹配的市长。
  • 城市能有几个市长?一个市长可以管理多少个城市?
  • @Lashane,市长表也包含了该市的所有前任市长,但只有当前的市长记录参考了该市,该城市不为空
  • 它没有回答我的问题

标签: sql c database design-patterns data-structures


【解决方案1】:

在您的情况下,最快的方法是使用非规范化数据,使用以下信息创建平面文件/表:

country    city    street    current mayor    additional information

数据当然要排序了,当然你不会用heavy去解析json/xml之类的格式,只有纯文本

那么你就可以使用单循环来遍历这个数组了

为了加快迭代速度,您可以尝试将单个文件拆分为具有固定宽度行的多个文件

【讨论】:

  • 此方法与document/materialized view 方法相同
  • @Aviv 是的,几乎相同,这是最快的方法
  • 如果您只想加载所有数据,这只是“最快的”。一旦涉及的数据量超过您机器上的可用内存,它就会出现扩展问题。另外,任何更新都需要重写整个文件。在不知道所有 OP 想要对数据做什么的情况下,我会犹豫是否建议这种方法或任何方法。
  • @JimMischel OP 提供了他想要实现的伪代码
  • 他还在问题的底部提供了一个我在寻找什么列表,其中前两个不是您提出的解决方案所实现的。
猜你喜欢
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 2012-01-22
  • 2015-08-17
相关资源
最近更新 更多