Должен ли я использовать одну или несколько настроек базы данных для мультиклиентского приложения? - PullRequest
61 голосов
/ 01 ноября 2008

Я работаю над приложением PHP, которое намеревается упростить рабочий процесс компании и управление проектами, скажем, что-то вроде Basecamp и GoPlan .

Я не уверен, какой из подходов лучше всего подходит для баз данных. Должен ли я использовать одну базу данных и добавлять специфичные для клиента столбцы в каждую из таблиц или мне следует создавать базу данных для каждого нового клиента? Важным фактором является автоматизация: я хочу, чтобы было очень просто создать нового клиента (и, возможно, открыть возможность зарегистрироваться для себя).

Возможные минусы, которые я могу подумать об использовании одной базы данных:

  • Отсутствие расширяемости
  • Проблемы с безопасностью (хотя ошибок не должно быть в первую очередь )

Что вы думаете об этом? Есть ли у вас какие-либо идеи, какое решение, скорее всего, выбрали вышеуказанные компании?

Ответы [ 10 ]

37 голосов
/ 01 ноября 2008

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

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

Ключевым фактором для удобства обслуживания является то, что вы сохраняете схему одинаковой во всех базах данных. Будет достаточно головной боли для управления версиями без введения специфичных для клиента схем.

34 голосов
/ 01 ноября 2008

Послушайте подкаст Stackoverflow, где Джоэл и Джефф обсуждают один и тот же вопрос. Джоэл рассказывает о своем опыте, когда предлагал размещенную версию своего программного обеспечения. Он отмечает, что добавление идентификаторов клиентов по всей вашей БД усложняет дизайн и код (вы уверены, что случайно не забыли добавить его в какое-то предложение WHERE?) И усложняет функцию хостинга, такую ​​как клиентские резервные копии.

Это было в эпизоде ​​№ 20 или № 21 (подробности смотрите в стенограммах).

22 голосов
/ 01 ноября 2008

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

Подумайте о резервном копировании базы данных. Клиент А говорит: «Пожалуйста, пришлите мне копию моих данных». Гораздо проще в отдельной настройке базы данных, чем в случае совместного использования одной базы данных. Подумайте об удалении клиента; опять же, намного проще с отдельными базами данных.

(Например, часть «инфраструктура» изуродована, потому что между разными СУБД есть существенные различия в том, что представляет собой «база данных», а не «экземпляр сервера», например. Добавить : вопрос помечен «mysql», так что, возможно, эти мысли не совсем актуальны.)

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

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

13 голосов
/ 15 февраля 2009
  • ДЕВЕЛОПМЕНТ Для быстрого развития используйте базу данных для каждого клиента. Подумайте, как легко будет сделать резервную копию, восстановить или удалить данные клиента. Или для измерения / мониторинга / использования счета. Вам не нужно писать код, чтобы сделать это самостоятельно, просто используйте примитивы базы данных.

  • ПРОИЗВОДИТЕЛЬНОСТЬ Для производительности используйте базу данных для всех. Подумайте о пуле соединений, общей памяти, кэшировании и т. Д.

  • БИЗНЕС Если в вашем бизнес-плане много мелких клиентов (например, hotmail), вам, вероятно, следует работать с одной БД. И все административные задачи, такие как регистрация, удаление, перенос данных и т. Д., Полностью автоматизированы и представлены в дружественном интерфейсе. Если вы планируете иметь десятки или до нескольких сотен крупных клиентов, вы можете работать в одной БД на каждого клиента и иметь сценарии системного администрирования, которыми может управлять ваш персонал поддержки клиентов.

12 голосов
/ 13 августа 2010

Следующая заставка объясняет, как это делается на salesforce.com. Они используют одну базу данных со специальным столбцом OrgId, который идентифицирует данные каждого арендатора. Это гораздо больше, так что вы должны посмотреть на это. Я бы пошел с их подходом.

На MSDN есть еще одна замечательная статья . Подробно объясняется, когда следует использовать общий или изолированный подход. Помните, что наличие общей БД для всех ваших арендаторов имеет некоторые важные последствия для безопасности, и если все они используют одни и те же объекты БД, вы можете использовать [безопасность на уровне строк] - в зависимости от используемой СУБД (я уверен, что это возможно в MS SQL Server и Oracle, вероятно, также в IBM DB2). Вы можете использовать такие приемы, как защита на уровне строк в mySQL для достижения аналогичных результатов (просмотры + триггеры).

10 голосов
/ 01 ноября 2008

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

http://en.wikipedia.org/wiki/Multitenancy

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

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

5 голосов
/ 08 октября 2016

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

  1. Иметь одну базу данных на каждого арендатора
  2. Есть одна схема на каждого арендатора
  3. Пусть все арендаторы используют одни и те же таблицы

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

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

  • Если вы строите в масштабе: пусть все арендаторы используют одни и те же таблицы
  • Если вы строите для изоляции: создайте одну базу данных для каждого арендатора

Например, Google и Salesforce следуют первому шаблону и имеют своих арендаторов в тех же таблицах. Stackoverflow, с другой стороны, следует второму шаблону и сохраняет одну базу данных на каждого клиента. Второй подход также более распространен в регулируемых отраслях, таких как здравоохранение.

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

4 голосов
/ 02 ноября 2008

Наличие базы данных для каждого клиента обычно плохо масштабируется. MySQL (и, возможно, другие базы данных) хранит ресурсы, открытые для каждой таблицы, это не очень хорошо подходит для таблиц 10k + в одном экземпляре, что может случиться в крупномасштабной многопользовательской ситуации.

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

Кроме того, «разделение» мультитенантного приложения, вероятно, будет правильным решением, поскольку ваше приложение становится все больше и больше.

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

€ Я не могу этого гарантировать.

4 голосов
/ 01 ноября 2008

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

0 голосов
/ 03 января 2009

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

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

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

...