Задать вопрос
Пользователь пока ничего не рассказал о себе

Наибольший вклад в теги

Все теги (3)

Лучшие ответы пользователя

Все ответы (9)
  • Создаю таблицу в sql lite в обычном варианте, и в варианте c WITHOUT ROWID получается огромная разница в размерах. Почему размеры так отличаются?

    @kuza2000 Автор вопроса
    В общем, разобрались.
    Когда размер блоба превышает определенный порог, он переносится на overflow pages. Это отдельная страница или несколько. Больше одного блоба на странице переполнения быть не может. А вот на странице данных (в записях) могут быть много блобов.

    Вот тут, в разделе 1.6 описаны пороги, при превышения которых блоб переносится на страницы переполнения: https://www.sqlite.org/fileformat.html

    Вот главная формула:
    X is U-35 for table btree leaf pages or ((U-12)*64/255)-23 for index pages.

    Тут U - это размер страницы. Размер страницы у меня 4096, получается, порог переноса будет 4096 - 12 = 4084 для листовой страницы и ((4096-12)*64/255)-23 = 1002 для страницы указателей. Это полный размер записи. За вычетом размера блоба остальная часть записи - 5 байт (подглядел в дампе страницы базы). Значит, пороги переноса блоба будут 4079 и 997.

    Провел эксперименты с разным размером блоба. База с WITHOUT ROWID перестает пухнуть при размере блоба 996 байт. А 997 - уже проблема. Вывод: в таблицах с WITHOUT ROWID применяется порог для блобов, который предназначен для страницы индекса.

    Вообще, ничто не мешает хранить блобы большего размера на страницах таблиц с WITHOUT ROWID. Вполне возможно, что это ошибка, которую позже поправят. Но пока в sql lite в таблицах с WITHOUT ROWID блобы лучше не хранить.

    UPD:
    Спросил у на форуме sql lite, ответили разработчики: https://www.sqlite.org/forum/forumpost/ad86fbaa04
    Как справедливо поправили - блобы тут не причем, имеет значение общий размер записи (payload). Ответили, что таблицы WITHOUT ROWID сделаны как покрывающие индексы, и унаследовали соответствующие ограничения. В общем, на мой взгляд, не стоит их использовать, если может произойти spliting. Для этого общий размер записи не должен приближаться к 1/4 размера страницы.
    Ответ написан
    Комментировать
  • Как в Python присвоить объекту класс, если имена классов хранятся в списке?

    @kuza2000
    Можно создавать свои классы на лету, используя type. Для этого ее нужно вызвать с тремя параметрами, вместо одного:
    new_class = type('Model1', (), {})
    Теперь в new_class лежит именно класс с именем Model1. После этого создаете объекты класса Model1:
    a_model1 = new_class()
    Я не знаю, как вы используете эти классы, но посмотрите 2-й и 3-й параметр type. Там можно указать родительский класс и инициализировать сразу свойства класса.
    Ответ написан
    Комментировать

Лучшие вопросы пользователя

Все вопросы (3)