Почему (почти) каждому Web-сайту нужна СУРБД

Готовимся к трудностям как можно раньше

Когда ваше Web-приложение достигает определённого размера, ему становится необходима хорошая структура базы данных. В действительности, этот "определённый размер" гораздо меньше, чем полагают почти все разработчики небольших сайтов. Системы управления реляционными базами данных – СУРБД (Relational Data Base Management Systems – RDBMS) не обязательно ограничивают ваши возможности или имеют слишком сложную архитектуру, хотя иногда их плохая репутация приводит разработчиков в ужас. Немного поразмыслив о том, что именно должен делать ваш сайт, можно быстро выработать разумную схему; также несложно предусмотреть расширяемые механизмы хранения, например таблицу конфигурации в серверных компонентах БД.

Дэвид Мерц, писатель, Gnosis Software, Inc.

Дэвид Мерц (David Mertz) - большой знаток в области открытых стандартов и только умеренно пугает многословием. С Дэвидом можно связаться по mertz@gnosis.cx его жизнь описывается более подробно на http://gnosis.cx/dW/. Предложения и комментарии по этой, предыдущей или будущей статьям приветствуются. Можете также посмотреть книгу Дэвида Text Processing in Python.



04.02.2009

Введение

Девиз экстремального программирования (Extreme Programming – XP) поддерживается многими программистами, особенно теми из нас, кто консультирует проекты: принцип "Вам это не понадобится" (You ain't gonna need it – сокращённо YAGNI) означает, что не следует разрабатывать определённый функциональный элемент, если он действительно не требуется вашему клиенту или проекту. В общем и целом, с принципом YAGNI трудно не согласиться; его очевидное преимущество состоит в том, что он позволяет демонстрировать клиентам готовые компоненты на ранней стадии разработки и по ходу всего проекта.

Одна из областей, в которой часто возникают проблемы при попытках избежать осложнений на слишком ранних стадиях, – это откладывание принятия решений по структуре базы данных до тех пор, пока вы не окажетесь в безвыходном положении. Проблема, с которой я сталкиваюсь чаще всего, связана не с выбором собственно СУРБД, а, скорее, с "черновыми" прототипами, на основе которых создаются специализированные решения, где вообще не предусмотрено использование СУРБД (или же они довольствуются реализациями типа MS-Access, SQLite или даже Berkeley DB).

Для огромного большинства динамических Web-сайтов правильным подходом будет использование на сервере какой-то настоящей СУРБД. Перебирая разные СУРБД, вы вряд ли найдёте идеальный вариант, если брать исключительно уровень базы данных, передача доступа данных через вызовы SQL хорошо работает при разбиении схем на компоненты. Если вы действительно определили требования к производительности, со временем может потребоваться оптимизация и настройка на уровне СУРБД; например, может понадобиться выбрать СУРБД или даже специализированную "колоночную" СУБД, если существуют определённые требования к организации хранилищ данных. В любом случае, когда придёт время заняться этими типами оптимизации, у вас будет отлично работающий Web-сайт, и вам будет о чём подумать, помимо вопросов, рассматриваемых в данной статье.


Стадии разработки

Другой лозунг, связываемый с экстремальным программированием – "Заставь это работать, делай правильно, делай быстро" (Make it work, make it right, make it fast) – принадлежит Кенту Беку. Я не хочу превращать эту статью в дискуссию ни за, ни против экстремального программирования. Однако, в определённом смысле некоторые идеи, зачастую связываемые с этой методикой программирования, являются причиной, по которой многие сбитые с толку люди избегают использовать базы данных и правильно сконструированные схемы.

Я согласен с преимуществами создания прототипов на ранних стадиях. "Работающая" модель – это прекрасный первый шаг, демонстрирующий идею. До этого этапа – создания почти статических страниц с небольшим объёмом данных для подстановки (placeholder data) – доходят практически все разработчики. Однако вскоре им приходится делать следующий шаг: "делай правильно". По моему мнению, "правильно" обычно означает использование СУРБД; и более того, это означает использование такой базы, которая делает правильные предположения о базовой структуре данных. Этап "делай быстро" следует отложить на максимально долгий срок, что, конечно же, не означает навсегда, но обычно это дольше, чем полагает большинство разработчиков.

Отступление: конфигурационные таблицы

Одной из областей, в которых используется специализированное хранение данных, являются конфигурационные файлы приложений. Форматы вроде простых файлов, специального XML, YAML, JSON, синтаксиса внутренних данных языка, используемого на вашем сервере (Python, Perl, Ruby, Scheme, PHP), а также других высокоуровневых языков – все они облегчают хранение данных в импортируемых модулях, которые могут иметь такие имена как config.py или config.pl.

Проблема с данными конфигурации состоит в том, что их границы определены неточно. Не существует чётко выраженной границы между "конфигурацией" и "приложением". В результате, по мере того, как возникает потребность в разнообразных "наборах конфигурации", файлы config склонны разрастаться, и, зачастую, размножаться. Нереляционные базы данных типа Berkeley DB часто переносят эту путаницу лишь на немного более высокий уровень.

Я обнаружил, что многие соблазны можно уменьшить, если с самого начала просто использовать таблицу СУРБД под названием configuration. Обычно в этой таблице достаточно трёх колонок (использовать две слишком соблазнительно), например:

SQL, определяющий стандартную таблицу-конфигуратор
-- General configuration
CREATE TABLE configuration (
  key     TEXT,       -- Configuration key
  version TEXT,       -- Allow single switch for multiple and
                      -- experimental application versions
  value   TEXT,       -- Configuration value
  PRIMARY KEY(key)
);

Такая таблица уменьшает соблазн, но не устраняет его полностью. В конце концов, вполне возможно свести все данные, которые обрабатывает ваше приложение, в одну эту таблицу. Однако на практике, как только вам потребуется считывать и записывать информацию о конфигурации через многоуровневые вызовы SQL, гораздо проще "стиснуть зубы" и переместить все данные, которые могли бы находиться в каких-то других таблицах, в схемы с соответствующей структурой. И даже если не сделать этого сразу же, когда вы всё-таки займётесь этим, потребуется лишь изменить SQL в серверном коде, а не выкорчёвывать ваш любимый анализирующий XML- или YAML-код и заменять его кодом SQL и кодом для подключения к базе данных.

Чему способствуют инструменты

Советы, которые даются в нашей статье, предназначены в основном разработчикам, которые создают серверный код с помощью "гибких" или "сверхвысокоуровневых" языков программирования, а именно, Perl, Python, Ruby, PHP и некоторых других. Если же говорить о разработчиках Web-приложений, которые пишут на Java или C++, можно с большой уверенностью предположить, что "более тяжёлый" метод тесно связан с процессом разработки; в этих случаях применение открытого дизайна схемы не " утяжеляет" процесс.

Более того, при использовании любого языка использование среды Web-разработки как бы "сдвигает в сторону" соблазн слишком раннего и слишком персистентного упрощения. То есть, разработчики, использующие CakePHP, Apache Struts, Ruby on Rails, Django или другие среды на основе модели Модель-Представление-Контроллер (MVC), вряд ли в конечном итоге смогут обойтись без СУРБД. Вместо этого они могут повергнуться другой опасности, связанной с упрощением: называется она объектно-реляционные преобразования (Object-Relational Mappings, ORM).

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

В то время как среды, очевидно, становятся всё более обыденным явлением, большой объём кода Web-приложений по-прежнему разрабатывается в виде простого (Fast)CGI, или, по крайней мере, как его эквивалент с помощью серверных модулей типа mod_perl, mod_php, JSP и т. д. При использовании этих "низкоуровневых" методик нетрудно поместить данные в локальные файлы в различных структурированных или частично структурированных форматах. Более того, то, как ведёт себя по умолчанию большинство Web-серверов в плане отражения структуры локальной файловой системы в обслуживаемых URL, делает локальное хранение данных ещё менее очевидным. Помимо вышеперечисленных факторов, многие типы исходных данных заранее упаковываются в текстовых или двоичных форматах, поэтому их конвертация в структурированные в соответствии со схемой таблицы может действительно потребовать дополнительных усилий. Например, задача некоторых Web-приложений состоит в обслуживании контента, полученного из log-файлов; CSV-дампов; электронных таблиц; созданных пользователями документов с нечёткой структурой в форматах типа reStructuredText или MarkDown; или из формата wiki.

Концептуальные различия существуют даже между разными "скриптовыми языками", многие из них отражаются в синтаксисе кода и организации модулей. Perl, а в несколько меньшей степени Ruby и Python, до абсурда облегчают анализ разнообразных форматов данных. В CPAN имеется анализатор для любого самого малоизвестного текстового формата, о котором вы могли только слышать, а также для большинства двоичных форматов. Напротив, в PHP или Java анализировать текстовые форматы сложнее, и, что ещё важнее, (в особенности для PHP), функции доступа к СУРБД являются "встроенными", а не просто импортируемыми модулями. Ясно, что написать одну или несколько строк кода, импортирующего привязку к СУРБД, нетрудно, однако сам факт, что это – отдельная операция, увязывается с концепцией Perl и Python "анализируем любой формат" и делает подход "просто используй файловую систему" более привлекательным применительно к этим двум языкам.


ACID

Причины, по которым для вашего Web-приложения потребуется СУРБД, в общем то, те же самые, почему она необходима для любого приложения. Не все приложения создаются с помощью MVC-сред, однако почти все приложения могут выиграть от хотя бы концептуального разграничения структуры данных, бизнес-логики и уровня презентации. Более того, важна не только структура данных, но их целостность.

Сокращение ACID (Atomicity, Consistency, Isolation, Durability – атомарность, непротиворечивость, изоляция, долговечность) – точно отражает гарантии целостности (и надёжности), которые мы ожидаем от СУРБД. Более того, создание "неформальных" решений, в которых не используется СУРБД, обычно заканчиваются принятием специальных мер для реализации (некоторых) этих гарантий, а связанные с ними тонкости обычно понимаются неправильно.

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

Атомарность: любая транзакция выполняется полностью, или вообще не выполняется. Действие пользователя может обновлять множество значений данных. При отказе во время обновления набора файлов, размещённых в файловой системе Web-сервера, может возникнуть такая ситуация, что один файл был обновлён, а другой, связанный с ним, – нет. Или что ещё хуже, отдельные файлы могут остаться в повреждённом состоянии (например, при неполной записи могут возникать данные, не соответствующие формату данных спецификации файла). Все мы знаем, как восприимчивы Интернет-транзакции к разнообразным отказам (многие из них не контролируются нашими серверами): отказы должны причинять как можно меньше ущерба.

Непротиворечивость: разница между непротиворечивостью и атомарностью очень небольшая. Оба эти принципа имеют своей целью сделать так, чтобы ваши данные всегда "имели смысл". Однако атомарность гарантирует лишь выполнение целой последовательности шагов, при этом необязательно, чтобы сами эти шаги были логически последовательными. Аналогично, журналирующая файловая система предоставляет некоторую гарантию атомарности: каждый файл записывается или изменяется либо целиком, либо вообще не изменяется. Журналирование не гарантирует отношение содержимого файлов друг к другу. Журналирующая файловая система не гарантирует, что содержимое каждого файла будет уникальным, а также то, что определённое содержимое или файл не может существовать, если уже существует другой файл. Но подобные гарантии – это именно то, что определяет теория реляционных БД (например, первичные и вторичные ключи в примере), и это как раз та информация о наших данных, которой мы располагаем на стадии проектирования.

Изоляция: это довольно просто. У вашего приложения есть – или может быть – несколько пользователей, и действия одного не должны противоречить результатам действий другого. Не пытайтесь реализовывать изоляцию на скорую руку, например, написав самостоятельно процесс демона, который будет ставить изменения в очередь. Я и сам впадал в этот грех, однако создатели оттестированных СУРБД уже решили эту проблему, и сделали это гораздо лучше, чем смогла бы ваша команда.

Долговечность: если транзакция выполнена успешно, вы её не потеряете. По-настоящему гарантировать долговечность сложно. Использовать журналы транзакций и моментальные снимки – это одно, гораздо сложнее гарантировать, что транзакция переживёт любой катастрофический отказ, какой можно только вообразить. (Поддерживать выполнение транзакций во время сильного землетрясения в том месте, где расположен ваш пул серверов, непросто). В любом случае, обычные СУРБД очень хорошо обеспечиваю долговечность транзакций.

Инструменты СУРБД

Стоит упомянуть некоторые вещи, которые при использовании СУРБД вы получаете "на халяву"; в противном случае на их реализацию придётся затратить большие усилия. Простейшая из этих вещей – старые добрые индексы. Находить нужные данные становится всё труднее по мере увеличения объёма данных. Для организации данных файловых систем часто появляются различные решения, которые держатся на соглашениях об именах, изоленте и честном слове. Общее у них то, что индексные поля, встроенные в СУРБД, решают большинство подобных проблем лучше. Да, оптимизация индекса представляет собой сложную задачу в некоторых случаях (типы индексов, партицирование таблиц, составные типы индексов, объединение таблиц, опции кэширования и т. д.), но по крайней мере это известная проблема, и существуют эксперты, которые помогут её решить. И в большинстве случаев готовые решения, встроенные в современные СУРБД, достаточно хороши.

Я часто сталкивался с ещё одной ситуацией, в которой разумно избегать использования СУРБД: полнотекстовый поиск. Существует большое количество достаточно хороших инструментов для индексирования и запроса наборов файлов в файловой системе или в конце URL-адресов. Многие из них сложнее применять для индексирования текстовых полей произвольного формата в базах данных. К счастью, в комплекте с современными СУРБД идут собственные полнотекстовые поисковые механизмы.


Заключение

В подобной статье трудно во всех подробностях рассказать о принципах разработки, относящихся к вашему Web-приложению. Каждое приложение имеет своё назначение, свои требования и ограничения. Но весь мой опыт консультанта и разработчика говорит о том, что привычка не использовать СУРБД, или, по крайней мере, откладывать её применение на значительно более долгий срок, чем нужно, встречается при быстрой разработке прототипов слишком часто, а это влияет практически на все процессы, использующиеся при разработке Web-приложений.

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

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


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

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



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

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


  • Bluemix

    Узнайте больше информации о платформе IBM Bluemix, создавайте приложения, используя готовые решения!

  • developerWorks Premium

    Эксклюзивные инструменты для построения вашего приложения. Узнать больше.

  • Библиотека документов

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, SOA и web-сервисы
ArticleID=368169
ArticleTitle=Почему (почти) каждому Web-сайту нужна СУРБД
publish-date=02042009