Database migration using Java

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Всем привет!

Нужна помощь в принятии решения, заранее спасибо!

Задача состоит в том, что нужно разработать инструмент (сервис) для миграции различных баз данных в реальном(либо приближенно к реальному) времени на Java. На данный момент времени у меня есть несколько вариантов: SymmetricDS, JavaLite, Liquibase, Flyway либо же использовать Hibernate или Jdbc.

Разработать нужно с ноля и у меня нет опыта. Есть ли у Вас готовые наработки либо же советы как правильно построить архитектуру приложения и какую технологию лучше выбрать. Мне больше всего понравилось SymmetricDS или Hibernate(но это очередной велосипед).

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

У меня есть готовое решение на Java для миграции данных между Oracle, MySQL, SQL Server и HSQLDB в любую сторону. На голом JDBC. Думаю, несложно адаптировать и для любой другой RDBMS.

Немного расставлю точки над i.

1. JDBC — это универсальное Java API для работы с различными реляционными базами данных. Каждая БД должна реализовать в виде драйвера данный протокол.

2. Hibernate — ORM (object relational mapping). Он позволяет мапить Java классы на таблицы базы данных. Так же предоставляет возможность мапить отношения между таблицами на классы (либо через xml, либо через аннотации). Hibernate реализует JPA 2.1 (?). Позволяет абстрагироваться от особенностей какой-либо базы данных. Он нужен, что бы писать реализовывать универсальные запросы, которые можно ранить на любых базах данных. Под капотом, Хибер использует JDBC API.

3. FlyWay/Liquibase являются системами централизованной накатки изменений в схеме/структуре БД. Те ты что-то пишешь на xml/yanl/json, а потом делаешь liquibase update и данные изменения материализовываются в БД. Причем, данные инструменты позволяют (в некоторой мере) абстрагироваться от БД (как и Хибер).

ИТОГО:
JDBC — не единственный вариант. Но вполне удобоваримый. Драйвера меняются очень медленно, что полезно для долгоживущих проектов.

Hibernate — штука чисто для программирования, где база данных выступает в основном просто хранилищем. Странно что не была (или была?) выпущена своя база, исключительно под Hibernate и ему подобные оболочки. Явно самоустранился бы лишний слой и снизились требования к системе. Большинству проектов жирные базы не нужны.

Программы развёртывания явно сложнее, чем обычные консольные утилиты с заливкой баз. Сложнее — значит куда выше вероятность ошибки и затраты времени на изучение. Они имеют свою область применения. Но для миграции между базами — сомнительно. Всё равно они не учтут нюансов.

Странно что не была (или была?) выпущена своя база, исключительно под Hibernate и ему подобные оболочки.

Всмысле? Зачем Хиберу нужна какая-то своя база данных? Я сказал к тому, что использовать Хибер для задачи миграции это как сравнивать теплое с мягким.

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

Это как он вполне удобоваримый? JDBC предоствляет low level API.

Для скорости и простоты развёртывания «из коробки». Просто базу надо как бы поднимать отдельно, админить отдельно, следить за её эффективностью отдельно. А тут можно было бы поэкспериментировать годков 4-5 на недорогих продакшен-решениях, а там уже и в серьёзные энетерпрайз на вытеснение баз данных из области малых данных.

Для скорости и простоты развёртывания «из коробки».

Есть embedded data bases. Например H2.

Странно что не была (или была?) выпущена своя база, исключительно под Hibernate и ему подобные оболочки.

Я такой редкостной херни еще не слышал.

своя база, исключительно под Hibernate

Что-то типа монго/кауч? И не нужно никаких хибернейтов. Была еще в начале 2000х «объектно-ориентирования БД» Cache, но не взлетела.

Если же говорить о бесполезных оболочках, то No1 — это как раз Хибернейт. Проблем решает минимум и простых, а создает много и совсем поначалу неочевидных.

Самая очевидная проблема всех оболочек — что они должны становиться ЕДИНСТВЕННОЙ точкой доступа, чтобы держать актуальность кешей. То есть де-факто ЗАМЕНЯЮТ собой базу данных вообще совсем.

Конечной эволюцией этого расклада станет простое монтирование томов БЕЗ файловой системы как таковой, чисто под Hibernate-пространство. Со своими структурами, понятными только этой приблуде. И соответственно админами, которые будут вынуждены этот цирк учить, и с ностальгией вспоминать времена когда был SQL, и практически всё сводилось к CRUD-операциям.

Впрочем есть и другая крайность — mongo-подобные базы, но вместо языка запросов у них будут РЕГУЛЯРНЫЕ ВЫРАЖЕНИЯ.

эластик что-ли? все уже есть ©

Вопрос только в леммингах. То что шизофрения существует ни для кого не секрет. Но в моду она не войдёт, разве что кто-то таки сделает её модной типа Гугла.

Так давно уже в моде. Ты в своем оракле, похоже, засиделся чуток. Уже даже чуть выходит.

А про шизофрению интересно. Расскажи.

Миграция чего и куда?
Миграция скриптов?
Миграция бд с одной платформы на другую?

То что перечисленно не является средствами для миграции данных. Это средства для поддержки change management-a схемы БД. В качестве пример средств для миграции данных я бы назвал Tungsten Replicator и скажем ora2pg (Perl). Tungsten Replicator мне не понравился. Слишком заумно, есть две версии коммерческая и типа опен-сорсная. Часть возможностей доступна только в комерческой версии. ora2pg — оставил очень положительное впечатление.

Что значит миграция? Копирование? Вживую или холодное? Структуры или данных? Сохраненных процедур? В чем цель?

Отлично уживаемся уже как 2,5 года с Liquibase на проекте 60+ разработчиков в пике, и 10-15 в обычном режиме. Около 600 миграций, поддержка трех СУБД: MySQL, Oracle, H2. 95% миграций — это DSL Liquibase, что позволяет портативность. Но, в то же время, никто не запрещает писать plain sql. Есть возможность делать «изменяемые миграции», т.е. когда нужно обновить хранимку или справочник.
Очень помогает при фичебранчинге, можно аккуратно добавить необходимое предусловие чтобы та или иная миграция не выполнялась.
Когда вышли в продакшн, сделали несколько снапшот базы и объединили миграции, т.к. их запуск занимал порядком времени (2-10 минут, в зависимости от железа).
Flyway — не рекомендую, так как у него, банально, наблюдались проблемы с переводом строк Unix-Windows.
Hibernate — вообще не вариант, т.к. вы не сможете нормально контролировать процесс обновления схемы/данных.

Ага, и первый же SELECT 1 разрывает мозг Ораклу.

а ты так не делай если портативность нужна.

Есть решение проще.
FUСK DATABASE where name like ’Oracle%’

ну то на любителя. а вот любителей писать все универсально для всего на всякий случай — вот тех я не очень люблю

Любители писать базу данных по-своему напоминают писателей Internet Explorer, у которых каждая новая версия революционная, несовместима с предыдущей, и разумеется несовместима с обычными браузерами.

Вот скажи, за 25 лет тяжело реализовать SELECT 1? Или для этого нужно сначала запатентовать свой особенный?

если бы «SELECT 1 FROM DUAL» был самой большой проблемой оракловской БД, это оставалось бы милой особенностью. Очень хочется делать одинаковый запрос в разных типах баз — добавь табличку DUAL в свои MySQLи, делов то :)

«Милая» особенность Оракла — считать SQL своим, и делать с ним примерно то же, что InternetExplorer с html и css.

Пример: как Ораклу в запросе select скормить по каким ИНДЕКСАМ сделать этот самый select? Ладно, задачка посложнее: как сделать внеиндексный запрос, а пройти ВСЕ записи в их естественном порядке? Да, задача неочевидна, но она бывает.

Задача из разряда тривиальных: как сделать View с заранее заданной предвыборкой индексов, которые там есть?

Далее — как сделать индекс на View? Хотя казалось бы, выборочный индекс — самое то, ради чего индексы теоретически и должны служить.

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

как Ораклу в запросе select скормить по каким ИНДЕКСАМ сделать этот самый select?

hint: /*+ index (tname iname) */

как сделать внеиндексный запрос, а пройти ВСЕ записи в их естественном порядке?

Нет такого понятия как «естественный порядок». Пройти все записи — это обычный FTS.

как сделать View с заранее заданной предвыборкой индексов, которые там есть?

Вообще не понял о чем речь.

как сделать индекс на View?

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

Все эти задачи из разряда натягивания совы на глобус. Большинство задач сейчас решается стоимостным оптимизатором, в сложных случаях есть другие подходы для фиксации плана выполнения, либо для изменения плана выполнения в рабочей системе.

То, что стоимостной оптимизатор до сих пор не в состоянии решить 100% задач по оптимизации, говорит о двух вещах.
1. Это сложная задача сама по себе.
2. Оракл коммерческая компания, и для них такая медленная эволюция оптимизатора — это часть их коммерческой стратегии

Неужели Оракл научился понимать слово index в запросах? Ну сорри, пропустил. Просто помню сколько бодался над костылями.

Оптимизатор вещь хорошая. Но куда более правильная стратегия — РАСКРЫТЬ возможности оптимизатора для автора базы. Он-то точно знает, как и зачем что будет работать, и соответственно куда более правильно может провести оптимизацию.

Индекс — это не нонсенс в любом случае. Если знаешь теорию, как работает бинарное дерево (или другие формы оптимизации) — то знаешь что это глупость — индексировать ВСЕМИ индексами ВСЕ данные. С другой стороны поиск по стандарту языка должен найти ВСЁ, а не только то что было в индексе. Потому оптимальный вариант — это сделать View на основе индекса. То есть чтобы сама вьюшка была не просто хранимым запросом, а полноценным индексом, притом по дефолту.

Очень полезный результат был бы в ограничении пользователей индексом. Это предотвратило бы многие эксплойты, направленные на повышение привилегий за счёт выхода не в свои данные. Особенно полезны были бы вьюшки на индексах для системных таблиц и таблиц производительности.

БЮРОКРАТИЯ — вот стратегия Оракла. Мамонт просто сильно жирный.

Неужели Оракл научился понимать слово index в запросах?

)) Хинты с седьмой версии есть вообще-то, возможно и раньше, я начал с 7-ки работать, то я не знаю как можно было пропустить)

Но куда более правильная стратегия — РАСКРЫТЬ возможности оптимизатора для автора базы.

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

С другой стороны поиск по стандарту языка должен найти ВСЁ, а не только то что было в индексе.

Опять я не понял, о чем идет речь.

Потому оптимальный вариант — это сделать View на основе индекса.

это опять натягивание совы на глобус. Если есть желание и необходимость зафиксировать путь выполнения запроса, то можно использовать SQL Profile и/или baseline.

Очень полезный результат был бы в ограничении пользователей индексом. Это предотвратило бы многие эксплойты, направленные на повышение привилегий за счёт выхода не в свои данные.

Это вообще бред. Для ограничения доступа или грануляции доступа есть FGA, в других базах можно создавать представления на основе таблиц/процедур, в которых можно реализовывать логику доступа к чувствительным данным.

В общем, я не очень понимаю почему так пригорает от Оракла как от СУБД. Это вполне зрелый и относительно стабильный продукт (если сравнивать с другими оракловыми продуктами), в плане возможностей уж точно не уступает другим аналогичным продуктам.

Почему «пригорает»? Продукт не зрелый, он ПЕРЕзрелый. Когда вместо того чтобы изучать реальный мир и подстраивать модели под него — Oracle пытается объяснить всему миру какой тот неправильный, неподходящий совершенной модели.

Как раз производители баз и натягивают сову на глобус, вместо того чтобы честно РАЗГРАНИЧИТЬ сущности таблицы и индекс, позволив индексам развиваться самостоятельно, В ТОМ ЧИСЛЕ быть построенными по нескольким таблицам и прочим сущностям которые крякают как таблицы.

Как раз производители баз и натягивают сову на глобус, вместо того чтобы честно РАЗГРАНИЧИТЬ сущности таблицы и индекс, позволив индексам развиваться самостоятельно, В ТОМ ЧИСЛЕ быть построенными по нескольким таблицам и прочим сущностям которые крякают как таблицы.

Хорош пороть чушь.
Таблицы и индексы — структуры, которые определяют физический доступ к данным, они и так разграничены.
Методы доступа к данным развиваются в рамках ограничений этих структур данных, для того чтобы не выдумывать ничего, нужно всего лишь изучить те, которые уже существуют.
jonathanlewis.wordpress.com/2010/11/22/index-join — хэширование результатов двух полных сканирований индекса
logicalread.com/...​ndexes-mc02/#.WYnTgoSGOpo — битовая маска на соединении двух таблиц.
richardfoote.wordpress.com/...​ap-join-iots-us-and-them — битмап джойн + таблица, организовання по индексу.

Я ровно так и сказал: с позиции паралленьного мира бюрократии — реальный мир со своими хотелками выглядит шизоидным бредом.

Да как это возможно, священную коровушку да на мясо!

В реале задача давно и прочно ушла на уровень приложений, раз базы данных решить её малой кровью не способны.

Это не базы неспособны, а разработчики, не владеющие инструментарием конкретной базы. Вот они и лепят петухов из говна.

Потому оптимальный вариант — это сделать View на основе индекса. То есть чтобы сама вьюшка была не просто хранимым запросом, а полноценным индексом, притом по дефолту.

Ну, есть еще такое понятие как index organized materialized view.
Но мсье знает толк в извращениях, да.

С точки зрения параллельного мира бюрократии, реальный мир выглядит извращённым хаосом.

Кстати, materialized view судя по описанию, штука хорошая. Но... оно может быть Lazy? А надо.

В смысле, одновременно и Lazy, и material? В нарушение (в смысле, аргументированно послав накуй) всех «нормальных» форм за которые Оракл стоят горой десятки лет?

Тогда это хорошо. Одно это стоит чтобы заводить такое счастье в большой и средний энтерпрайз, где данные хранятся годами и при этом актуальны.

В гос.органы бы такое, да чтоб распределённо — цены б им не было!

В смысле, одновременно и Lazy, и material?

В смысле матвьюшка, обновляемая по запросу.

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

Но в этой стране точно не светит.

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

Видимо, кто-то не понял. По запросу — это on demand, т.е. когда скажешь — тогда и обновится.

Но в этой стране точно не светит.

Ну это уже ваше дело, в какой стране какие возможности СУБД использовать.

Flyway — не рекомендую, так как у него, банально, наблюдались проблемы с переводом строк Unix-Windows.

починили уже год как. В принципе пользоваться можно уже. Мне лично ликвибейз все равно больше нравится, но у него наследия прошлого многовато. Типа идентификатора миграции из трех частей зачем-то...

это DSL Liquibase, что позволяет портативность.

осмелюсь спросить, зачем?

Приложение работает в продакшине на разных сетапах: Oracle, MySQL. Например BOOLEAN vs BIT(1) или RAW vs BINARY. Без DSL пришлось бы писать 2 вида скриптов.

и в чем ее прикол? В том чтобы SQL писать в XML...
А если нужен jSQL (SQL c Java кодом)? И не пишите пожалуйста про возможность автогенерируемый скриптов в Liquibase, если вы с ними не работали

никто не запрещает писать plain sql

коме нужен raw SQL...
Что за бред. Нахера строкой выше писать что оно поддерживает несколько SQL engine, а строкой ниже, что кто-то туда хочет в plain SQL определенного engine?

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

Прикинь миграции и так лежат под VCS — так что пофиг на фичебранчинг
Rollback в этой фигне не работает! Достотаточно взглянуть на XML, чтобы это понять! Мы не знаем в каком порядке будет система запускать rollback changeset, чтобы правильно предугадать действия rollback, а зависимостей я между ними не видел (если оно запускается в порядке добавления в GIT — то это вообще бред, особенно если несколько людей над этим работают)
Где система управления конфликтами миграций??? А я скажу где: в жопе! Какая система управления конфликтами, если мы plain SQL пишем... Plain SQL в changeset — это треш

т.к. их запуск занимал порядком времени

2 — 10 минут это порядком времени? Лол

Hibernate — вообще не вариант, т.к. вы не сможете нормально контролировать процесс обновления схемы/данных.

Hibernate это ORM. ORM, Карл!!!

Что за бред. Нахера строкой выше писать что оно поддерживает несколько SQL engine, а строкой ниже, что кто-то туда хочет в plain SQL определенного engine?

потому что у разных людей разные потребности, сюрприз! И ликвибейз относительно удобно их удовлетворяет. Нужны абстракции высокого уровня совместимые с разными СУБД — используй DSL. Нужен полный контроль на более низком уровне — пиши просто SQL. Я предпочитаю SQL по разным причинам.

2 — 10 минут это порядком времени? Лол

ну если раз в полгода релизиться, то жить можно. Хоть и лол само по себе. А если в день несколько релизов — то дофига.

Hibernate это ORM. ORM, Карл!!!

spring.jpa.hibernate.ddl-auto не слышал?

По поводу роллбаков и сорц контрола ты вообще не в тебе. Так, FYI.

spring.jpa.hibernate.ddl-auto не слышал?

А это кто-то рискует ставить, кроме как на дев машине в деф профиле с инмемори базой(или с локально развернутой на дев машине)?

это уже другой вопрос. Хотя да, пытаются.

Если ответственность на тебе, и задача единичная — то мой совет:
1) При миграции с MySQL выбирать не PostgreSQL, а Percona или MariaDB.
Percona ощутимо быстрее, но жрёт оперативу. Если не готов ей скормить хотя бы метров 600, и близко не подходи.
MariaDB — наоборот, скромняшка. Но и она отхавает некисло, если серьёзная задача.
Ну и наконец, классический MySQL. Лучше не надо. Достаточно понимать, что его даже из Debian вышвырнули, заменив на MariaDB.

2) И Percona, и MariaDB — форки MySQL. Это значит крайне высокую совместимость по специфичным командам, таким как INSERT c параметром «ON DUPLICATE KEY UPDATE». Читай прекрасно льётся дампом, притом на полигоне у тебя может стоять одна база, на продакшене другая.

Если проект не жутко нагружен, и простой не вылетит в копеечку — я бы без дополнительных тестов просто поставил на полигоне нужную базу, влил дамп, прогнал стандартные тесты или мануалку (если таких нет). Проверил глазами все запросы на предмет специфичности (то есть выхода за пределы обычного SQL). И ночью спокойно положив сервер, поднял на продакшене нужную базу (вероятно со сносом старой), и поднял дамп. Наутро почитал логи.

Почему так: Если миграция со старого MySQL — не ищи особенностей, он достаточно примитивен. Но сам стек MySQL прекрасно развивается, и в плане своевременного затыкания дыр — лучшее что на сегодня есть. Так что если проект способен на нём крутиться — ну его в болото этот PostgreS, НИЧЕМ он не лучше Мускула.

А вот кеширование запросов, которым так гордится PostgreS — рекомендую просто выключить в любой базе. Втупую жрёт оперативу, и никакой выгоды в типичных задачах.

Если кратко: Задача примитивна, программирования не требует. Типичная админская задача. Но нужно ознакомиться с движками, в частности устроит ли тебя InnoDB (XtraDB), и соответственно поправить всё это в дампе, поискав по ключевому слову ENGINE.
Поскольку дамп очень большой как файл, для редактирования понадобится вменяемый текстовый редактор. Рекомендую EmEditor.
Есть и сложный путь — влить дамп как есть, а движок менять уже потом через ALTER TABLE. Часа четыре убьёшь, а результат тот же самый. Проще сразу в дампе поправить, и таблица будет сразу создана на нужном движке.

АКЦКЕНТ: Базы (не таблицы, а именно базы) дампить раздельно, а не все в общий дамп. Базу MySQL (где все пользователи) — не вливать вообще, но сдампить. Тебя будет интересовать таблица USERS (сдампи её отдельно). Она хранит пользователей и привелегии. Теоретически ты можешь её влить, но... процесс формирования паролей у разных баз разный, так что стоит потом принудительно задать пароли для юзеров запросами из-под рута. Строку с рутом не вливать вообще, иначе потеряешь доступ сам и будешь восстанавливать через танцы с бубном.

выбирать не PostgreSQL, а Percona или MariaDB.

На MariaDB поимел проблему с русской кодировкой, которую так и не смог решить.. (spring — hibernate).. все то же самое на postgreSQL работает без проблем..

Что за русская кодировка? По-моему, проблемы с кодировками решены очень давно и однозначно.
Если же вылил дамп не в той кодировке — тоже мне проблема. Почитай как влить в нужной. Если конечно не потерял часть данных уже на выливке.

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

Основные грабельки возникают на понимании разницы между utf8 и utf8mb4. У китайцев можно и 6-байтные символы utf8 обнаружить, но в большинстве фреймворков пришли к соглашению что 4-байтного предела достаточно.

Вообще мог бы просто спросить здесь на DOU :)

github.com/...​umMicroservices/d-school2
В этом проекте.
i.gyazo.com/...​e088a3fddce444ec974e8.png — Кодировка в БД

Уже перешел на posgreSQL потому, только интерес остался, почему не работало с MariaDB

Ну для начала, MyISAM — это сильно позавчерашний день. Годятся для баз, которые не планируется часто менять по данным, и тем более структуре.

Интерес удовлетворяется просто: utf8mb4. Хотя utf8 и поддерживает русский. Но стоит кому-то сунуть спецсимволы типа смайликов итд итп — и запросы к базе начинают валить твою апликуху в самом неожиданном месте.

Лично я предпочитаю UTF16. Хотя бы потому, что индексы меньше места занимают.

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

Ещё есть неочевидные грабли MySQL и его потомков: поля таблицы на самом деле хранятся НЕ в той кодировке, которая задана при создании таблицы. Но в той, которая стоит как COLLATE на конкретное поле. Сам был в шоке. Мало того, в момент ALTER TABLE почему-то данные ПЕРЕКОДИРУЮТСЯ до невменяемости.

Ещё неочевидные грабли — у консольных утилит снятия дампа кодировка своя, и может не совпадать с кодировкой базы. Прикинь сюрприз, когда в дампе оказываются покоцаные данные. И ведь это не так сразу заметишь. Благо на продакшене не нарвался, поймал когда сливал на полигон.

В общем, настройки кодировок везде надо делать. И utf16 для современных баз пожалуй лучший вариант. Особенно для Java, которая нативно держит данные в utf16, что делает её оптимальным дефолтным вариантом для Java-проектов.

Спасибо, проект учебный, под изучение spring, потому с БД сильно не заморачивался, mariaDB идет в сборке XAMPP, что довольно было удобно.
utf8mb4 пробовал, не помогло. utf8 тоже, все русские символы заменялись знаками вопроса. При том, что если в БД внести что-то на русском, то все нормально. В следующий раз попробую все через utf16.. А пока-то чуть поковыряю postgreSQL, тоже пригодится наверное..

Spring — hibernate ... postgreSQL

А как там с хранимками, уже без боли можно работать?

С храниками без боли работать нельзя НИГДЕ, поскольку хранимые процедуры каждая самкасобаки из писателей баз ограничивает по-своему, и ставит свои костыли якобы ради безопасности, на деле просто так когда-то показалось правильным, и теперь вместо того чтобы поправить — поддерживают старое «показалось».

Казалось бы, это обычный язык программирования, да напиши ты его как язык программирования, и будет счастье. Нееет, обязательно через SELECT и UPDATE, да с выгебонами.

В Oracle как раз с этим проще всего, может потому что они являются авторами SQL и львиной доли его фич.

В чем проблема работать с хранимками у вас?

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

Spring Data + hibernate

Собственно то, что это хранимые процедуры. При этом имеющие огромные проблемы ЧЕРЕЗ ЖОПУ сделанных переменных, которым НЕЛЬЗЯ к примеру присвоить блокировку транзакции дабы ею владеть. Нельзя выйти из дедлока. Нельзя явно блокировать или разблокировать таблицу или запись.

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

Ну и классика try — finally далеко не во всех базах есть. А без этого огромный риск наступить на грабли, и лишь вопрос времени когда грабли сработают.

Лично я бы предпочёл обычное API под обычный язык программирования. Так сказать, драйвер. Чтобы командами на этом языке в его родной среде дёргать низкоуровневые запросы к базе. Вариант, что это будет совсем даже не SQL.

Я даже не исключаю что это есть. Просто лень искать и осваиваться. NoSQL в этом плане куда более покладисты.

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

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

А ещё, если вносятся изменения — их не прольёшь в приложение. То есть использование хранимых процедур оправдано в двузвенной системе, где репликация данных идёт по уровню базы данных. И не оправданы совсем за редким частными случаями, где есть приличный бекенд, кеширующий львиную долю часто используемых данных, хранящихся в удобном ООП-виде с соответствующими связями.

Плюс поддержание целостности явно легче реализовывать в приложении, нежели в базе. Например, можно напрочь отказаться от словарей и foreign key по ним.

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

Ну что ж поделать — SQL так устроен.

использование хранимых процедур оправдано в двузвенной системе, где репликация данных идёт по уровню базы данных.

Ну да. И используется сейчас в основном в целях изоляции какой-нибудь логики + скриптовых задач. Все что можно было безопасно перенести на middle tier, туда уже давно перенесено.

Плюс поддержание целостности явно легче реализовывать в приложении, нежели в базе.

А вот и нифига подобного. Ибо при наличии Х серверов приложений задача контроля целостности на них становится крайне увлекательной и до сих пор полный ACID таким образом никто сколь-либо удачно не реализовал.

Например, можно напрочь отказаться от словарей и foreign key по ним.

В проекте типа «убийца фейсбучега» — да. В проекте CoreBanking етц. — категорически нет. Удали одну запись из словаря (а на аппе это возможно) и развалишь всю базу.

Мы сейчас про банк и не говорим. И даже для банка львиная доля процедур не нуждается в поддержке целостности.

И потом, ты просто не был свидетелем, когда в банке при переносе на новую версию или софт, в базу через админ-полномочия ОТКЛЮЧИВ ПРОВЕРКИ вливают данные старых баз, которые не соответствуют словарям. И так каждый раз!

И потом, ты просто не был свидетелем, когда в банке при переносе на новую версию или софт, в базу через админ-полномочия ОТКЛЮЧИВ ПРОВЕРКИ вливают данные старых баз, которые не соответствуют словарям.

Прям таки не соответствуют?

Прям абсолютно вообще совсем, и нарушат логику приложений когда те в них вступят. В том числе приложений работающих на полном автомате, например обзвон должников по 100500 раз в сутки.

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

Мигрировать данные можно простым дампом, как говорится, из коробки. Куда сложнее мигрировать логику, если она построена на запросах, специфичных для конкретной базы данных.

Универсального решения нет, и разумеется не может быть. Попытка построить такой сервис — не более чем геморой с необоснованным взятием на себя ответственности за то, что технически невозможно.

Простая рекомендация: учитывая среднюю продолжительность жизни базы менее 2 лет, лучше просто тянуть с миграцией как можно дольше. И только в тех редчайших случаях, когда проект очень круто выстрелил, взорвался — выбрать продукт и очень меееедленнно и пошагово выполнить на него миграцию. Выбор продукта как правило очень специфичен, каждый выстреливший проект — велосипед в своём роде, и нельзя предсказать в какую сторону по данным он выстрелит.

Типичный пример: один мой проект занимал около 4 гиг в архиве по базе, требовал 12-процессорного сервера. Когда пошёл на стабильный спрос, проделаны сотни оптимизаций логики. Сейчас он занимает около 0.5Гб в развороте, всего 18Мб в архиве, и еле-еле напрягает одно ядро на 8% в пике. Нужна ли ему миграция? Да, он её прошёл. Но только когда стала понятна структура ключевых таблиц.

Підписатись на коментарі