Автор Тема: Велосипедная СУБД  (Прочитано 8417 раз)

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Велосипедная СУБД
« : Август 28, 2012, 01:57:31 pm »
Однажды понадобилось иметь персистентную коллекцию неких записей. В процессе работы программы записи могут изменяться, удаляться, добавляться. Держать для неё отдельную СУБД - это как из пушки по воробъям, так что просто завёл файл. Встал вопрос как организовать с ним работу. Я выделил три условия:

1) С одной стороны размер этого файла не очень гигантский в том смысле, что при старте программа зачитывает его целиком в оперативку. Пусть программа стартует медленно, зато работает быстро.

2) С другой стороны его размер достаточно велик для того чтобы при изменении одной или нескольких записей перезаписывать файл целиком сбрасывая все записи из оперативки на диск. Жесткий диск может интенсивно использоваться другими программами работающими на этом же компьютере, поэтому полная перезапись файла может занять несколько секунд.

3) Если во время записи в файл произойдёт авария (выключение питания, падение программы), то данные не должны серьёзно испортиться. При рестарте программа перечитывая файл должна сама исправить ошибки в файле.

Хотелось бы узнать кто как поступил бы в этой ситуации.

Я организовал работу с этим файлом так.
Каждая запись снабжается уникальным идентификатором. Данные в файле представляют собой набор команд двух типов:
1) добавить или перезаписать запись с таким-то идентификатором такими-то значениями,
2) удалить запись с таким-то идентификатором.
Программа стартует, читает файл и выполняет команды; после выполнения всех команд в оперативной памяти получается итоговый набор записей. Когда в процессе работы программы какая-то запись удаляется, то в конец того файла дописывается команда "удалить запись с таким-то идентификатором". Когда какая-то запись добавляется или изменяется, то в конец файла дописывается команда "добавить или перезаписать запись с таким-то идентификатором такими-то значениями". То есть во время работы программы в файл дописываются только изменения -- это очень быстро (правда занимает больше места на диске). Важно что запись всегда идёт только в конец файла. Если во время записи данных в файл произойдёт авария, то при рестарте программа дочитав до этого места обнаружит ошибку в формате данных и перезапишет файл автоматически удалив эту ошибку. Ошибка может быть только в конце файла! Если при старте программа прочитав файл обнаруживает, что количество команд в нём более чем в два раза превышает итоговое количество записей, то она перезапишет файл (тем самым уменьшит его размер более чем в 2 раза). Перезапись осуществляется естественно сначала во временный файл, а затем выполняется (как бы атомарная) замена старого файла новым.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #1 : Август 28, 2012, 02:10:00 pm »
Однажды понадобилось иметь персистентную коллекцию неких записей. В процессе работы программы записи могут изменяться, удаляться, добавляться. Держать для неё отдельную СУБД - это как из пушки по воробъям, так что просто завёл файл.
...
Хотелось бы узнать кто как поступил бы в этой ситуации.

А чем вас не устроила SQLite? Она ведь как раз для подобных целей разработана...
Конфигурации не требует, привязка простейшая, надёжность хранения данных высокая...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #2 : Август 28, 2012, 03:04:59 pm »
Хотелось бы узнать кто как поступил бы в этой ситуации.
Я бы посмотрел на jdbm3/4. Если бы у меня была java, я бы это использовал as is, если бы что-то другое, я бы поковырялся в исходниках на предмет интересующих меня деталей реализации.

Это работает всяко быстрее чем любая реляционная СУБД.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Велосипедная СУБД
« Ответ #3 : Август 28, 2012, 03:09:58 pm »
Да, кстати, запись команд в конец файла делаю не при каждом изменении данных, а не чаще чем два раза в секунду. Чаще сохранять особого смысла нет так как у других частей системы латентность больше.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #4 : Август 28, 2012, 03:22:49 pm »
Да, кстати, запись команд в конец файла делаю не при каждом изменении данных, а не чаще чем два раза в секунду. Чаще сохранять особого смысла нет так как у других частей системы латентность больше.
Запись в конец файла можно делать каждый раз, а вот fflush делать раз в секунду/две а на fsync забить вообще.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Велосипедная СУБД
« Ответ #5 : Август 28, 2012, 03:45:10 pm »
Ваше описание, Сергей, напоминает ранние версии Btrieve

add Тут описание: http://emanual.ru/download/5195.html
« Последнее редактирование: Август 28, 2012, 03:47:02 pm от ilovb »

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Велосипедная СУБД
« Ответ #6 : Август 28, 2012, 04:21:44 pm »
А еще возможно Microsoft Compound подойдет
http://www.openoffice.org/sc/compdocfileformat.pdf

В винде вроде даже API для работы с ними есть. Да и самописные библиотеки думаю можно найти

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #7 : Август 28, 2012, 04:59:59 pm »
Не понимаю, зачем все эти велосипеды -- jdbm-ы всякие, компаунды...
Есть же промышленный стандарт для таких вещей -- SQLite -- чуть ли не в каждом смартфоне, на большинстве компов установлена -- мало кто об этом просто знает...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Велосипедная СУБД
« Ответ #8 : Август 28, 2012, 05:09:44 pm »
В общем да. SQLite наверно лучший вариант.

Но если хочется самому написать, то я бы делал что-то вроде Btrieve :)

alexus

  • Гость
Re: Велосипедная СУБД
« Ответ #9 : Август 28, 2012, 05:20:58 pm »
Я организовал работу с этим файлом так.
Каждая запись снабжается уникальным идентификатором. Данные в файле представляют собой набор команд двух типов:
1) добавить или перезаписать запись с таким-то идентификатором такими-то значениями,
2) удалить запись с таким-то идентификатором.
Программа стартует, читает файл и выполняет команды; после выполнения всех команд в оперативной памяти получается итоговый набор записей. Когда в процессе работы программы какая-то запись удаляется, то в конец того файла дописывается команда "удалить запись с таким-то идентификатором". Когда какая-то запись добавляется или изменяется, то в конец файла дописывается команда "добавить или перезаписать запись с таким-то идентификатором такими-то значениями". То есть во время работы программы в файл дописываются только изменения -- это очень быстро (правда занимает больше места на диске). Важно что запись всегда идёт только в конец файла. Если во время записи данных в файл произойдёт авария, то при рестарте программа дочитав до этого места обнаружит ошибку в формате данных и перезапишет файл автоматически удалив эту ошибку. Ошибка может быть только в конце файла! Если при старте программа прочитав файл обнаруживает, что количество команд в нём более чем в два раза превышает итоговое количество записей, то она перезапишет файл (тем самым уменьшит его размер более чем в 2 раза). Перезапись осуществляется естественно сначала во временный файл, а затем выполняется (как бы атомарная) замена старого файла новым.
Посмотрите на Firebird в embedded варианте. Полноценная СУБД... в Вашей программе для 32- и 64-битного варианта.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #10 : Август 28, 2012, 06:07:13 pm »
Не понимаю, зачем все эти велосипеды -- jdbm-ы всякие, компаунды...
Есть же промышленный стандарт для таких вещей -- SQLite -- чуть ли не в каждом смартфоне, на большинстве компов установлена -- мало кто об этом просто знает...
Потому, что sqlite во-первых жуткий тормоз, во-вторых дико сложен (относительно поставленной задачи), в-третьих не thread safe.

Любая sql-СУБД жуткий тормоз относительно jdbm и ему подобным.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #11 : Август 28, 2012, 06:31:51 pm »
По поводу решения Сергея:

когда-то сделал за вечер версионное хранилище контента для Web-сервера на таком же принципе. Клиент отправлял из настольного редактора обновление контента на некоторый URI (по своему протоколу сообщений), сервер заменял node в памяти и дописывал в файл-журнал. При запуске сервер прогонял журнал.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #12 : Август 28, 2012, 06:44:11 pm »
По поводу решения Сергея:

когда-то сделал за вечер версионное хранилище контента для Web-сервера на таком же принципе. Клиент отправлял из настольного редактора обновление контента на некоторый URI (по своему протоколу сообщений), сервер заменял node в памяти и дописывал в файл-журнал. При запуске сервер прогонял журнал.
Ну, вообще такой "журнал" называется write ahead log, и активно применяется во всяких там mysql и подобных для обеспечения отказоусточивости/транзакционности. (в сам файл базы странички скидываются в весьма ленивом темпе, а вот в этот лог пишутся сразу (+fsync каждые несколько секунд)). Лог не бесконечен по объему, и по сути своей является неким аналогом ring buffer'a.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #13 : Август 28, 2012, 07:02:59 pm »
Или наборот: ваш write-ahead-log называется журнал с опережающей записью, если по-русски. :) Я его обычно называю дельта-журнал.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Велосипедная СУБД
« Ответ #14 : Август 28, 2012, 07:40:29 pm »
Или наборот: ваш write-ahead-log называется журнал с опережающей записью, если по-русски. :) Я его обычно называю дельта-журнал.
Опережающая что? :-)

Если действительно по русски, то это "упреждающая регистрация (записываемых данных)".
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"