Hibernate и мультитенантная база данных с использованием схем в PostgreSQL - PullRequest
8 голосов
/ 02 декабря 2011

Справочная информация

Я работаю над будущим мультитенантным веб-приложением, которое будет поддерживать тысячи пользователей.Приложение создается на основе Java-игры Play!MVC Framework с использованием JPA / Hibernate и postgreSQL.

Я наблюдал выступление Гая Наора на Написание мультитенантных приложений в Rails , в котором он рассказывает о нескольких подходах к мультитенантности (изоляция данных уменьшаетсяпо мере продвижения по списку):

  1. Каждый клиент имеет отдельную базу данных
  2. Одна база данных с отдельными схемами и таблицами (пространства имен таблиц) для каждого клиента.
  3. Одна база данных с 1 набором таблиц со столбцами идентификаторов клиентов.

Я остановился на подходе № 2, где некоторый идентификатор пользователя анализируется из запроса, а затем используется для доступа к табличному пространству этого пользователя.Команда postgres SET search_path TO customer_schema,public дается перед выполнением любого запроса, чтобы убедиться, что таблицы клиента являются целью запроса.Это легко сделать с помощью @Before аннотаций контроллера в методах контроллера в Play! (этот подход Гай использовал в своем примере с рельсами). search_path в postgres действует точно так же, как $PATH в ОС;Круто!

Все это звучало замечательно, но я сразу же столкнулся с трудностями при реализации его поверх стека JDBC / Hibernate / JPA, потому что, похоже, нет способа динамического переключения схем во время выполнения.

Проблема

Как заставить JDBC или Hibernate поддерживать динамическое переключение схем Postgres во время выполнения?

Кажется, что соединения с базой данных статически конфигурируются фабрикой соединений (см .: Как управлять множеством схем в одной базе данных, используя hibernate ).Я нашел похожие вопросы с похожими ответами об использовании нескольких SessionFactorys для каждого пользователя, но, поскольку я понимаю, что SessionFactorys являются объектами с большим весом, поэтому маловероятно, что вы сможете поддерживать сотни пользователей, не говоря уже о тысячах пользователей, идущих по этому маршруту.* Я не полностью посвятил себя достижению # 2 выше, но я еще не совсем отказался от него для подхода # 3.

Ответы [ 3 ]

5 голосов
/ 02 декабря 2011

Вы можете выполнить команду

SET search_path TO customer_schema,public

так часто, как вам нужно, в пределах одного соединения / сеанса / транзакции. Это просто другая команда типа SELECT 1;. Больше в руководстве здесь .

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

ALTER ROLE foo SET search_path=foo, public;

Если у каждого пользователя или многих из них есть схема, соответствующая его имени пользователя, вы можете просто перейти с настройкой по умолчанию в postgresql.conf :

search_path="$user",public;

Другие способы установки search_path здесь:
Как search_path влияет на разрешение идентификатора и "текущую схему"

1 голос
/ 02 августа 2017

Несмотря на то, что шардирование по схеме является обычным явлением, см. в этом посте от авторов самоцветов Apartment, в котором освещены некоторые недостатки.

В Citus мы шардим с помощью опции № 3, указанной выше, и вы можете прочитатьбольше в нашем руководстве по использованию в документации.

1 голос
/ 18 января 2012

Начиная с Hibernate 4.0, многопользовательская поддержка изначально поддерживается на уровне распознавания (customerID), схемы и базы данных.См. Исходный код здесь и модульный тест здесь .

Сложность состоит в том, что, хотя имя файла модульного теста равно SchemaBasedMultitenancyTest, в действительности используется MultitenancyStrategy - база данных.Я не могу найти примеров того, как заставить это работать на основе схемы, но, возможно, будет достаточно модульного теста, чтобы продолжить ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...