为什么两个相同数据的SQLite数据库有不同的大小?

时间:2017-04-22 20:44:11

标签: database sqlite csv foxpro dbf

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

对于.dbf文件集,我使用带有Python和Sqlite的spaceite虚拟化扩展将它们转换为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个表的数据库(让& #39; s称之为CSV派生的)使用此代码的修改版本(来自此page):

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-derived在sqlite中获得自动索引。
    • 日期在CSV派生的数据库中保留了日期格式,而在DBF派生的数据库中它们变成了若干天。
    • 通过DBF派生的数据库的垂直化过程得到的主要数据类型是REAL,我也将其设置为数据类型为I 创建了CSV衍生的数据库。
    • 所有其他方面都是相同的,只是CSV衍生的db的大小比DBF派生的小22%,我很困惑为什么 考虑到它已被索引并具有相同的数据和数据类型。 这两个数据库在技术上在DB中显示相同的信息 浏览器程序。

有关为何大小差异的任何解释?是不是因为我没有转换为CSV的3个.txt文件?

1 个答案:

答案 0 :(得分:1)

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