Perst — An open source, object-oriented embedded database
Высокопроизводительная объектно-ориентированная встраиваемая база данных от компании McObject.
Поддерживаемые платформы
- J2SE 1.4 and выше
- Android (Open Handset Alliance)
- J2ME MIDP 2.0/CLDC 1.1
- .NET Framework (1.0, 2.0, 3.0, 3.5)
- .NET Compact Framework (1.0, 2.0)
- Mono
Основные возможности
- Хранит данные непосредственно в объектах Java и .NET, исключая время на преобразование необходимое реляционным и объектно-ориентированным БД
- Компактная (сборка для .NET весит всего чуть больше 500 кб)
- Поддержка транзакций
- Легко используемые инструменты разработки (ниже приведен код, по которому вы сможете это оценить)
- Есть возможность использовать SQL-подобный язык запросов (для .NET 3.5 можно использовать LINQ)
- Экспорт в XML
- Репликация
- Полнотекстовый индекс (скорость индексации конечно не сравниться со Sphinx или Lucene, но все же для некоторых задач сгодиться)
- Шифрование базы при помощи алгоритма RC4
- Быстрая система восстановление БД после сбоев (без использования log-файлов)
- с остальными возможностями вы можете ознакомиться на странице спецификации Perst
Лицензия
Двойная: либо GNU General Public License version 2, либо если вас не устраивает GNU GPL v2 есть коммерческая.
Быстродействие
На официальном сайте выложены тесты от двух компаний PolePosition и TestIndex. PolePosition производит сравнение Perst с db4o, о которой не раз упоминали на Хабре. Результат, как вы наверно догадались, Perst быстрее. Такой же результат сообщает нам TestIndex, проводившая тестирование на эмуляторе Android и смартфоне T-Mobile G1 сравнивая Perst c SQLite. Pdf-ки с графиками можно скачать с официального сайта.
Пример на С#
Тут действительно все просто — все объеты (классы), которые необходимо хранить в базе данных Perst наследуются от класса Persistent. Создадим класс простой класс данных:
- /// <summary>
- /// Класс для хранения данных.
- /// </summary>
- class MyData : Persistent
- {
- public int intKey;
- public string strData;
- }
* This source code was highlighted with Source Code Highlighter.
Теперь нам необходимо создать класс который будет создавать нужные нам индексы, а также являться корневым элементом базы данных.
- /// <summary>
- /// Корневой элемент базы данных.
- /// </summary>
- class MyRoot : Persistent
- {
- /// <summary>
- /// Индекс по полю intKey в класе MyData.
- /// </summary>
- public FieldIndex<int, MyData> intKeyIndex;
-
- public MyRoot(Storage db)
- : base(db)
- {
- intKeyIndex = db.CreateFieldIndex<int, MyData>("intKey", false); // False обозначает неуникальность ключа.
- }
- public MyRoot()
- {
- }
- }
* This source code was highlighted with Source Code Highlighter.
Ну, а теперь там осталось только подключиться к базе и работать с ней. Заодно проведем тестирование быстродействия.
- class Program
- {
- static void Main(string[] args)
- {
- DateTime t1;
- DateTime t2;
- Storage db = StorageFactory.Instance.CreateStorage();
- MyRoot Root;
- MyData Obj;
- MyData[] ObjList;
-
- // Выделим Perst 10Мб оперативной памяти для работы с базой, что бы немного снизить нагрузки на диск и
- // увеличить скорость.
- db.Open("MyDB.pdb", 10 * 1024 * 1024, "My_SecreT_k3y");
- // Если в базе еще нет корневого элемента, создадим его.
- if (db.Root == null)
- {
- db.Root = new MyRoot(db);
- }
- Root = (MyRoot)db.Root;
-
- // Добавим объект MyData в базу.
-
- t1 = DateTime.Now;
- for (int i = 0; i < 100000; i++)
- {
- Obj = new MyData();
- Obj.intKey = i;
- Obj.strData = "Привет, мир!!!";
- Root.intKeyIndex.Put(Obj);
- }
- t2 = DateTime.Now;
- Console.WriteLine((t2 - t1).TotalMilliseconds.ToString() + " ms");
-
- // Теперь попробуем его получить.
- //Т.к. мы создали индекс с неуникальным ключом, то воcпользуемся перегруженой функцией Get(from, till).
- ObjList = Root.intKeyIndex.Get(1000, 1000);
- foreach (MyData Obj1 in ObjList)
- {
- Console.WriteLine(Obj1.strData);
- }
-
- db.Close();
- }
- }
* This source code was highlighted with Source Code Highlighter.
На моем ноуте создание 100000 объектов выполняется за 2.4сек, т.е. ~42к записей в сек.Вывод
Perst действительно быстрая и компактная ООБД, которая подойдет не только для вашего приложения для PC, но и для мобильных устройств.
Но можно ли ее применить на сайтах спросите вы? Ответ будет таков: в туториале заявлена поддержка мульти-клиентского приложения, используя для этого ThreadTransaction и свойство БД perst.multiclient.support, но мне так и не удалось добиться высокой производительности (10 потоков создают по 10 записей выполнялось 21сек). Скорее всего я что, то не так делаю?! В любом случае исходники я выложу, что вы смогли меня поправить и сами потестировать.