В чем преимущества использования единой базы данных для КАЖДОГО клиента?

В приложении, ориентированном на базу данных, которое разработано для нескольких клиентов, я всегда считал, что «лучше» использовать единую базу данных для ВСЕХ клиентов, связывая записи с соответствующими индексами и ключами. Слушая подкаст Stack Overflow, я слышал, как Джоэл упомянул, что FogBugz использует одну базу данных для каждого клиента (так что если бы было 1000 клиентов, было бы 1000 баз данных). Каковы преимущества использования этой архитектуры?

Я понимаю, что для некоторых проектов клиентам нужен прямой доступ ко всем их данным - в таком приложении очевидно, что каждому клиенту нужна собственная база данных. Однако для проектов, где клиенту не нужен прямой доступ к базе данных, есть ли какие-либо преимущества в использовании одной базы данных для каждого клиента? Кажется, что с точки зрения гибкости намного проще использовать единую базу данных с единственной копией таблиц. Легче добавлять новые функции, проще создавать отчеты и проще управлять.

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

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

Любой вклад приветствуется!


person Ryan    schedule 16.08.2008    source источник
comment
См. Также Одна база данных против нескольких баз данных в serverfault.   -  person Örjan Jämte    schedule 06.07.2011


Ответы (10)


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

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

Вы также получаете преимущества разделимости - просто извлечь данные, связанные с данным клиентом, и переместить их на другой сервер. Или восстановите резервную копию этого клиента при вызове, чтобы сказать «Мы удалили некоторые ключевые данные!», Используя встроенные механизмы базы данных.

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

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

Думаю, я могу придумать еще несколько десятков. Но в целом ключевое понятие - «простота». Продукт управляет одним клиентом и, следовательно, одной базой данных. Проблема «Но в базе данных есть и другие клиенты» никогда не возникает никаких сложностей. Это соответствует ментальной модели пользователя, где они существуют поодиночке. Такие преимущества, как возможность легко составлять отчеты по всем клиентам одновременно, минимальны - как часто вы хотите получать отчет по всему миру, а не только по одному клиенту?

person Adam Wright    schedule 16.08.2008
comment
С точки зрения сохранения стены между клиентами, это то, для чего нужны хранимые процедуры и триггеры (предупреждение: не рекомендуется для MySQL) - также тривиально легко (повторно) переместить данные клиентов на разные серверы, если кто-то правильно построил схему. . Простота работает и в обратном направлении. Если у меня есть одна база данных, я могу легко объединить свои соединения и упростить этот код. Если у меня заканчиваются соединения, я просто увеличиваю пул; не нужно следить за каждым клиентом отдельно. - person BryanH; 19.10.2009

Вот один из подходов, который я видел раньше:

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

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

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

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

person The How-To Geek    schedule 16.08.2008

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

person bruceatk    schedule 16.08.2008
comment
Так быть не должно. Если вы не можете использовать индексы для изоляции строк, либо база данных плохо спроектирована, либо вы пытаетесь запросить весь кросс-клиентский набор данных, что было бы труднее сделать с отдельными базами данных для начала. - person Nick; 19.02.2019

Что ж, что, если один из ваших клиентов скажет вам восстановить более раннюю версию своих данных из-за какой-то неудачной операции импорта или чего-то подобного? Представьте, что почувствовали бы ваши клиенты, если бы вы сказали им: «Вы не можете этого сделать, поскольку ваши данные используются всеми нашими клиентами» или «Извините, но ваши изменения были потеряны, потому что клиент X потребовал восстановления базы данных».

person Lasse V. Karlsen    schedule 16.08.2008
comment
Все таблицы должны быть разделены по TenantID. Это дает вам возможность делать резервные копии / восстанавливать разделы только для одного клиента :) - person dariol; 21.05.2010
comment
@ dario-g: Похоже, вы поддерживаете подход с общей базой данных. Пожалуйста, объясните, что вы имеете в виду под TenantID, поскольку это может быть неочевидно. - person Gruber; 21.09.2012
comment
В Oracle вы можете разделить таблицу и переместить разделы в удаленные места, но при этом у вас останется одна таблица. - person givanse; 06.02.2014

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

Вот статья по этой теме (да, это MSDN, но это статья, не зависящая от технологий): http://msdn.microsoft.com/en-us/library/aa479086.aspx.

Еще одно обсуждение мультитенантности в связи с вашей моделью данных здесь: http://www.ayende.com/Blog/archive/2008/08/07/Multi-Tenancy--The-Physical-Data-Model.aspx

person Nathan    schedule 16.08.2008
comment
Кто-нибудь знает инструмент, который автоматизирует обновление нескольких баз данных, скажем, MySQL? Если вы решите использовать подход изоляции, вам необходимо убедиться, что 1000 баз данных обновлены, зеркально отображая схему назначенной главной базы данных. - person Gruber; 21.09.2012
comment
@ Натан, вы все еще используете один дб на каждого арендатора? - person jonathancardoso; 17.10.2016
comment
Нет, в итоге пришлось использовать одну многопользовательскую базу данных и включить конфиденциальность клиентов в структуру приложения. Одна база данных на каждого арендатора была для нас слишком накладной. - person Nathan; 24.10.2016

Масштабируемость. Безопасность. Наша компания также использует 1 БД на каждый клиентский подход. Это также упрощает сопровождение кода.

person Darren Kopp    schedule 16.08.2008
comment
Эй, ты все еще пользуешься этим подходом? Не могли бы вы поделиться некоторыми цифрами о том, сколько клиентов / БД у вас в настоящее время? - person jonathancardoso; 12.07.2016

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

person Daniel Magliola    schedule 28.08.2008
comment
В то время у меня не было достаточной репутации, проверьте дату моего ответа. - person Daniel Magliola; 14.10.2009

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

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

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

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

person Ryan    schedule 16.08.2008
comment
Вы, кажется, склоняетесь к Общему подходу. Я с тобой. - person Matt Kocaj; 22.04.2009

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

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

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

Мне было бы интересно услышать от вас немного больше контекста по этому поводу, потому что кластеризация - непростая тема, и ее дорого реализовать в мире РСУБД. Существует много разговоров / бравады о кластеризации в нереляционном мире Google Bigtable и т. Д., Но они решают другой набор проблем и теряют некоторые полезные функции СУБД.

person Brian Lyttle    schedule 16.08.2008

У слова "база данных" есть несколько значений.

  • аппаратная коробка
  • запущенное программное обеспечение (например, "оракул")
  • конкретный набор файлов данных
  • конкретный логин или схема

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

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

person Mark Harrison    schedule 16.08.2008
comment
Нет, он имеет в виду базу данных. То, что создается при выполнении оператора CREATE DATABASE. - person BobbyShaftoe; 15.12.2008