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

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

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

Проектирование базы данных

Проектирование базы данных

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

Моделируем реальные объекты

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

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

Исходя из этого, база данных должна содержать, как минимум, три таблицы: Customers (Клиенты), Orders (Заказы) и Books (Книги).

Исходная схема таблиц
Customers (Клиенты)
CustomerID
(Идентификатор клиента)
Name (ФИО) Address (Адрес) City (Город)
1 Сидоров Владимир ул. Гоголя 5 Пушкин
2 Пупкин Василий ул. Полевая 14/2 Гатчина
3 Иванов Павел ул. Сталеваров 52 Новгород
Orders (Заказы)
OrderID
(Идентификатор заказа)
CustomerID
(Идентификатор клиента)
Amount (Сумма) Date (Дата)
1 3 100.00 02-Июн-2010
2 1 300.00 15-Июн-2010
3 2 150.00 28-Июн-2010
4 4 350.00 04-Июл-2010
Books (Книги)
ISBN Author (Автор) Title (Название) Prise (Цена)
0-1-1 Смирнов В.И. Разработка веб-сайта с помощью PHP и MySQL 300.00
0-1-2 Смирнов В.И. Используем Adobe Dreamweaver CS3 000.00
0-2-1 Смирнов В.И. Основы веб-дизайна. Графический редактор Adobe Fireworks CS4 300.00

Храние избыточной информации

Мы задавались вопросом: "Почему бы просто не хранить адрес Сидорова Владимира в таблице Orders?". Если данный клиент закажет в магазине несколько книг, сведения о нем придется записывать несколько раз. В итоге таблица Orders может приобрести следующий вид.

OrderID
(Идентификатор заказа)
Amount (Сумма) Date (Дата) CustomerID
(Идентификатор клиента)
ФИО (Имя) Address (Адрес) City (Город)
12 300.00 15-Июн-2010 1 Сидоров Владимир ул. Гоголя 5 Пушкин
13 300.00 20-Июн-2010 1 Сидоров Владимир ул. Гоголя 5 Пушкин
14 000.00 30-Июн-2010 1 Сидоров Владимир ул. Гоголя 5 Пушкин
15 300.00 2--Июл-2010 1 Сидоров Владимир ул. Гоголя 5 Пушкин

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

С таким подходом связаны две проблемы.

Во-первых, имеет место напрасная трата пространства на жестком диске. Зачем сохранять информацию Сидорове Владимере трижды, если достаточно сделать это только один раз?

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

Следует избегать трех типов аномалий обновлений: аномалий модификации, аномалии ввода и аномалии удаления.

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

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

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

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

Использование элементарных значений столбцов

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

Orders (Заказы)
OrderID
(Идентификатор заказа)
CustomerID
(Идентификатор клиента)
Amount (Сумма) Date (Дата) Books Ordered (Заказанные книги)
1 3 300.00 05-Июн-2010 0-1-1, 0-2-1
2 1 300.00 15-Июн-2010 0-2-1
3 2 300.00 20-июн-2010 0-1-1, 0-2-1
4 4 300.00 02-Июл-2010 0-1-1

В силу ряда причин это не очень-то приемлемо. По существу в этом случае в один столбец мы помещаем целую таблицу, связывающую заказы с книгами. Такой подход осложняет ответ на вопрос типа "Сколько экземпляров книги "Разработка веб-сайта с помощью PHP и MySQL" было заказано?" Система не сможет просто подсчитать количество совпадающих записей. Вместо этого ей придется проанализировать значение каждого атрибута, чтобы внутри него найти любые возможные совпадения.

Поскольку в этом случае мы создаем таблицу в таблице, в действительности следует просто создать новую таблицу. Назовем ее Order_Items (Элементы заказа). Схема этой таблицы показана ниже.

Order_Items (Элементы заказа)
OrderID (Идентификатор заказа) ISBN Quantity (Количество)
1 0-1-1 1
2 0-1-1 2
2 0-2-1 1
3 0-2-1 1

Этот подход упрощает процесс поиска заказанных книг.

Приведенная выше таблица обеспечивает связь между таблицами Orders и Books. Использование таблиц подобного типа весьма характерно для случаев, когда два объекта связаны между собой отношением "многие ко многим" — в данном случае один заказ может включать в себя несколько книг, а каждая из книг может быть заказана несколькими людьми.

Выбор ключей

Убедитесь в том, что выбранные ключи уникальны. Как раз для этого мы создали специальные ключи для клиентов (CustomerlD) и для заказов (OrderlD), поскольку у этих реальных объектов может не оказаться идентификатора, претендующего на звание уникального. Книгам создавать подобный идентификатор не требуется, он у них уже есть — это ISBN. Для Order_Item можно, при желании, добавить один ключ, однако комбинация таких атрибутов как Order_Item и ISBN будет уникальной до тех пор, пока заказ двух и больше экземпляров одной и той же книги рассматривается как одна строка. По этой причине в таблице Order_Items присутствует столбец Quantity (Количество).

Вопросы, которые могут быть заданы базе данных

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

Проекты с большим количеством пустых атрибутов

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

Books
ISBN Author (Автор) Title (Название) Prise (Цена) Review (Рецензия)
0-1-1 Смирнов В.И. Разработка веб-сайта с помощью PHP и MySQL 300.00  
0-1-2 Смирнов В.И. Используем Adobe Dreamweaver CS3 000.00  
0-2-1 Смирнов В.И. Основы веб-дизайна. Графический редактор Adobe Fireworks CS4 300.00  
Book_Review (Рецензии на книги)
ISBN Review (Рецензия)
   

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

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

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

Используя альтернативный вариант проекта, можно избежать большинства проблем с нулями. Для этого мы предлагаем второй проект, представленный выше. Здесь в таблице Book_Reviews (Рецензии на книги) размещаются только книги с рецензиями (рецензии прилагаются).

Обратите внимание, что в основе этого подхода лежит идея рецензирования книг единым рецензентом, то есть, между таблицами книг и рецензий существует отношение "один к одному". Если вы хотите поддерживать несколько рецензий для одной и той же книги, возникает отношение "один ко многим", и в качестве начального проекта необходимо выбрать второй вариант. Кроме того, если для книги поддерживается одна рецензия, можно использовать ISBN в качестве первичного ключа таблицы Book_Reviews. При наличии многих рецензий для каждой книги необходимо ввести идентификатор для каждой рецензии.

Типы таблиц

Как правило базы данных состоят из двух типов таблиц:

  • Простые таблицы, описывающие реальные объекты. Они могут иметь ключи к другим простым объектам, которые поддерживают отношения типа "один к одному" и "один ко многим". Например, один клиент может сделать несколько заказов, однако в то же время один заказ приходит от одного клиента. Так, в заказе создается ссылка на клиента.
  • Связывающие таблицы, которые описывают отношения типа "многие ко многим" между двумя реальными объектами, например, между Orders и Books. Такие таблицы зачастую ассоциируются с некоторой реальной транзакцией.

Архитектура баз данных

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

Архитектура

Основная операция веб-сервера проиллюстрирована на рисисунке. Эта система состоит из двух объектов: веб-браузера и веб-сервера. Между ними должен существовать канал связи. Веб-браузер посылает запрос на сервер, сервер отсылает обратно ответ. Для сервера, отсылающего обычные статические страницы, такая архитектура подходит. Архитектура же сайта, который включает в себя базу данных, несколько сложнее.

Отношение типа клиент-сервер межде веб-браузером и веб-сервером требует наличия обмена информацией

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

Базовая архитектура баз данных включает в себя веб-браузер, веб-сервер, сценарный механизм и сервер баз данных

Типичная транзакция базы данных состоит из этапов, обозначенных цифрами на рис. Мы рассмотрим их на примере Интернет-магазина.

  1. Web-браузер пользователя отправляет HTTP-запрос определенной веб-страницы. Например, поиск в интернет-магазине всех книг, написанных В. Смирновым, используя HTML-форму. Страница с результатами поиска называется results.php.
  2. Веб-сервер принимает запрос на results.php, получает файл и передает его механизму РНР на обработку.
  3. Механизм РНР начинает синтаксический анализ сценария. В сценарии присутствует команда подключения к базе данных и выполнения запроса в ней (поиск книг). РНР открывает соединение с сервером MySQL и отправляет необходимый запрос.
  4. Сервер MySQL принимает запрос в базу данных, обрабатывает его, а затем отправляет результаты — в данном случае, список книг — обратно в механизм РНР.
  5. Механизм РНР завершает выполнение сценария, форматируя результаты запроса в виде HTML, после чего отправляет результаты в HTML-формате веб-серверу.
  6. Веб-сервер пересылает HTML в браузер, с помощью которого пользователь просматривает список необходимых книг.

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