Показаны сообщения с ярлыком data base. Показать все сообщения
Показаны сообщения с ярлыком data base. Показать все сообщения

воскресенье, 21 апреля 2013 г.

очень упрощенный конспект книги о Spring Data

Долго сомневался, но все же решил опубликовать краткий конспект того, что вычитал в книге Чтение он не заменит, опыта не добавит, но общее представление о том, что в книге способен дать.
Итак, тезисно:
  1. Причины появления NoSQL: увеличение количества данных, соотношение структуры домена со структурой базы данных (графы как графы, key-value как key-value)
  2. Виды NoSQL баз: key-value (похоже на hashtable), column family (как key-value но value это column), document (структурированные данные, например XML или JSON) и graph (графы, модель данных содержит узлы-nodes и ребра-edges)
  3. Atomicity Consistency Isolation Durability (ACID) в RDBMS заменяется Basically Available Scalable Eventually consistent (BASE) для NoSQL
  4. JPA не подходит как основа общего интерфейса для NoSQL - его спецификация завязана на Object Relational Mapping.
  5. Каждое из хранилищ Spring Data содержит не только одинаковую структурную модель, но и отличия в свойствах и возможностях
  6. Spring Data работает на основе декларативного маркерного обозначения имен элементов архитектуры (классов, интерфейсов, полей данных, методов). Выбор конкретного хранилища определяется в конфигурации приложения (например, @EnableJpaRepositories или jpa:repositories base-package="..." если используется XML-конфиг).
  7. Методы интерфейса для работы с определенным доменным класом (например, Client) определяются или полностью пользователем (через запрос @Query для выполнения), или путем расширения интерфейсов Spring Data.
    Repository - простой маркерный интерфейс для пометки для Spring Data определяемого пользователем репозитория.
    CrudRepository расширяет Repository основными методами объектно-реляционной модели - поиском, сохранением и удалением сущностей.
    PagingAndSortingRepository расшираяет CrudRepository методами распределения по страницам и сортировкой.
  8. Пользователь может сам определять новые интерфейсы для репозиториев согласно своему представлению архитектуры приложения. Для этого интерфейс необходимо пометить как @NoRepositoryBean если интерфейс будет наследоваться от существующего интерфейса репозиториев, или создать свой собственный интерфейс и его реализацию согласно соглашения по именованию (например, ClientRepositoryCustomization и ClientRepositoryCustomizationImpl)
  9. Имена методов интерфейсов репозитория должны соответствовать верблюжемуРегистру и основываться на запроектированных шаблонах чтобы Spring Data их распознал, или полагаться на прилагаемое Query.
    Например,
    Client findByFirstname(String firstname) - найти клиента Client по его полю данных firstname,
    List findByAddress_ZipCode(ZipCode zipCode) - найти список клиентов по почтовому коду, который содержит его поле данных - адрес address,
    List findByEmailAndLastname(EmailAddress email, String lastname) - найти список клиентов по почтовому адресу и фамилии.
    Если держаться за конвенцию именования, то Spring Data генерирует нужный запрос Query.
  10. Spring Data поддерживает интеграцию с Querydsl. который позволяет обобщенно составлять запросы к JPA, Hibernate, JDO, native JDBC, Lucene, Hibernate Search, и MongoDB. Похоже на попытку сделать нечто подобное LINQ, но для java. Не понравилось - Eclipse не подхватил даже с танцами, Intellij Idea разобралась, но осадочек остался. По-моему, шаг с отдельной автогенерацией запросов не удобный. Вот разве что если запросов в проекте много, и их все надо поддерживать в удобочитаемом виде?
  11. MongoDB - хранилище документов в формате BSON - бинарного расширения JSON.
  12. Neo4J - база данных графов, состоит из вершин и их отношений.
  13. Redis - key-value база данных.
  14. Spring Roo - проект SpringSource для управления кодом и его созданием.
  15. Spring REST Exporter - проект SpringSource для доступа к основанным на JPA репозиториям через REST-интерфейс.

пятница, 15 марта 2013 г.

Это приятное чувство "а я ведь говорил"

Вспомнилось.

На одной из прошлых работ столкнулся с любопытной ситуацией различия работы серверов баз данных MySQL и MS SQL.
Вкратце и упрощенно, клиенты часто получали неприятность отказа программы при использовании определенных тяжелых запросов с помощью внутренней системы поиска.
Внутри все сводилось к запросу вида
SELECT DISTINCT [smthng1] FROM (множество_1) WHERE [smthng2] NOT NULL AND EXISTS (множество_2)
Не буду углубляться в сложности выборки обоих указанных множеств - это не существенно. Сложные. Поля из нескольких таблиц.

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

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

Разбор полетов показал, что эффективнее разбить запрос на две части, и с помощью java перебрать совпадения множеств, чем ждать пока MySQL обработает EXISTS.
Что ж, решение было внедрено и отправлено клиенту.

Но внезапно оказалось, что у клиента MS SQL и его проблему патч не решил.
Ощущение собственной правоты подогрело душу.
Клиент своим отказом отсрочил полноценное решение проблеммы.

Но это не было концом истории.

Дамп базы MS SQL для препарирования мы все-таки получили.
Но потом оказалось, что никаких проблем с EXISTS у запроса нет.
Недоразумения для MS SQL связаны с DISTINCT.

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

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

Выводы, они же советы.

  1. Добивайтесь максимального совпадения рабочей среды и среды разработки.
  2. Осторожно с  EXISTS в MySQL.
  3. Осторожно с DISTINCT в MS SQL.
Дальше надо бы подкрепить примерами на тестовой базы на чистом и свободном проекте, но уж очень лень. "Я просто оставлю здесь это"...