Применение мультитенантных рельсов: каковы плюсы и минусы разных методов?

Изначально я написал приложение Ruby on Rails для одного клиента. Сейчас я меняю его, чтобы его можно было использовать для разных клиентов. Моя конечная цель состоит в том, чтобы какой-нибудь пользователь (не я) мог нажать кнопку и создать новый проект. Затем все необходимые изменения (новая схема, новые таблицы, обработка кода) генерируются, и мне никому не нужно редактировать файл database.yml или добавлять новые определения схемы. В настоящее время я использую доступ SCOPED. Итак, у меня есть модель проекта, а у других связанных моделей есть столбец project_id.

Я просмотрел другие сообщения о мультитенантных приложениях в Rails. Многие люди предлагают создавать разные схемы для каждого нового клиента в Postgres. Для меня, однако, для нового клиента не очень полезно иметь другую схему с точки зрения модели данных. У каждого клиента будут одинаковые таблицы, строки, столбцы и т. Д.

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

Похож ли способ, которым я объяснил свое видение, на то, как Postgres реализует различные «схемы»? Это похоже на вложенные таблицы? Или Postgres все равно должен запрашивать всю информацию в базе данных? В настоящее время я не использую Postgres, но я хотел бы узнать, подходит ли он для дизайна. Если вам известно о программном обеспечении для баз данных, которое работает с Rails и которое соответствует моим потребностям, пожалуйста, дайте мне знать.

Прямо сейчас я использую области для создания мультитенантных приложений, но это не кажется масштабируемым или чистым. Тем не менее, это очень упрощает для нетехнических пользователей создание нового проекта при условии, что я даю им заполняемую информацию. Знаете ли вы, возможно ли с определением Postgres с несколькими схемами, чтобы он работал автоматически после того, как пользователь нажимает кнопку? И я бы предпочел, чтобы это выполнялось Rails, а не внешним скриптом, если это возможно? (пожалуйста, посоветуйте в любом случае)

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

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

Спасибо, - Дэйв


person David Groff    schedule 09.08.2011    source источник


Ответы (3)


Не забывайте об использовании областей действия по умолчанию, при создании именованных областей действия, как вы сейчас работаете, кажется, что это можно было бы сделать лучше. Я наткнулся на это руководство Самуэля Кадольфа по этому вопросу. несколько месяцев назад, и похоже, что это может хорошо сработать в вашей ситуации и иметь то преимущество, что ваше приложение не содержит некоторых функций, связанных только с PgSQL.

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

person Devin M    schedule 09.08.2011
comment
это действительно чисто! это сделало бы код намного проще. Однако знаете ли вы, как это влияет на производительность? разделяет ли он данные в каждой таблице на каждого арендатора? или он хранит данные по первичному ключу и требует полной итерации для получения данных для конкретного клиента? - person David Groff; 14.08.2011
comment
Теннант должен быть первичным ключом, поскольку он похож на любые отношения Rails. Это будет так же медленно, как и любой другой поиск по индексированному первичному ключу в SQL или любой другой базе данных, которую вы используете. - person Devin M; 14.08.2011

В MSDN есть хорошее введение в многопользовательскую архитектуру данных.

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

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

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

Это звучит так, будто вы говорите об одной схеме для каждого арендатора. Обратите особое внимание на разрешения (SQL GRANT и операторы REVOKE. И ALTER DEFAULT PRIVILEGES.)

person Mike Sherrill 'Cat Recall'    schedule 10.08.2011
comment
Спасибо. руководство действительно полезно. вариант с отдельной схемой мне очень нравится. Вы знаете, есть ли у него какая-либо поддержка в рельсах, или я буду в основном идти против течения? - person David Groff; 14.08.2011
comment
Если вы выполните поиск на этой странице, edgeguides.rubyonrails.org/3_0_release_notes.html, вы найдете есть некоторая поддержка схемы. Я занимаюсь этим десятилетиями; Я склонен пессимистично относиться к документальной поддержке чего-либо. (Помните, что MySQL поддерживает ограничения внешнего ключа? Он поддерживал ограничения FK, анализируя их, а затем игнорируя их.) На вашем месте я бы разработал дизайн с одной или двумя таблицами и протестировал бы его. - person Mike Sherrill 'Cat Recall'; 14.08.2011

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

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

Вот также хорошая презентация multitenancy-with-rails.

person cwadding    schedule 23.10.2012