【问题标题】:Why Two Same-data SQLite Databases Have Different Sizes?为什么两个相同数据的 SQLite 数据库大小不同?
【发布时间】:2017-04-22 20:44:11
【问题描述】:

我在 Foxpro 数据库中存储了超过 6600 只股票的一些财务数据。我可以将数据库视图下载到一组 15 个文件中,我首先将其下载到 .dbf 文件中,然后再下载到 .txt 文件中(逗号分隔)。

对于 .dbf 文件集,我使用 Python 和 Sqlite 的空间虚拟化扩展将它们转换为 Sqlite 表,然后将它们合并到一个 8 表数据库中(我们称之为 DBF 派生的)。所以用 c 作为光标:

c.execute("CREATE VIRTUAL TABLE temp_virt USING VirtualDbf({}, UTF-8)".format(file))
c.execute("CREATE TABLE {} AS SELECT * FROM temp_virt;".format(table_name))

对于 .txt 文件,我使用 Pandas 将 15 个文件中的 12 个转换并组合成 5 个 CSV 文件,然后我将它们与 Python 和 Sqlite 中的其他 3 个 .txt 文件相结合,以创建一个 8 表数据库(让我们使用此代码的修改版本(来自此page)将其称为 CSV 派生):

with open(csvfile, "rb") as f:
    reader = csv.reader(f)
    header = True
    for row in reader:
        if header:
            # gather column names from the first row of the csv
            header = False

            sql = "DROP TABLE IF EXISTS %s" % tablename
            c.execute(sql)
            sql = "CREATE TABLE %s (%s)" % (tablename,
                      ", ".join([ "%s text" % column for column in row ]))
            c.execute(sql)

            for column in row:
                if column.lower().endswith("_id"):
                    index = "%s__%s" % ( tablename, column )
                    sql = "CREATE INDEX %s on %s (%s)" % ( index, tablename, column )
                    c.execute(sql)

            insertsql = "INSERT INTO %s VALUES (%s)" % (tablename,
                        ", ".join([ "?" for column in row ]))
  • 现在,当我检查两个 sqlite 数据库时,我发现以下内容:
    • DBF 派生的数据库保留了其 ID 列(尽管它并未设计为主键)。
    • ID 列无法在 CSV 派生数据库中下载到 .txt 后继续存在,因此我将股票代码列声明为主键。
    • 派生的 DBF 未在 sqlite 中编制索引。
    • CSV 派生的在 sqlite 中获得了自动索引。
    • 日期在 CSV 派生数据库中保留其日期格式,而在 DBF 派生数据库中变成天数。
    • 通过虚拟化过程为 DBF 派生的数据库提供的主要数据类型是 REAL,我也将其设置为我的数据类型 创建了 CSV 派生数据库。
    • 除了 CSV 派生的 db 比 DBF 派生的小 22% 之外,其他一切都相同,我不明白为什么 考虑到它已被索引并且具有相同的数据和数据类型。 从技术上讲,这两个数据库在数据库中显示相同的信息 浏览器程序。

关于为什么大小不同的任何解释?是不是因为我没有转换成 CSV 的 3 个 .txt 文件?

【问题讨论】:

    标签: database sqlite csv foxpro dbf


    【解决方案1】:

    很难理解您在做什么,尤其是当您可以直接从另一个数据库系统获取数据时,为什么还要在这两者之间使用 CSV。无论如何,这是您的选择,不同之处可能在于具有字符字段的 VFP DBF 数据具有尾随空格。假设一个 30 个字符的字段,其中有一个字母仍然有 30 的长度。您转换为 SQLite 可能不会修剪尾随空格,而在 CSV 文件中,这些数据已经保存为修剪。 可能最简单和最可靠的方法是直接创建 SQLite 表并用 VFP 程序中的数据填充它们(当然,使用 VFP 不是必须的,可以用任何语言完成)。

    【讨论】:

    • 谢谢切廷。这有助于了解,但在仔细检查 DP 浏览器中源自 DBF 的字符字段时,我似乎找不到任何尾随空格。至于为什么要走 CSV 路线,我从中下载数据的程序只允许以 DBF 或 CSV 格式保存。它没有直接保存在 SQLite 中的功能。因此,在将文件转换为 SQLite 之前,我必须先使用任何一种格式,到目前为止,CSV 路由似乎更有效。
    • 恕我直言,使用 CSV 传输数据容易出错。只要有机会,我就会使用数据库到数据库的传输。在您的情况下,DBF 是一个更好的选择恕我直言。
    • 再次感谢 Cetin。奇怪的是,我发现使用 DBF 会产生误差。 DBF 路由将日期返回为天数(从某个日期开始),其中一些日期奇怪地被替换为 NULL,而所有日期都完全在 CSV 传输中幸存下来,并表示为 MM/DD/YYYY。
    • 这意味着你做错了什么。在数据库系统(如果不是全部的话)中,日期(时间)存储为数字。但是当您存储、查询等时,司机会意识到这是一个日期。但是,使用 CSV,您必须告知您正在获取特定格式的日期。无论如何,如果您确定 CSV 是好的,那么就使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多