LINUX.ORG.RU

Сохранение данных в файл


0

1

Всем привет!

Изучаю CPP и пишу не большую программку, необходимо реализовать сохранение данных в файл. Я сперва взялся за sqlite но мне стало интересно как можно самому организовать подобие бд. SQL не нужен и запросы тоже, только чтение и запись.

struct Person
{
    char *name;
    int age; 
}

Пока два варианта. Сделать name массивом или два файла, один смещения хранит другой данные. Что посоветуете?



Последнее исправление: RA (всего исправлений: 1)

SQL не нужен и запросы тоже, только чтение и запись.

А ACID нужно?

Если не нужно, то можно пользоваться std::fstream или FILE*, возможно в связке с (атомарным по определению) rename.

Если нужно, то таки нужна БД: самодельный велосипед погрязнет в детских ошибках и нюансах работы разных ОС и ФС, и никогда из этой трясины не выберется.

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 2)

Массивом.

А если уж c++, то std::string же.

unfo ★★★★★
()
Ответ на: комментарий от Manhunt

boost::serialization

Человеку, который только начал изучать с++, в буст рановато лезть :)

unfo ★★★★★
()

Изучаю CPP

сишный препроцессор? О_о

sdio ★★★★★
()

Ок, записать некоторое количество байтов не проблема. Проблема в том, что name может быть разной длинны, и присчитывании надо распознать где начинается и заканчивается name и начинается age

RA
() автор топика

man 2 open write close

anonymous
()
Ответ на: комментарий от RA

name может быть разной длинны, и присчитывании надо распознать где начинается и заканчивается name и начинается age

Есть два простых и популярных подхода к распознаванию завершения строки при ее считывании:
* читать символ за символом, пока не встретится специальный символ, которым ты условился обозначать конец строки (например, '\n' или '\0')
* перед строкой явно указывать её размер

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 2)
Ответ на: комментарий от RA

Проблема в том, что name может быть разной длинны, и присчитывании надо распознать где начинается и заканчивается name и начинается age

Еще вариант - приспособить формат твоего файла к использованию высокоуровневых функций типа scanf или istream::operator >> (string &). http://www.cplusplus.com/reference/string/operator>>/

Manhunt ★★★★★
()

Изучаю CPP
как можно самому организовать подобие бд

Лучше бы тебе не распыляться. Разберись с C++, потом хватайся за принципы построения БД. Глубина областей почти соразмерна.

По сабжу: бери сериализацию, если данных не много. Иначе sqlite - самое то.

schizoid ★★★
()
Ответ на: комментарий от RA

длинны
блинны
филинны
путинны
оливье

anonymous
()

Ну конечно dbm. Позволяет хранить структуры данных переменного размера с помощью индекса и затем извлекать структуру либо используя индекс, либо просто
последовательно просматривая файл.

sergijoo
()
Ответ на: комментарий от sergijoo

Ну конечно dbm

+1. А если записи бить на поля, хранить их в базе по отдельности, а саму запись держать как индексные ссылки на поля, то фактически получим «нижнюю часть» SQL машины

MKuznetsov ★★★★★
()
Ответ на: комментарий от Reset

sqlite тоже если данных мало и их не жалко петерять

а какие есть альтернативы? чтоб безсерверный вариант с таким же набором настроек журналирования, синхронизации и возможностью бэкапа налету?

wota ★★
()
Ответ на: комментарий от wota

Нет, яйца совершенно другие. Скорость, десятки и сотни миллионов записей, транзакции, полноценная многопоточность и даже многопроцессность, убить базу практически невозможно, полноценная репликация, а не убогий backup api, тонкий тюнинг всего что только можно затюнить, возможность выглядеть снаружи как stl и sqlite ... огромная куча других полезных фичей. Сравнивать sqlite с berkeley это как сравнивать запорожец с мерседесом — совершенно разного уровня продукты.

Reset ★★★★★
()
Последнее исправление: Reset (всего исправлений: 1)
Ответ на: комментарий от Manhunt

boost::serialization

его можно советовать только в том случае, если данные не пойдут дальше одного экземпляра программы - оно даже при переезде 32/64 разъезжаются.

lazyklimm ★★★★★
()
Ответ на: комментарий от Reset

убить базу практически невозможно

У нас пацаны отказались от BDB как раз из-за того, что база неоднократно билась.

Manhunt ★★★★★
()
Ответ на: комментарий от Reset

Скорость, десятки и сотни миллионов записей
транзакции

нет проблем

полноценная многопоточность

ага, в документации сходу пишется про возможные дедлоки, полноценная многопоточность такая полноценная

убить базу практически невозможно

если не отключать журналирование - аналогично, более того журналирование на скорость практически не влияет

тонкий тюнинг всего что только можно затюнить, возможность выглядеть снаружи как stl и sqlite ... огромная куча других полезных фичей

да ладно заливать, возможностей там гораздо меньше чем у sqlite, где есть пользовательские расширения, «виртуалные» таблицы, SQL( только не надо говорить про возможность использовать sqlite поверх bdb ), тонкая настройка авторизации и разграничения прав, временные объекты, full text search, rtree, поддержка icu, profile, explain, trace, логи и пр и пр.

wota ★★
()
Ответ на: комментарий от Reset

Сравнивать sqlite с berkeley это как сравнивать запорожец с мерседесом

Слишком категорично. BDB может предоставить сопоставимое качество: http://www.sqlite.org/testing.html ?

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Transaction subsystem включали? Я использовал и то и то в продакшене. Некорретное выключение машины, сегфолт процесса, некорректное завершение процесса и т.д. и т.п. и sqlite'у в 50% случаев наступал песец. При этом bdb живет под страшной нагрузкой 24/7 ~1000rps в среднем. База переживала всё начиная от смерти машины и заканчивая выключением дц. Ничего никогда не билось.

Reset ★★★★★
()
Ответ на: комментарий от Reset

Transaction subsystem включали?

Деталей не знаю: трахалась с этим соседняя команда. Знаю только, что пацаны вполне грамотные, не быдло и не лохи, и что радости им BDB не принесла.

Manhunt ★★★★★
()
Ответ на: комментарий от wota

ага, в документации сходу пишется про возможные дедлоки

И там же рядом в документации написано как с ними бороться. Если кратко, то надо правильно приложение проектировать, да и то для криворуких там предусмотрен костыль — deadlock detector.

если не отключать журналирование - аналогично, более того журналирование на скорость практически не влияет

Ога, даже 10k записей в любом случае поставят sqlite колом.

да ладно заливать, возможностей там гораздо меньше чем у sqlite

Всё перечисленное реализуется на уровне приложения так как ты хочешь. Главное, что в bdb базовый функционал сделан отменно. Например, тот же backup в bdb я могу делать по крону _сторонним_ скриптом, который настроят админы как хотят, а в sqlite трах с backup api внутри приложения, который в случае чего поставит колом систему.

Reset ★★★★★
()
Ответ на: комментарий от Manhunt

Видимо использовали bdb по рабоче-крестьянски. То есть открыли один файл без окружений, без опций, и начали в него фигачить :) Ибо только в таком случае база может испортиться безвозвратно.

Reset ★★★★★
()
Ответ на: комментарий от Reset

только в таком случае база может испортиться безвозвратно

Им не нужна «возвратность». Им нужна работоспособность 7*24 под бешеной нагрузкой. Охлаждаемая серверная, межделмашевское железо, избыточные рейд-массивы, дизель на случай пропадания света, квалифицированный обслуживающий персонал. Так вот по факту bdb ломалась, несколько раз за несколько месяцев.

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

У меня оно живет как раз в режиме 24/7. Не ломается. В продакшене под нагрузкой с первого декабря живет. За это время проблемы с сетью и железом были, а с bdb - нет.

Reset ★★★★★
()
Ответ на: комментарий от wota

У меня есть подозрения, что не включали :)

Reset ★★★★★
()
Ответ на: комментарий от Reset

И там же рядом в документации написано как с ними бороться.

здорово

Ога, даже 10k записей в любом случае поставят sqlite колом.

	sqlite3_exec( db, "CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));", 0, 0, 0 );
	sqlite3_exec( db, "CREATE INDEX i1 on T1(a);", 0, 0, 0 );
	sqlite3_exec( db, "CREATE INDEX i2 on T1(b);", 0, 0, 0 );
	
	sqlite3_exec( db, "BEGIN", 0, 0, 0 );
	int i = 0;
	for( i = 0 ; i < 10000 ; ++i )
	{
		char buf[ 512 ];
		sprintf( buf,  "INSERT INTO t1 VALUES(%d,13153,'test');", rand() );
		sqlite3_exec( db, buf, 0, 0, 0 );
	}

	sqlite3_exec( db, "COMMIT", 0, 0, 0 );

0.083сек - прям таки колом

Например, тот же backup в bdb я могу делать по крону _сторонним_ скриптом, который настроят админы как хотят, а в sqlite трах с backup api внутри приложения, который в случае чего поставит колом систему.

http://www.sqlite.org/sqlite.html

просвещайся

wota ★★
()
Ответ на: комментарий от Manhunt

Знаю только, что пацаны вполне грамотные, не быдло и не лохи

Судя по лексикону, у вас там всё не так уж хорошо.

tailgunner ★★★★★
()
Ответ на: комментарий от wota

0.083сек - прям таки колом

Это пока одна табличка и пока оно влезает в память. Когда перестанет всё ляжет и ничего тебя не спасет.

просвещайся

это?

.backup ?DB? FILE      Backup DB (default "main") to FILE

А разве к sqlite можно безопасно подключаться из стороннего процесса пока оно используется?

Reset ★★★★★
()
Ответ на: комментарий от Reset

Ога, даже 10k записей в любом случае поставят sqlite колом.

Если не коммитить после каждого инсерта, то всё будет пучком. Потому как скорость коммита ограничена скоростью вращения жёсткого диска.

PolarFox ★★★★★
()
Ответ на: комментарий от Reset

Это пока одна табличка и пока оно влезает в память. Когда перестанет всё ляжет и ничего тебя не спасет.

	sqlite3_exec( db, "CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100));", 0, 0, 0 );
	
	sqlite3_exec( db, "BEGIN", 0, 0, 0 );
	int i = 0;
	for( i = 0 ; i < 10000000 ; ++i )
	{
		char buf[ 512 ];
		sprintf( buf,  "INSERT INTO t1 VALUES(%d,13153,'test');", rand() );
		sqlite3_exec( db, buf, 0, 0, 0 );
	}

	sqlite3_exec( db, "COMMIT", 0, 0, 0 );

45сек, т.е. на 10млн записей обвала нет, для чего-то большего логично брать тот же postgre, чтоб раскидывать нагрузку и трафик по серверам

А разве к sqlite можно безопасно подключаться из стороннего процесса пока оно используется?

не только можно, но sqlite еще и кэш расшарит

wota ★★
()
Ответ на: комментарий от wota

0.083сек - прям таки колом

При разрастании базы до десятков гигабайт, sqlite и правда встаёт на колени. Вот что об этом написано у них на сайте: «Develop a new sort implementation that does much less disk seeking. Use to improve indexing performance on large tableshttp://sqlite.org/cvstrac/wiki?p=ToDo

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

При разрастании базы до десятков гигабайт

на таких объемах я б точно sqlite не использовал

wota ★★
()
Ответ на: комментарий от lazyklimm

его можно советовать только в том случае, если данные не пойдут дальше одного экземпляра программы - оно даже при переезде 32/64 разъезжаются.

Прозреваю, что ты делаешь что-то не так. В design goals boost::serialization явно указано: «Data Portability - Streams of bytes created on one platform should be readable on any other.» http://www.boost.org/doc/libs/1_50_0/libs/serialization/doc/index.html

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

Manhunt ★★★★★
()
Ответ на: комментарий от Manhunt

Просто у тебя embedded головного мозга.

Просто я бреду по колено в Ъ-ынтерпрайз кодерах, и у каждого как минимум звание мастера спорта по Си++. ТС спрашивает «как бы мне сохранить структурку с двумя полями?», а через десяток постов начинается: «sqlite или смерть^W XML!!11», «dbm или смерть!!!11», «bdb и смерть вам, неверные!!!11», «ваш sqlite говно, он даже сотню гиг не тянет!!11». При всей любви к Ъ-ЛОР-стайл дискуссии - выдыхайте уже, бобры.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

ТС спрашивает «как бы мне сохранить структурку с двумя полями?»

а потом к структурке добавится еще одно поле, или изменится тип данных - и твоя простая и удобная картина мира вдруг потускнеет, а потом окажется, что записей таки будет много и/или их потеря будет критичной - и станет совсем мрачно

а через десяток постов начинается

дык не читай

wota ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.