Комментарии 54
все её данные надо держать одномоментно в памяти;
А если данных будут десятки гигабайт? Или предполагается запуск на мощных серверах с сотнями гигов ОЗУ? В памяти надо держать то, что необходимо в данный момент.
СУБД типа SQLite не даёт каких-то преимуществ (отпадают базы переписки в почте или мессенджере);
Отпадание баз переписки — это проблема конкретных мессенжеров, кривости рук их разработчиков (вы про Skype?). Сама СУБД тут ни в чем не виновата…
SQLite продвигает свой формат БД как формат документа. По-моему, из-за сложностей программирования с ним имеет смысл работать именно как с СУБД.
Не очень понятно, что в этом плохого. Библиотеки для SQLite есть для многих языков программирования. Расширяемость — вообще не проблема — добавляй новые столбцы в таблицу или создавай новые таблицы. Иерархическая структура данных — в виде реляционной БД. Файл целиком грузить в память не нужно. Вручную разбирать его тоже не нужно, запросами можно получать данные, необходимые именно в этом конкретном месте. Аналогично с записью. Формат файла документирован, достаточно стороних инструментов для его просмотра и редактирования, если будет такая необходимость.
Во-первых, в принципе работа с СУБД сложна, по опыту. Во-вторых, бывают и очень нелюбимы программистами изменения структуры файла — и на XML-то это противное дело, а на БД тем более.
Если программа пишется в одно лицо, и только одно приложение будет шариться по файликам — то да, россыпь файлов ограниченна только фантазиями разработчика.
Но данная лафа кончается, когда к данным необходимо ходить из нескольких модулей одновременно и появляется требование иметь хоть сколько нибудь не противоречивый бекап.
в принципе работа с СУБД сложнаСарказм?
Исходя из п.4, вам оочень стоит рассмотреть SQLite как формат, убирающий большинство проблем с потерями. Поскольку при чтении-записи старые версии программы смогут работать со знакомыми им данными, не убивая старые при перезаписи части информации.
Автор не говорит что «всегда надо данные держать в памяти, а SQLite не дает преимуществ», автор говорит «рассмотрим случай, когда данные надо держать в памяти, в этом случае SQLite не даст нам преимуществ».
Но что, мало прог, где реально всё держим в памяти?
Для небольших программ, например, программ редактирования документов, вполне оправдано держать все в памяти. Но попробуйте, например, в LibreOffice открыть документ на десятки мегабайт — уже почувствуете боль. А если объем данных заранее неизвестен и может быть очень большим — тут нужны иные подходы.
Во-первых, в принципе работа с СУБД сложна, по опыту.
Достаточно будет выучить самые базовые вещи SQL, этого уже хватит для работы. Более сложные конструкции могут и не понадобиться.
Во-вторых, бывают и очень нелюбимы программистами изменения структуры файла — и на XML-то это противное дело, а на БД тем более.
Вот тут не согласен. В случае СУБД вообще нет никакой нужды лезть в структуру файла. Например, добавились новые колонки в таблицу. Один раз делаешь ALTER TABLE при миграции данных на новый формат (да, версионность нужна, куда без нее. Но даже версию можно хранить в БД в отдельной таблицу). Те места в коде, где эти колонки не используются, можно вообще не трогать, там все будет работать по-прежнему. Аналогично с добавлением новых таблиц. То есть ты в принципе не касаешься конкретной физической структуры файла, а работаешь непосредственно с данными.
Сложность работы с СУБД не столько в сложности SQL, сколько в промежуточном слое между программной логикой и обёрткой над СУБД, который генерирует гарантированно корректный SQL и инкапсулирует стандартную логику (то ли ORM, то ли горбушка попроще).
re ORM: если полноценный орм тащить не хочется, то между ним и ручным написанием запросов есть ещё куча готовых промежуточных решений.
В процессе компиляции разве есть экземпляры классов?
И что плохого в так называемом «compile time reflection»?
А вы не пробовали ini файлы? В Delphi их поддержка есть с незапамятных времён. А с некоторых пор даже json поддерживается стандартными классами.
В чём плюс ini по сравнению с sqlite — сразу есть вменяемый (типа CRUD) API, и скорость, как ни странно, в разы выше. Минусы — нет транзакционности из коробки, неэффективно хранение бинарных данных.
Кстати есть отличный формат toml — фактически ini файлы, только стандартизированные.
Если требования человекочитаемости нет, то намного лучше делать свой формат, разумеется, бинарный, не придерживаясь идеологии иных форматов, которые делали с совершенно другими целями и исходя из других соображений. Например, вместо хранения ключей (названий параметров) в строковом виде, можно использовать числовые идентификаторы, а лучше хэши. Это упрощает формат и экономит место. Расширяемость формата обеспечивается попросту тем, что парсер игнорирует незнакомые ключи.
Когда не ограничиваешь себя изначально чужими парадигмами, можно создать формат, превосходно подходящий под свои конкретные задачи, «срезая углы» там, где это допустимо и акцентируя то, что требуется. Важно не стремиться чересчур сильно его обобщить.
Просто игнорировать незнакомые ключи может привести к отображению мусора для просмотрщиков и к испорченному файлу для редакторов. Нужны флаги как в PNG: public/private, safe to ignore, safe to copy.
Если требования человекочитаемости нет, то намного лучше делать свой формат, разумеется, бинарный
Зачем свой? Куча бинарных форматов тоже существует, не надо изобретать велосипед. Например, MessagePack, в котором поддерживаются расширения, древовидные структуры. Он быстрый и компактный.
JSON несколько проще в программировании, чем XML, но всё равно сложен. Плюс затруднено потоковое считывание: JSON различает объекты и массивы, и синтаксис JS говорит, что от перестановки атрибутов результат не меняется.
Попробуйте YAML
Автор написал про YAML. И он кстати значительно сложнее.
Сравните JSON grammar и YAML grammar. Формат описания разный, но общее представление о разнице в сложности, думаю, даёт.
Когда XML конфиг вырос до мегабайт, начал тормозить запуск приложения, я переехал в БД. Самый бюджетный вариант — SQLite. Запуск снова выполняется быстро, конвертировать БД намного проще (т.к. есть куча готовых вариантов в интернетах), дополнительно на уровне БД теперь есть ограничения — нельзя как в текстовые конфиги забить невалидные данные, даже ссылочная целостность уже дает много плюсов.
Из вопросов к автору — что с сохрананием старых настроек в новый файл? Ну т.е. есть у меня приложение версии 10, есть приложение версии 20, и есть конфиг версии 15. Сделать чисто запуск версии 10 на конфиге версии 15 не так сложно, а вот чтобы ещё и работало сохранение настроек без даунгрейда до 10 версии — сложная работа, стоит ли, какие есть хорошие приемы? У меня чаще получается, что 10 перетирает конфиг на 10 версию, 20 обновляет до 20 (потому что он то знает как мигрировать).
ПС: json читабельнее xml, не понял минусов json-а в статье.
Ещё важное преимущество SQlite — файлы вообще говоря сложная штука. Нужно делать сложные трюки вроде копирования файла, записи изменений в временную копию, при сохранении нужно атомарно удалить старый файл и переименовать временный.
Тем временем в SQLite можно просто сделать BEGIN TRAN, изменения делать сразу в БД, а при нажатии кнопки сохранить делать COMMIT.
Если семантика реляционки не подходит, можно сделать либо Entity-Attribute-Value, либо каждый объект хранить в JSON / другом формате в строковом поле в БД, либо в бинарном в protobuf. Даже просто ради написанной за вас транзакционности я бы текстовые файлы не использовал.
Текстовый формат нужен в случае, если файл смотрит/пишет человек.
Не рассмотрены S-expressions (и их возможные вариации).
Инструментов почти нет, довольно неудобная, имхо, штука.
Я в курсе что за формат, я в курсе как он работает, я смогу написать парсер даже сам, если вдруг что. Я больше к тому, что не сильно популярен он, в отличие от кучи других форматов, для которых найдется пяток бесплатных и удобных тулов для всего-всего.
Не могу не поделиться своим разбором форматов данных: https://youtu.be/vBqJWQzPB3Y?list=PLXyFFhv8ucKSC96WOd7Ju2HmEWTA3jPa5&t=5652
В такой ситуации, JSON всё ещё заметно лучше.
JSON придуман, кстати, по другой причине — если источнику данных доверяешь, на JS в две строчки разбирается.
У базы данных преимущество в том, что вам не нужно парсить и заново сериализовывать всю сохранку, если требуется поменять одно единственное поле.
Не освещен вопрос возможности / удобства использования в системах контроля версий — тут SQLite и прочие бинарные форматы жестко проигрывают человекочитаемым.
Непричёсанные мысли по поводу формата сохранения: теория