Можно ли указывать схему в `table_name_prefix`? - PullRequest
6 голосов
/ 15 мая 2019

TL; DR: Можно ли указывать схему в table_name_prefix?

У нас есть большое приложение Rails, которое не совсем традиционное мультитенантное приложение.У нас есть сотня клиентов, и все они поддерживаются одним приложением, и это число никогда не будет расти больше, чем на 1-2 в год.В настоящее время у каждого клиента есть своя собственная база данных Postgresql.

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

Приложение невидимо даже для клиентов, поэтому многие традиционные принципы мультитенантного веб-сайта не применимы здесь аккуратно.

  • У каждого арендатора есть особыйБаза данных Postgres, управляемая в database.yml.
  • Каждая база данных имеет схему, названную для арендатора.
  • У нас есть модель, специфичная для каждого арендатора, с заметно отличающимся кодом.
  • Каждая модель использует Estab_connection для выбора другой базы данных и схемы.
  • Каждая модель использует отдельный table_name_prefix с уникальным именем клиента.

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

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

Мы посмотрели на жемчужину квартиры и решили, что она не подходит для того, что мы делаем.

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

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

def self.table_name_prefix
  'client99_'
end

Посредством экспериментов и поиска в Rails 4 (наша текущая версия) и в исходном коде Rails 5 это работает для определения схемы ('tenant_99'), а такжетрадиционный префикс таблицы ('client99'):

def self.table_name_prefix
  'tenant_99.client99_'
end

До этого запросы выглядели так:

SELECT COUNT(*) FROM 'client99_products'

После этого они включают схему по желанию:

SELECT COUNT(*) FROM 'tenant_99.client99_products'

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

Итак, несмотря на все это, вот вопросы, на которые я не нашел однозначных ответов:

  • Есть ли опасения, что слишком много схем перечислено в schema_search_path?
  • Поместите имя схемы в table_name_prefix хорошо?

1 Ответ

1 голос
/ 17 июля 2019

Чтобы решить ваши проблемы в обратном порядке:

  • Хорошо ли помещать имя схемы в table_name_prefix?

Нет проблем, если только именаявляются уникальными (внутренними и внешними). ​​

  • Есть ли проблема с тем, что слишком много схем указано в schema_search_path?

Ответ может быть, любой не полностьюквалифицированный запрос (запрашивающий таблицу только по имени) должен будет искать каждую из схем в порядке, указанном в schema_search_path. Если он кэшируется в памяти, штраф будет незначительным;поиск всех схем на диске будет медленным (пропорциональным его расположению в списке). Сначала обязательно перечислите наиболее активные схемы.

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

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

Помните, что пул соединений только сводит к минимуму накладные расходы на настройку и время разрыва соединений, используя преимущества «пробелов» во время связи.

Например:

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

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

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

Недостаток / преимущество объединения баз данных в одну: невозможность перемещения отдельныхбазы данных на другой сервер для целей балансировки нагрузки вне методов PostgreSQLs для балансировки нагрузки.

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