Общая таблица
При таком подходе данные всех тенантов хранятся в одной общей таблице, а для идентификации данных каждого тенанта используется поле (или набор полей). Чтобы добиться максимальной производительности, это поле должно входить в первичный ключ. Чтобы пользователи могли получать доступ только к данным своих тенантов, используется ролевое управление доступом, реализованное с помощью политик на уровне строк.Мы рекомендуем этот подход, так как им проще всего управлять, особенно если у всех тенантов одинаковая схема данных, а объёмы данных умеренные (< ТБ)Объединение данных всех тенантов в одной таблице повышает эффективность хранения за счёт оптимизированного сжатия данных и снижения накладных расходов на метаданные. Кроме того, упрощается обновление схемы, поскольку все данные управляются централизованно. Этот метод особенно эффективен при работе с большим числом тенантов (вплоть до миллионов). Однако в некоторых случаях могут лучше подойти альтернативные подходы — например, если у тенантов разные схемы данных или предполагается, что со временем различия между ними будут увеличиваться. Если объёмы данных у тенантов сильно различаются, у небольших тенантов может без необходимости снижаться производительность запросов. Обратите внимание: эта проблема в значительной степени решается, если включить поле тенанта в первичный ключ.
Пример
Это пример реализации модели мультиарендности с общей таблицей. Сначала создадим общую таблицу, где полеtenant_id входит в состав первичного ключа.
user_1 и user_2.
user_1 и user_2 получать доступ только к данным своих тенантов.
GRANT SELECT для общей таблицы с помощью общей роли.
user_1 и выполнить простой SELECT-запрос. Будут возвращены только строки первого тенанта.
Отдельные таблицы
При таком подходе данные каждого тенанта хранятся в отдельной таблице в одной и той же базе данных, поэтому не требуется специальное поле для идентификации тенанта. Доступ пользователей настраивается с помощью оператора GRANT, так что каждый пользователь может обращаться только к таблицам с данными своих тенантов.Использование отдельных таблиц — хороший выбор, если у тенантов разные схемы данных.В сценариях с небольшим числом тенантов и очень большими наборами данных, где критична производительность запросов, этот подход может быть эффективнее модели с общей таблицей. Поскольку не нужно отфильтровывать данные других тенантов, запросы могут выполняться быстрее. Кроме того, первичные ключи можно дополнительно оптимизировать, так как в первичный ключ не нужно включать дополнительное поле (например, идентификатор тенанта). Обратите внимание: этот подход не масштабируется на тысячи тенантов. См. ограничения использования.
Пример
Это пример реализации модели мультиарендности с отдельными таблицами. Сначала создадим две таблицы: одну для событий изtenant_1 и одну для событий из tenant_2.
user_1 и user_2.
GRANT SELECT для соответствующей таблицы.
user_1 и выполнить простой SELECT-запрос к таблице, соответствующей этому пользователю. В результате будут возвращены только строки первого тенанта.
Отдельные базы данных
Данные каждого тенанта хранятся в отдельной базе данных в рамках одного сервиса ClickHouse.Этот подход полезен, если каждому тенанту требуется большое количество таблиц и, возможно, materialized views, а также если схемы данных у тенантов различаются. Однако при большом числе тенантов управлять этим становится сложно.Реализация похожа на подход с отдельными таблицами, но вместо предоставления привилегий на уровне таблицы привилегии предоставляются на уровне базы данных. Обратите внимание: этот подход не масштабируется на тысячи тенантов. См. ограничения использования.
Пример
Это пример реализации модели мультиарендности с использованием отдельных баз данных. Сначала создадим две базы данных: одну дляtenant_1 и одну для tenant_2.
user_1 и user_2.
GRANT SELECT на соответствующую таблицу.
user_1 и выполнить простой запрос SELECT к таблице events в нужной базе данных. Будут возвращены только строки первого тенанта.
Разделение вычислительных ресурсов
Три описанных выше подхода также можно дополнительно изолировать с помощью хранилищ. Данные совместно используют общее Объектное хранилище, но благодаря разделению вычислительных ресурсов с различным соотношением CPU/Memory у каждого тенанта может быть собственный вычислительный сервис. Управление пользователями аналогично описанным ранее подходам, поскольку все сервисы в хранилище используют общее управление доступом. Обратите внимание, что число сервисов в хранилище отдельно не ограничивается, но суммарное количество реплик по всем сервисам хранилища ограничено. См. Ограничения использования и масштабирование хранилища.Отдельный сервис ClickHouse Cloud
Самый радикальный подход — использовать отдельный сервис ClickHouse для каждого тенанта.Этот менее распространённый метод может подойти, если данные тенантов должны храниться в разных регионах — по юридическим причинам, из соображений безопасности или географической близости.В каждом сервисе, к которому пользователь должен иметь доступ к данным соответствующего тенанта, необходимо создать учётную запись пользователя. Этим подходом сложнее управлять, и с каждым новым сервисом растут накладные расходы, поскольку для работы каждого из них требуется собственная инфраструктура. Сервисами можно управлять через ClickHouse Cloud API; оркестрация также возможна с помощью официального Terraform-провайдера.
Пример
Это пример реализации модели мультиарендности с отдельными сервисами. Обратите внимание: в примере показано создание таблиц и пользователей в одном сервисе ClickHouse; то же самое потребуется повторить во всех сервисах. Сначала создадим таблицуevents
user_1
GRANT SELECT на соответствующую таблицу.
user_1 и выполнить простой запрос SELECT. Будут возвращены только строки первого тенанта.