Метка: database

  • Заметка об экспериментах со SnappyDB (NoSQL KeyValue DB под Android)

    Небольшая заметка про SnappyDB. Это NoSQL база данных под Android, которая базируется на LevelDB и алгоритме сжатия Snappy.

    LevelDB – это key-value база данных. Написана Google-ом для каких-то своих мега проектов.
    Snappy – метод сжатия данных, сбалансированный на скорость (т.е. приоритет быстрота, а не степень сжатия). Также написана Google-ом.

    Авторы SnappyDB на своем блоге приводят очень привлекательный график сравнивая скорость работы SnappyDB с SQLite.

    Все это конечно очень и очень заманчиво, но лично меня она заинтересовала не поэтому. Дело не в скорости и даже не в том, что какие-то части этой БД делал Сам Google, а в более-менее нормальном API.

    На практике у меня пока не возникали задачи, в которых нужно было обрабатывать на мобильных устройствах (а я напомню это именно БД для Android) терабайты данных. При этом хранить различные небольшие справочники, настройки, профили и прочую ерунду приходится регулярно.

    Конечно по-хорошему можно использовать API Preferenes или SQLite, но в некоторых случаях это не очень удобно.
    В частности у SQLite несколько громоздкий API, а в preferences нет удобных методов для сложных выборок по ключам.

    Упоминая более-менее нормальное API я имел в виду следующее. Вот что нужно сделать чтобы получить значение по ключу в Preferences (Android API).

      SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
      String username = sharedPref.getString("name", "");
    

    Вот что нужно сделать чтобы получить значение по ключу в Snappy DB.

      DB db = DBFactory.open(context); 
      String username =  db.get("name");
    

    Другими словами, API не такое “многословное” как стандартное Android API.

    При этом если есть несколько записей (“name:0″,”name:1″,”name:2” и т.д.), то их можно получить как-то так:

      db.findKeys("name:");
    

    Такое “из коробки” в Preferences сделать пока невозможно.

    Поэтому мне показалось, что Snappy DB это удобно. Можно использовать например в таких задачах как:
    – Сохранить справочников кодов и их описание
    – Запоминать время работы каких-то специальных команд или хранить данные по мониторингу
    – Идентификатор пользователя и его профиль (например в XML или JSON формате)

    В общем все было хорошо, пока не наткнулся на одну приставку под Android TV, на которой был установлен Android M. Так вот, на этом устройстве Snappy DB внезапно стала работать с ошибками. Поскольку БД нативная, а желания дебажить сишный код у меня в последнее время нет, пришлось отказаться от ее использования в текущих проектах.

  • Заметки по Derby DB

    Нельзя сказать, что к Derby DB у меня особо теплые отношения. Первое знакомство с ней произошло много лет назад, когда на работе возникла идея прикрутить Derby вместо полноценной базы данных, чтобы проще было готовить демку программы к выставке. Идея была в том, что если взять легковесную встраиваемую базу, то тогда развертывание демонстрационного дистрибутива сильно упростится — скопировал файлики и ничего настраивать не нужно (в отличие от Оракла). В случае если нам нужен всего-лишь выставочный демонстрационный образец ПО такое решение было вполне оправдано. Почему выбор пал в тот момент именно на дерби думаю сейчас мало уже кто вспомнит.
    В итоге конечно всё прикрутить получилось, но скорость работы базы на тот момент оставляла желать лучшего. Возможно где-то я был не прав (был молодым и неопытным), а возможно и сама база была “юной” и не достаточно расторопной. derby_db_logo

    С тех пор прошло много времени, Derby уже давно поставляется вместе с JDK под именем Java DB, поэтому думаю в жизни многих Java-программистов также возникали случаи совместной работы с этой удивительной базой данных. Собственно поэтому решил описать некоторые её капризы и особенности. Сразу хочу заметить, что эту БД использую в жизни не так часто и возможно именно поэтому ее поведение меня иногда удивляет.

    1.Кидается исключениями при отключении.

    Чтобы отключить БД в embedded режиме, нужно в JDBC-URL прописать “jdbc:derby:;shutdown=true”. Если всё нормально, в вас обязательно при отключении кинут исключением SQLException с кодом XJ015. К этому нужно привыкнуть и не пугаться.

    2.Режим использования RAM (In-memory).

    У Derby есть не плохой экспериментальный режим, когда она работает в памяти.
    Удобно использовать для создания временного окружения (чтобы не удалять созданные файлы и директории) или в различных jUnit-тестах.
    Опять таки все делается через URL, например для создания пишем: “jdbc:derby:memory:myDB;create=true”.

    При этом если вы сделаете shutdown, но не потушите JVM, то ваша БД не почистится. Чтобы удалить данные из памяти нужно сделать сделать drop (jdbc:derby:memory:myDB;drop=true), который сам сделает shutdown:
    You can shut down an in-memory database using the shutdown=true attribute before you drop the database, but this is optional. Dropping the database also performs the shutdown.

    3.JRE7u51

    В JRE7u51 поменялись ограничение в настройках безопасности. Поэтому при запуске дерби в сетевом режиме могут валиться исключения AccessControlException.
    На официальной странице oracle предлагается решение, в котором необходимо настроить собственный security.policy файл, чтобы в нем был доступ к порту (по-умолчанию 1527). Например так:

    grant {
        permission java.net.SocketPermission "localhost:1527", "listen";
    };
    

    Хорошая пошаговая инструкция на странице администрирования.

  • OrderBy или OrderColumn

    Между JPA аннотациями OrderBy и OrderColumn существует огромная разница. (далее…)

  • oracle xe + ru. >_< Rrrr!

    Нужно было поставить Oracle XE на Windows XP (RU).
    Все нормально качается с официального сайта.
    Установка супер-простая (по сравнению с обычной установкой оракла).

    Пользователь по-умолчанию: system
    SID по-умолчанию: XE
    Панель управления доступна через на порту 8080.

    Админка работает, SQLPlus подключается и уже казалось, что счастье так близко.

    Если вы попытаетесь подключиться через JDBC, напоритесь на эпохальный баг с NLS.
    Достаточно в Google вбить: oracle xe nls и вы увидите огромное множество советов по решению этой проблемы.
    Вариантов уйма: править в реестре, менять локаль, выполнять магические команды в оракле, использовать специальный jdbc-драйвера от другой версии.

    Все это конечно очень весело, но мне интересно, когда-нибудь Oracle подправит это баг или нет?… Это же ужасно.

  • деревья и реляционные базы данных. вложенные множества.

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

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

    1.  Узел хранит информацию о родителе. Это  классика.

    CREATE TREE_NODE (ID INT ..., PARENT_ID INT, ...);
    

    Все очень просто –  узел хранит идентификатор родительского узла. Самая простая схема.

    Такую схему удобно использовать когда:

    Добавление и удаление детей происходит чаще, чем поиск по деревьям.  Структура дерева постоянно меняется. Например идет процесс моделирования какой-то древовидной структуры и нам необходимо сохранять ее состояние в базе данных. В качестве примера можно привести программу в которой пользователь описывает иерархию свой организации.  Другой пример – сохранение в виде дерева информации о структуре разрабатываемого небольшого веб-сайта.

    Другой вариант использования, когда в основном  требуются выборки на уровне одного поколения – получить список  “детей” у данного узла или получить информацию о родителе. Например, если мы используем асинхронное получение узлов в дереве.  Тогда дерево отображается не сразу, а после нажатия пользователем на соответствующий узел, после которого идет обращение к веб-серверу на получение данных. Например, как это выглядит в  Ext GWT (GXT).

    Кстати, в некоторых базах данных существует уже готовые механизмы для работы с деревьями. В частности в ORACLE это CONNECT BY.

    2. Вложенные множества.  Узел хранит в себе информацию о своем расположение в дереве.

    CREATE TREE_NODE (ID INT ...,  LEFT INT...,  RIGHT INT...) ;

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

    и следующего SQL запроса (получение всей ветки для C.1):

    SELECT id FROM tree WHERE left <= 5  AND right => 6 ORDER BY left; -- в итоге получим узлы A, B.2, C.1

    (далее…)