Иерархическая мультитенантная архитектура с Django и Postgresql с использованием отдельных схем - PullRequest
0 голосов
/ 08 ноября 2018

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

Иерархическая часть

Клиенты могут рекурсивно включать других клиентов. Например, Клиент A включает Клиент B и Клиент C . Если пользователь Клиент A входит в систему, пользователь увидит данные Клиент B и Клиент C . Если пользователь Client B входит в систему, он увидит только данные Client B .

мультитенантная часть

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

Когда я исследовал Создание мультитенантных приложений с Django , я увидел эту часть:

def set_tenant_schema_for_request(request):
    schema = tenant_schema_from_request(request)
    with connection.cursor() as cursor:
        cursor.execute(f"SET search_path to {schema}")

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

1 Ответ

0 голосов
/ 09 ноября 2018

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

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

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

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

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

https://www.postgresql.org/docs/11/ddl-rowsecurity.html

...