Почему две базы данных SQLite с одинаковыми данными имеют разные размеры?

У меня есть некоторые финансовые данные по более чем 6600 акциям, хранящиеся в базе данных Foxpro. Я мог загрузить представления базы данных в набор из 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, чтобы преобразовать и объединить 12 из 15 файлов в 5 файлов CSV, затем я объединил их с другими оставшимися 3 файлами .txt в Python и Sqlite, чтобы создать базу данных с 8 таблицами (назовем ее CSV). -derived) с использованием модифицированной версии этого кода (с этой страницы):

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 ]))
  • Now when I examined both sqlite databases, I found the following:
    • The DBF-derived database retained its ID column (although it was not designed as primary key).
    • Столбец идентификатора не сохранился при загрузке в .txt в базе данных, полученной из CSV, поэтому я объявил столбец биржевого тикера первичным ключом.
    • Полученный из DBF файл не был проиндексирован в sqlite.
    • Полученный из CSV файл автоматически индексируется в sqlite.
    • Даты сохранили свой формат даты в базе данных, полученной из CSV, тогда как в базе данных, полученной из DBF, они превратились в количество дней.
    • Основным типом данных, полученным в процессе вертуализации базы данных, полученной из DBF, был REAL, который я также установил в качестве типа данных при создании базы данных, полученной из CSV.
    • Все остальное было идентично, за исключением того, что база данных, полученная из CSV, была на 22% меньше по размеру, чем полученная из DBF, и я озадачен, почему, учитывая, что она проиндексирована и имеет те же данные и тип данных. Две базы данных технически отображают одну и ту же информацию в программе DB Browser.

Любое объяснение, почему разница в размере? Это из-за 3 файлов .txt, которые я не конвертировал в CSV?


person Muhamed Al Khalil    schedule 22.04.2017    source источник


Ответы (1)


Трудно понять, что вы делаете, и особенно, почему вы когда-либо захотите использовать CSV между ними, когда вы можете напрямую получать данные из другой системы баз данных. В любом случае, это ваш выбор, разница, вероятно, заключается в том, что данные VFP DBF с символьными полями имеют конечные пробелы. Скажем, поле из 30 символов, в котором есть одна буква, по-прежнему имеет длину 30. Ваше преобразование в SQLite может не обрезать конечные пробелы, тогда как в файле CSV эти данные уже сохранены как обрезанные. Вероятно, самым простым и надежным способом было бы непосредственное создание таблиц SQLite и заполнение их данными из программы VFP (использование VFP, конечно, не является обязательным, это можно сделать на любом языке).

person Cetin Basoz    schedule 25.04.2017
comment
Спасибо Цетину. Это полезно знать, но я не могу найти никаких конечных пробелов при внимательном изучении полей char из DBF в DP Browser. Что касается того, зачем идти по маршруту CSV, программа, из которой я загружаю данные, позволяет сохранять только в DBF или CSV. У него нет возможности напрямую сохранять в SQLite. Поэтому я должен сначала использовать любой формат, прежде чем конвертировать файлы в SQLite, и пока маршрут CSV кажется более эффективным. - person Muhamed Al Khalil; 26.04.2017
comment
IMHO передача данных с использованием CSV подвержена ошибкам. Всякий раз, когда есть шанс, я бы использовал базу данных для передачи базы данных. В вашем случае DBF - лучший выбор ИМХО. - person Cetin Basoz; 26.04.2017
comment
Еще раз спасибо Цетину. Как ни странно, я обнаружил, что использование DBF приводит к неточностям. Маршрут DBF возвращает даты в виде количества дней (от определенной даты), и некоторые из этих дат были странным образом заменены на NULL, тогда как все даты полностью пережили передачу CSV и представлены в виде MM/DD/YYYY. - person Muhamed Al Khalil; 28.04.2017
comment
Это означает, что вы делаете что-то не так. В системах баз данных (в большинстве, если не во всех) дата (время) хранится в виде чисел. Но когда вы сохраняете, запрашиваете и т. д., драйверы знают, что это дата. Однако с CSV вы должны сказать, что получаете дату в определенном формате. В любом случае, если вы уверены, что CSV хорош, используйте его. - person Cetin Basoz; 28.04.2017