Druzya.org
Возьмемся за руки, Друзья...
 
 
Наши Друзья

Александр Градский
Мемориальный сайт Дольфи. 
				  Светлой памяти детей,
				  погибших  1 июня 2001 года, 
				  а также всем жертвам теракта возле 
				 Тель-Авивского Дельфинариума посвящается...

 
liveinternet.ru: показано количество просмотров и посетителей

Библиотека :: Компьютеры и Программирование :: Начинаем изучать MySQL
 [Весь Текст]
Страница: из 157
 <<-
 
Начинаем изучать MySQL 

Предисловие
В мире программирования 1990-е годы можно по праву назвать десятилетием 
программного обеспечения с открытым кодом (Open Source software). Движение Open 
Source оставило свой след практически в каждом уголке технологий - от Linux до 
Perl и от карманных компьютеров до мэйнфреймов. Это влияние особенно сильно в 
области серверных приложений среднего масштаба, в которых часто нуждаются 
некоммерческие организации и малые предприятия и которыми пренебрегают 
нацеленные на коммерческий успех производители.
В первые два десятилетия компьютерного века серверы среднего масштаба 
встречались достаточно редко. Компьютеры были дорогими изделиями, имевшимися в 
больших учреждениях, таких как банки и университеты. Громадные серверы, 
работавшие в режиме разделения времени, обеспечивали вычислительными мощностями 
целые корпорации. Большая часть использовавшегося на этих системах программного 
обеспечения была такой же грандиозной, как сами серверы. Поскольку единственный 
компьютер обслуживал нужды нескольких подразделений, если не всей организации, 
ему приходилось удовлетворять запросы всех пользователей.
На другом конце спектра располагался персональный компьютер. В результате 
революции, произведенной ПК, вместо одного компьютера в крупной компании 
появился один компьютер в каждом доме. Хотя мощность этих компьютеров легко 
позволяла удовлетворить потребности отдельного пользователя, между 
возможностями и стоимостью персональных вычислений и вычислений в масштабе 
организации существовал большой разрыв.
Более всего этот разрыв был очевиден в области управления данными. Приложения, 
работающие с базами данных на больших машинах, содержали в себе все мыслимые 
функции. Из-за многоцелевой сущности этого программного обеспечения в него 
включалась любая необычная функция, если она была нужна хотя бы одному 
пользователю. Появились также приложения баз данных, удовлетворяющие 
потребности управления данными для отдельных пользователей. Однако если базы 
данных для мэйнфреймов были слишком громоздки для потребностей среднего уровня, 
то возможности персональных баз данных были слишком ограниченны.
В первой половине 1990-х «жалкий» персональный компьютер достиг такого уровня, 
когда фактически оказался мощнее мэйнфреймов прежних лет. И если аппаратная 
часть более не была препятствием для вычислений среднего уровня, то таковым 
служило отсутствие доступного по цене программного обеспечения. Чтобы 
удовлетворить потребности некоммерческих организаций и малых предприятий в 
хранении данных, требовались доступные по цене операционная система и система 
управления базами данных. Одна половина этой задачи была решена с появлением 
таких дешевых и мощных операционных систем для серверов, как FreeBSD и Linux.
Решение той части задачи, которая относится к управлению базами данных, дают 
MySQL и mSQL. Они обладают мощью и гибкостью, сохраняя в то же время 
компактность и эффективность. В особенности MySQL удалось уместить большой 
набор возможностей в очень маленьком и быстром ядре. Хотя то и другое ядро 
далеко не обладают полным набором функций, имеющихся в дорогих корпоративных 
базах данных, они обладают вполне достаточными характеристиками, чтобы 
удовлетворить потребности управления базами данных среднего масштаба.
Кому предназначен этот диск
В основном книга предназначена для двух групп читателей. Прежде всего это те, 
кто заинтересован в использовании MySQL и mSQL с точки зрения администратора 
баз данных или программиста баз данных. С другой стороны, для каждого, 
желающего узнать об администрировании реляционных баз данных и программировании,
 не раскошеливаясь при этом на лицензию, приобретаемую у кого-нибудь из 
«больших парней», MySQL или mSQL окажется отличной отправной точкой. Если вы 
начинаете с MySQL или mSQL, то эта книга для вас.
С точки зрения администратора баз данных, книга охватывает основные методы 
создания и управления базами данных и таблицами в MySQL и mSQL. Мы не 
ограничиваемся простейшими вещами и даем советы по настройке производительности 
и устранению неполадок, чтобы позволить вам наиболее эффективно использовать 
свои приложения для MySQL или mSQL. Наконец, подробно описываются все 
инструментальные средства, поставляемые с MySQL и mSQL. Предварительного 
знакомства с SQL и реляционными базами данных не предполагается.
Для программистов баз данных описаны все основные программные интерфейсы 
наиболее популярных языков программирования систем клиент/сервер и приложений 
Интернет. При описании интерфейсов для отдельных языков программирования 
предполагается наличие у читателя основных навыков работы с рассматриваемым 
языком. К. примеру, в главе, посвященной Java™, предполагается, что читатель 
умеет писать простые приложения на Java и хочет теперь узнать, как заставить 
свои приложения общаться с базами данных MySQL или mSQL.
Ввиду огромной популярности MySQL и mSQL в Интернет естественно остановиться на 
создании CGI-приложений для MySQL и mSQL. Поэтому разработчики приложений для 
Интернет найдут в этой книге полезное описание того, как управлять своими 
сайтами с помощью MySQL или mSQL. В этих главах требуется самое незначительное 
знание CGI, но все же предполагается знакомство читателя с основами 
используемого языка программирования.
Цель книги на даном диске
На первый взгляд, цель книги очевидна: MySQL и mSQL принадлежат к числу 
наиболее популярных приложений, исходный код которых открыт. Они предоставляют 
практические преимущества программного обеспечения Open Source, несмотря даже 
на то, что их лицензии несколько более ограниченны, чем полагается для 
категории Open Source. Однако для каждого, достаточно долго изучавшего MySQL и 
mSQL, ответ не так прост.
Наиболее часто жалобы, касающиеся проектов Open Source, связаны с тем, что, как 
правило, отсутствует подробная и понятная документация. Однако в отношении 
MySQL и mSQL проблема едва ли состоит в отсутствии документации в сети.
Для MySQL есть великолепное бесплатное руководство, доступное на http://www.
mysql.com. В нем полностью освещены синтаксис MySQL, инсталляция и API на языке 
С, а также администрирование базы данных и настройка производительности. 
Аналогично, по mSQL существует хорошее, хотя, возможно, менее подробное 
руководство по адресу: http://www.hughes.com.au.
Еще более осложняет дело то, что MySQL и mSQL не стоят на месте, они быстро 
развиваются. MySQL не просто не стоит на месте: благодаря усилиям, в основном, 
Майкла Видениуса (Michaelle «Monty» Wide-nius) MySQL движется вперед со 
скоростью курьерского поезда. Поэтому будьте готовы к тому, что некоторые 
данные в этой книге опережают старые версии или отстают от новых.
Но погодите ставить эту книгу обратно на полку! Обо всех этих проблемах мы 
знали до того, как взялись за работу над ней. Есть существенная причина, по 
которой написание книги на данную тему не только оправданно, но и важно. Мир 
MySQL и mSQL не ограничивается лишь двумя базами данных. Огромная 
распространенность в сообществе Open Source вызвала появление массы 
инструментальных средств для администрирования и разработки приложений, которые 
входят в комплекты MySQL и mSQL. Поэтому задачей данной книги является создание 
единого и цельного руководства по ядру этих баз данных, а также интерфейсам 
программирования и инструментальным средствам, используемым для создания 
конечных решений, связанных с ба-
зами данных. Во всяком случае, лежа в ванне или сидя в самолете, проще читать 
книгу, чем электронную документацию.
Как пользоваться этой книгой
Мы разделили книгу на три части. В первой части описываются начальный этап и 
управление базами данных MySQL и mSQL. Она служит основой для второй части, в 
которой показано, как создавать приложения, использующие базы данных MySQL или 
mSQL. Наконец, третья часть служит полным справочником для получения быстрой 
подсказки по всем API и инструментальным средствам, описанным в первых двух 
частях.
Если вы принадлежите к отмеченной выше аудитории, то попадаете в одну из трех 
категорий:
* Пользователи и администраторы MySQL.
* Пользователи и администраторы mSQL.
* Не приняли решения, но определенно собираетесь использовать MySQL или mSQL.
Мы предназначили первую часть книги администраторам баз данных. Вначале 
рассматривается общий вопрос о том, что же такое база данных. Возможно, у вас 
уже есть опыт работы с базами данных и тогда, конечно, изложение слишком 
элементарно для вас. Все же посмотрите в конце Главы 1 «Введение в реляционные 
базы данных» краткое введение в MySQL и mSQL. Особый интерес оно представляет 
для тех, кто еще не решил, какую базу данных ему использовать, и хочет кратко 
ознакомиться с обеими.
Глава 2 «Проектирование баз данных» может вначале показаться не представляющей 
ценности, но на самом деле это одна из важнейших глав в книге. Правильное 
проектирование базы данных важно как для администраторов, так и для 
программистов, если ставится задача создания приложений для работы с базами 
данных, которые достаточно легко масштабировать в случае необходимости внесения 
изменений. Правильное проектирование базы данных необходимо также для 
обеспечения высокой производительности ее работы.
Глава 3 «Установка» описывает процесс инсталляции ядра для обеих баз данных.
Если вы выбрали конкретное ядро базы данных, то можете пропустить либо главу 4 
«MySQL», либо главу 5 «mSQL». Каждая глава посвящена ядру одной из баз данных и 
не имеет никакого отношения к пользователям другого ядра. Однако если вы еще не 
сделали свой выбор, то чтение этих двух глав может быть решающим для вас.
Мы завершаем часть, предназначенную администраторам, обсуждением вариантов SQL, 
представленных в MySQL и mSQL. Хотя во многих случаях первая глава не 
представляет интереса для программистов, у них может возникнуть необходимость 
время от времени обращаться к ней, даже если они имеют опыт работы с SQL. Тем 
же, кто раньше не работал с SQL, явно необходимо прочесть эту главу.
Вторая часть начинается с обзора модели программирования клиент/ сервер. 
Изложение ведется на самом общем уровне, но закладывает основу понимания 
взаимодействия между базами данных и программированием приложений, ведущего к 
созданию крепких приложений, работающих с базами данных. Конечно, если у вас 
есть опыт разработки клиент-серверных приложений в других средах, то это 
обсуждение архитектуры может быть для вас повторением давно пройденного. 
Остальные главы этой части посвящены программированию на отдельных языках или с 
помощью отдельных инструментальных средств. Особый интерес для 
Web-программистов представляют главы по Perl, Java, Python и PHP.
Завершает книгу справочный раздел по всем инструментальным средствам и API, 
рассмотренным в книге.
О MySQL и mSQL
Мы попытались в этой книге одинаково полно осветить MySQL и mSQL. Написание 
одной книги, описывающей обе СУБД, оправданно, поскольку они весьма схожи. Они 
не имеют общего кода, но сходство является преднамеренным. Для единообразия мы 
всегда используем выражения «MySQL и mSQL» или «MySQL или mSQL», если 
какой-либо факт справедлив для обеих СУБД. Первым указывается MySQL, поскольку 
мы произвольно решили, что наиболее популярный продукт будет идти первым. Если 
упоминается лишь одно из названий MySQL или mSQL, то это значит, что фраза 
особо отмечает факт, связанный с этим конкретным ядром. За исключением глав, 
посвященных исключительно одному из продуктов, вы можете считать, что наличие в 
предложении лишь одного из названий MySQL или mSQL означает его справедливость 
только для одной базы данных.
Обозначения, используемые в книге
Моноширинный шрифт
Используется для всего, что находится внутри программы, включая ключевые слова, 
команды SQL и имена переменных. Этот шрифт используется также для программных 
примеров, результатов выполнения команд и файлов конфигурации системы.
Жирный моноширинный шрифт
Обозначает данные, вводимые пользователем.
Моноширинный курсив
Обозначает передаваемый вами элемент, например, имя файла или переменную.
Курсив
Используется для обозначения имен каталогов, файлов, программ, команд Unix и 
URL. Этот шрифт используется также для введения новых терминов и для 
выразительности.
Символ восклицательный знак используется для обозначения подсказки, предложения 
или общего замечания.
Символ крестика используется для обозначения предупреждения.

Часть I.
Начинаем изучение MySQL и mSQL
Первая часть этой книги познакомит вас с понятием и архитектурой реляционной 
базы данных. Мы углубляемся здесь в детали самых первых шагов изучения MySQL и 
mSQL. Возможно, вы уже имеете опыт общения с одним из этих великолепных 
программных продуктов и ждете, что книга станет вашим помощником в работе. Если 
это так, вы можете просто сосредоточиться на выбранном вами продукте и не 
отвлекаться на остальные. С другой стороны, если вы еще не сделали свой выбор, 
этот раздел расскажет вам об особенностях MySQL и mSQL, дабы вы не ошиблись в 
выборе. К концу этой части, после благополучной установки и конфигурирования 
вашей базы данных, вы будете готовы к подробному изучению программирования баз 
данных, которому мы посвятили вторую часть нашей книги.
Глава №1.
Введение в реляционные базы данных
Большие корпоративные вычислительные центры в течение многих лет используют 
сложные и дорогие программные продукты для работы с базами данных. 
Использование этих обладающих полным набором возможностей и тщательно 
оптимизированных программных систем является единственным способом управления 
теми объемами корпоративной информации, которые существуют в больших компаниях.
Традиционно пользователи домашних компьютеров вообще не нуждались в базах 
данных. Они хранят свои данные - адреса, списки дел и т. д. - в маленьких 
файлах или специализированных покупных программах, вроде электронных таблиц или 
телефонных справочников.
Но появилась новая категория пользователей компьютеров, находящихся между двумя 
этими крайностями. Они поддерживают информационные массивы средних размеров, 
которые требуются в небольших организациях, таких как вновь образовавшиеся 
предприятия и некоммерческие организации. Иногда эти пользователи не столько 
малы, сколько являются территориально самостоятельными частями более крупной 
компании, либо этими новыми пользователями являются просто частные лица, 
заинтересованные в поддержке сложных, но частных данных, таких, например, как 
перечень песен любимых ансамблей, который можно выложить на персональную 
страницу в Интернет. Если вы тот человек, которому нужна база данных, готовый 
немного потрудиться, чтобы установить ее, и не хотите тратить шестизначные 
суммы на программный продукт вкупе с отрядом поддерживающих его программистов, 
то эта книга - для вас.
Эта книга вводит вас в мир разработки малых баз данных с помощью двух 
популярных продуктов, MySQL и mSQL. Мы начнем с введения в реляционные базы 
данных и проектирование приложений в реляцион-
ном мире. Если у вас есть опыт работы с реляционными базами данных и их 
проектированием, вы можете сразу перейти к главе 4, «MySQL» или главе 5, «mSQL»,
 где мы углубляемся в детали практической работы с MySQL и mSQL. Но, если вы 
собираетесь это сделать, обратите внимание, что в конце данной главы мы 
приводим краткое введение и сравнение основных возможностей этих продуктов. В 
оставшейся части книги в основном излагается применение MySQL и mSQL для 
создания и поддержки того типа приложений, которые важны для таких 
пользователей, как вы.
Что такое база данных?
База данных - это, попросту говоря, собрание данных. Примером неэлектронной 
базы данных является общественная библиотека. В библиотеке хранятся книги, 
периодические издания и прочие документы. Когда нужно отыскать в библиотеке 
какие-либо данные, вы просматриваете каталог либо указатель периодики или даже 
справляетесь у библиотекаря. Другой пример - неупорядоченная стопка бумаг, 
которая может находиться у вас на столе. Когда нужно что-то найти, вы роетесь в 
этой кипе, пока не найдете нужный листок. Эта база данных может работать (или 
нет), поскольку ее размер крайне мал. Стопка бумаг, несомненно, будет 
неэффективна для большого объема данных, такого, например, как библиотечное 
собрание. Библиотека без картотеки, индекса периодики и библиотекаря останется 
базой данных, только ей нельзя будет пользоваться. Поэтому, чтобы библиотека 
имела какую-то ценность, она должна быть организована каким-либо способом. 
Вашей стопкой бумаг можно было бы пользоваться более уверенно при наличии 
упорядоченной системы их хранения (тогда, возможно, вы не потеряли бы тот 
телефонный номер!). Поэтому, уточняя наше определение, мы скажем, что база 
данных - организованное собрание данных.
У библиотеки и стопки бумаг много сходства. Та и другая являются базами данных, 
состоящими из документов. Нет никакого смысла, однако, соединять их вместе, 
поскольку ваши документы интересны только вам, а библиотека содержит документы, 
представляющие общий интерес. Каждая из баз данных отвечает определенному 
назначению и организована в соответствии с этим назначением. Поэтому мы еще 
несколько улучшим наше определение: база данных есть собрание данных, которые 
организованы и хранятся в соответствии с некоторым назначением.
У традиционных бумажных баз данных много недостатков. Им требуется огромное 
физическое пространство. Библиотеки занимают целые
здания, и поиск в них осуществляется относительно медленно. Каждый работавший в 
библиотеке знает, что для поиска порой требуется немало времени. Библиотеки 
также утомительно содержать в порядке, и для поддержания соответствия 
содержимого полок и каталогов требуется чрезмерно много времени. Хранение базы 
данных в электронном виде помогает решать эти вопросы.
MySQL и mSQL не являются базами данных. Фактически они являются компьютерными 
программами, позволяющими пользователю создавать, поддерживать базы данных и 
управлять ими. Такой тип программного обеспечения известен как Системы 
управления базами данных (СУБД). СУБД действует как посредник между физической 
базой данных и ее пользователями.
Когда вы впервые начинали работать с данными в электронной форме, вы почти 
наверняка использовали плоский файл. Файл файловой системы является электронной 
версией стопки бумаг на вашем столе. Вероятно, вы пришли к заключению, что этот 
тип специальной электронной базы больше не отвечает вашим потребностям. СУБД 
является следующим логическим шагом для удовлетворения ваших потребностей при 
хранении информации, и MySQL и mSQL являются первыми шагами в мир систем 
управления реляционными базами данных.
Что такое реляционная база данных?
Согласно нашему определению, база данных является организованным собранием 
данных. Реляционная база данных организует данные в таблицы. Вероятно, проще 
проиллюстрировать понятие таблицы, чем пытаться объяснить его. Таблица 1-1 
является примером таблицы, которая может появиться в базе данных по книгам.


Таблица 1-1. Таблица книг
ISBNНазваниеАвтор0-446-67424-9 
0-201-54239-Х 
0-87685-086-7 
0-941423-38-7L.A. Confidential
An Introduction to Database Systems 
Post Office 
The Man with the Golden ArmJames Ellroy 
C.J. Date
Charles Bukowski 
Nelson AlgrenВ таблице 1-2 и таблице 1-3 показаны две таблицы, которые могут 
появиться в базе данных Национальной Баскетбольной Ассоциации.
Таблица 1-2. Таблица команд НБА
№ командыНазваниеТренер1Golden State WarriorsP.J. Carlesimo2Minnesota 
TimberwolvesFlip Saunders3L.A. LakersKurt Rambis4Indiana PacersLarry Bird  
Таблица 1-3. Таблица игроков НБА
ИмяПоложение№ командыRik SmitsЦентровой4Kevin GarnettНападающий2Kobe Bryant
Защитник3Reggie MillerЗащитник4Stephen MarburyЗащитник2Shaquille O'Neal
Центровой3Позже мы разберемся в специфике таблиц, а пока обратите внимание на 
некоторые особенности этих примеров. У каждой таблицы есть название, несколько 
колонок и строки, содержащие данные в каждой из этих колонок. Реляционная база 
данных представляет все ваши данные в таких таблицах, как эти, и обеспечивает 
операции извлечения, генерирующие новые таблицы из уже имеющихся. В результате 
пользователь видит всю базу данных в виде таблиц.
СУБД для реляционной базы данных часто называется Реляционной системой 
управления базами данных (РСУБД). MySQL и mSQL являются примерами РСУБД.
Какое отношение ко всему этому имеет SQL? Нам необходимо иметь некий способ 
взаимодействия с базой данных. Нужно определять таблицы, а также извлекать, 
добавлять, обновлять и удалять данные. SQL (Structured Query Language - язык 
структурированных запросов) является компьютерным языком, используемым для 
выражения операций с базой данных, организованной в реляционной форме (то есть 
в виде таблиц). SQL является принятым в отрасли стандартом языка, на котором 
говорит большинство программистов баз данных и который используется 
большинством пакетов РСУБД. Как следует из их названий, механизм работы с MySQL 
и mSQL основан на SQL. Из-за своей простоты, однако, они поддерживают лишь 
подмножество современного стандарта SQL - SQL2. Мы обсудим, в чем именно 
состоит отличие поддерживаемого MySQL и mSQL диалекта SQL от стандарта, в 
последующих главах.
Приложения и базы данных
Согласно нашему определению, база данных есть организованное собрание данных, 
служащее определенной цели. Простого наличия СУБД недостаточно, чтобы у вашей 
базы данных появилось назначение. Назначение определяется тем, как вы 
используете свои данные. Представьте себе библиотеку, в которой никто никогда 
не читает книги. Будет немного смысла в хранении и организации всех этих книг, 
если они никогда не используются. Теперь представьте себе библиотеку, в которой 
нельзя поменять книги или добавить новые. Полезность библиотеки как базы данных 
будет со временем уменьшаться, поскольку невозможно заменить устаревшие книги и 
добавить новые. Короче, библиотека существует для того, чтобы люди могли читать 
книги и находить нужную им информацию.
Базы данных существуют для того, чтобы люди могли с ними взаимодействовать. В 
случае электронных баз данных взаимодействие происходит не непосредственно с 
базой данных, а косвенно — с помощью программного обеспечения. До появления 
Всемирной паутины (World Wide Web) базы данных обычно использовались большими 
корпорациями для поддержки различных деловых функций - бухгалтерии и финансов, 
контроля поставок и складского учета, планирования производства, учета 
персонала и т. п. Интернет и более сложные задачи домашних вычислений 
содействовали перемещению потребностей в использовании баз данных за пределы 
больших корпораций.
Базы данных и WWW
Область, в которой развитие баз данных имело особо взрывной характер, и где 
отличились MySQL и mSQL, - это разработка приложений для Интернет. По мере 
роста спроса на все более сложные и надежные приложения для Интернет растет и 
спрос на базы данных. База данных сервера может поддерживать многие важные 
функции в Интернет. Фактически, любое содержание веб-страниц может управляться 
базой данных.
Рассмотрим в качестве примера торговца по каталогу, который хочет опубликовать 
свой каталог в WWW и принимать заказы через Интернет. Если опубликовать каталог 
в виде HTML-файла, то кому-то придется вручную редактировать каталог всякий раз,
 когда добавляется новый товар или изменяется цена. Если же вместо этого 
держать данные каталога в реляционной базе данных, то становится возможной 
публикация изменений в каталоге в реальном масштабе времени путем простого 
изменения в базе данных сведений о товаре и цене. Становится также возможной 
интеграция каталога с имеющимися системами электронной обработки заказов. Таким 
образом, использование базы данных для управления таким веб-сайтом дает 
очевидные преимущества как продавцу, так и покупателю.
Вот как веб-страница обычно взаимодействует с базой данных. База данных 
находится на вашем веб-сервере или другой машине, с которой ваш сервер может 
обмениваться данными (хорошая СУБД позволяет легко организовать такое 
распределение обязанностей). Вы помещаете на веб-страницу форму, в которую 
пользователь вводит свой запрос или данные, которые нужно передать. После 
передачи формы на сервер последний запускает написанную вами программу, которая
извлекает переданные пользователем данные. Эти программы чаще всего делаются в 
виде CGI-сценариев или серверных приложений на Java, но возможно также 
встраивание программы прямо в HTML-страницу. Все эти методы мы рассмотрим в 
нашей книге.
Теперь ваша программа знает, какие данные нужны пользователю или что он хочет 
внести в базу данных. Программа формирует команду SQL для выборки или изменения 
данных, а база данных чудесным образом делает все остальное. Результаты, 
получаемые от базы данных, ваша программа может оформить в виде новой 
HTML-страницы и отправить обратно пользователю.
MySQL и mSQL
MySQL и mSQL - очень схожие, дешевые, компактные и быстрые базы данных. В этой 
книге описаны обе эти базы данных, что связано с их крайним сходством. Однако 
между ними есть и очень важные различия, о которых мы также обязательно 
расскажем. Обе системы поддерживают программирование на С, Perl, Java (через 
API Java DataBase Connectivity - JDBC) и Python. Благодаря инструментальным 
средствам, которые MySQL и mSQL предоставляют для этих языков, можно создавать 
полноценные клиент-серверные приложения и интегрированные с базами данных 
веб-сайты, не тратя на это состояния. Это приятное известие для маленьких фирм, 
публикующих данные в Интернет, и всех тех, кто разрабатывает небольшие 
клиент-серверные приложения и не может позволить себе приобрести коммерческие 
продукты.
Дешевизна, а в некоторых случаях бесплатность, MySQL и mSQL не дается даром. Ни 
одна из этих СУБД полностью не поддерживает SQL. В них отсутствуют некоторые 
возможности, которые могут понадобиться при создании более сложных приложений. 
В некоторых случаях приходится также несколько больше потрудиться, разрабатывая 
клиентскую часть, чтобы достичь того, что дорогие базы данных предоставили бы 
вам даром. Однако мы научим вас, как делать переносимые приложения MySQL и mSQL,
 чтобы вы попробовали использовать какие-либо базы данных с более мощными 
внутренними механизмами, если это вам понадобится, и вам не пришлось бы 
переписывать весь код, чтобы перейти на большую базу данных. Для понимания того,
 что же могут предложить эти две СУБД, лучше всего кратко рассмотреть их 
историю.
История mSQL
До 1994 года вам не удалось бы обзавестись РСУБД с поддержкой SQL, не потратив 
при этом изрядной суммы денег. На рынке тогда доминировали Oracle, Sybase и 
Informix. Эти системы управления базами данных были разработаны для обработки 
огромных объемов данных с очень сложными взаимосвязями. Они были мощными, 
обладали множеством возможностей, а также требовали больших вычислительных 
ресурсов и были дороги. В те времена еще нельзя было за $2000 купить сервер с 
200-MHz Pentium. Ресурсы, требуемые для этих СУБД, стоили десятки тысяч 
долларов.
У больших корпораций и крупных университетов не возникало проблем с тем, чтобы 
потратить за год несколько миллионов долларов на такие комплекты серверов и 
СУБД. Малым организациям и частным пользователям приходилось довольствоваться 
слабыми настольными приложениями. Несколько дешевых СУБД с архитектурой клиент/ 
сервер в то время существовало, но ни в одной из них не использовался SQL в 
качестве языка запросов. Наиболее примечательной из них была Postgres, имевшая 
общее происхождение с коммерческой базой данных Ingres. К несчастью, Postgres 
требовала примерно тех же ресурсов, что и ее коммерческие аналоги, не давая 
преимущества использования SQL в качестве языка запросов. В то время в Postgres 
использовалась разновидность языка QUEL, называвшаяся PostQUEL.
Дэвид Хьюз
Часть диссертации, которую Давид Хьюз (David Hughes) (известный также как 
Bamby) писал в Университете Бонд в Австралии, была посвящена разработке системы 
мониторинга и управления группой систем из одного или нескольких мест. Проект 
носил название Minerva Network Management System. Главным элементом Minerva 
была база данных для хранения данных обо всех компьютерах в сети. Будучи 
студентом университета и не имея доступа к серверам, на которых работали 
большие коммерческие базы данных, Хьюз решил, что Postgres - это очевидное 
решение, вполне отвечающее его потребностям.
Его коллеги предложили сделать SQL стандартным языком запросов для Minerva. В 
конце концов, SQL был и остается самым общепринятым стандартом языка запросов. 
Основываясь на SQL, Minerva могла бы использоваться в любой точке света, где 
установлена поддерживающая SQL СУБД. Иными словами, SQL предоставлял 
возможности Minerva гораздо более широкому кругу пользователей, нежели PostQUEL,
 ограничивавший его пользователями Postgres. В конечном итоге оказалось, что 
сегодня даже Postgres поддерживает SQL.
Желание пользоваться стандартом SQL, с одной стороны, и отсутствие доступа к 
базе данных, поддерживающей SQL, - с другой, поставили Хьюза в трудное 
положение. Если использовать в Minerva язык запросов, основанный на SQL, то не 
удастся найти СУБД с соответствующим механизмом работы. Не имея возможности 
приобрести дорогую РСУБД, Хьюз нашел творческое решение проблемы: выход в том, 
чтобы создать программу, «на лету» транслирующую запросы SQL в запросы PostQUEL.
 Такая программа должна была перехватывать все
посылаемые Minerva предложения SQL, преобразовывать их в PostQUEL и результат 
пересылать дальше в Postgres. Хьюз написал такую программу и назвал ее miniSQL, 
или mSQL.
От транслятора PostQUEL к РСУБД
В течение некоторого времени такая конфигурация удовлетворяла потребности Хьюза.
 Для Minerva было безразлично, какая СУБД используется, если только она 
понимает SQL, и она считала, что Postgres понимает SQL, поскольку в середине 
находился mSQL, производивший трансляцию в PostQUEL. К несчастью, по мере роста 
Minerva ее работа стала значительно замедляться. Стало ясно, что ни Postgres, 
ни другая большая РСУБД не смогут поддерживать тот небольшой набор возможностей,
 который требовался для Minerva, на тех ограниченных ресурсах, которые были ей 
доступны. Например, для Minerva требовалось одновременное подключение к 
нескольким базам данных. Для поддержки этого Postgres требовал одновременного 
запуска нескольких экземпляров* сервера базы данных. Кроме того, несколько 
потенциальных участников проекта не могли принять в нем участие, поскольку 
Postgres не поддерживал их системы, а они не могли позволить себе купить 
дорогую СУБД с поддержкой SQL.
Оказавшись перед лицом этих проблем, Хьюз пересмотрел свое отношение к Postgres.
 По своим размерам и сложности она, возможно, превышала потребности Minerva. 
Большинство запросов, генерируемых Minerva, представляли собой простые 
операторы INSERT, DELETE и SELECT. Все остальные возможности, имевшиеся в 
Postgres и снижавшие производительность, просто не требовались для Minerva.
У Хьюза уже был mSQL, осуществлявший трансляцию SQL. Ему требовалось только 
добавить хранилище данных и возможности извлечения данных, чтобы получить 
сервер базы данных, удовлетворявший его потребности. Эта эволюция привела к 
существующему на сегодняшний день mSQL.
История MySQL
Было бы ошибкой рассматривать MySQL просто как ответ на недостатки mSQL. Ее 
изобретатель Майкл Видениус (известный также как Monty) из шведской компании 
ТсХ работает с базами данных с 1979 г. До недавнего времени Видениус был в ТсХ 
только разработчиком. В 1979 г. он разработал для внутрифирменного 
использования средство управления базами данных под названием UNIREG. После 
1979 года UNIREG была переписана на нескольких разных языках и расширена для 
поддержки больших баз данных.
Каждый из процессов, в котором выполняется одна и та же-программа, называется 
экземпляром этой программы, поскольку он занимает память точно так же, как 
экземпляр переменной занимает память программы.
В 1994 г. ТсХ стала разрабатывать приложения для WWW, используя для поддержки 
этого проекта UNIREG. К несчастью, UNIREG из-за больших накладных расходов не 
могла успешно использоваться для динамической генерации веб-страниц. И ТсХ 
начала присматриваться к SQL и mSQL. В то время, однако, mSQL существовала 
только в виде релизов 1.x. Как мы уже говорили, версии mSQL 1.x не поддерживали 
никаких индексов и поэтому по производительности уступали UNIREG.
Видениус связался с Хьюзом, автором mSQL, чтобы узнать, не заинтересуется ли 
тот подключением mSQL к обработчику В+ ISAM в UNIREG. Хьюз, однако, к тому 
времени уже далеко продвинулся на пути к mSQL 2 и создал средства для работы с 
индексами. ТсХ решила создать сервер баз данных, более соответствующий ее 
нуждам.
В ТсХ работали неглупые люди, которые не стали изобретать велосипед. Они взяли 
за основу UNIREG и использовали утилиты сторонних разработчиков для mSQL, число 
которых все увеличивалось, написав для своей системы API, который, по крайней 
мере первоначально, почти совпадал с API для mSQL. В результате любой 
пользователь mSQL, желавший перейти на более богатый возможностями сервер баз 
данных ТсХ, должен был внести в свой код очень незначительные изменения. Тем не 
менее исходный код новой базы данных был полностью оригинальным.
К маю 1995 г. у ТсХ имелась база данных, удовлетворявшая внутренние потребности 
компании, - MySQL 1.0. Бизнес-партнер фирмы Давид Аксмарк (David Axmark) из 
Detron HB стал убеждать ТсХ представить свой сервер в Интернет. Цель 
представления сервера в Интернет -использование бизнес-модели, пионером которой 
был Аладдин Петер Дейч (Aladdin Peter Deutsch). Результатом стали очень гибкие 
авторские права, которые делают MySQL «более бесплатной», чем mSQL.
Что касается названия, то Видениус говорит об этом так: «До конца не ясно, 
откуда идет название MySQL. В ТсХ базовый каталог, а также значительное число 
библиотек и утилит в течение десятка лет имели префикс «mу». Вместе с тем мою 
дочь (на несколько лет младше) тоже зовут Май (My). Поэтому остается тайной, 
какой из двух источников дал название MySQL».
С момента публикации MySQL в Интернет она перенесена на многие UNIX-системы, 
под Win32 и OS/2. ТсХ считает, что MySQL использует около 500 000 серверов.
Основные изменения, внесенные в текущую рекомендованную версию 3.22:
* Усиленная защита.
* Ускорение соединений, анализа запросов SQL и улучшенный оптимизатор запросов.
* Поддержка большего числа операционных систем.
* INSERT DELAYED.
* Команды GRANT и REVOKE.
* CREATE INDEX и DROP INDEX.
* Уровни блокировки HIGH_PRIORITY и LOW_PRIORITY для операторов SELECT, INSERT, 
UPDATE и DELETE.
* Новая команда FLUSH, применимая к TABLES, HOSTS, LOGS и PRIVILEGES.
* Новая команда KILL в SQL, действующая, как kill в Unix или msqladmin.
* Поддержка выражений в предложении НAVIN G.
* Сжатие протокола клиент/сервер.
* Сохранение параметров программы по умолчанию в файлах my.cnf. Основные 
изменения в разрабатываемой версии 3.23:
* Таблицы, переносимые напрямую между различными ОС и ЦП.
* Временные таблицы и таблицы HEAP, хранимые только в ОЗУ.
* Поддержка больших файлов (63 бит) на операционных системах, которые их 
поддерживают.
* Подлинные поля чисел с плавающей точкой.
* Комментарии к таблицам.
* Шаблон процедуры ANALYSE().
* Функции, определяемые пользователем.
* Значительное ускорение обработки SELECT DISTINCT.
* COUNT(DISTINCT).
Дальнейшие усовершенствования, запланированные в 3.23, включают в себя 
поддержку вложенных операторов SELECT и поддержку репликации баз данных, 
обеспечивающей распределение нагрузки между несколькими серверами и 
восстановление в случае аппаратных сбоев.
MySQL является очень быстро развивающейся платформой баз данных благодаря 
существованию армии добровольцев-программистов, помогающих строить ее дальше на 
крепком основании. Поэтому не следует удивляться, если что-либо, верное в 
момент написания этой главы, больше не соответствует действительности.
MySQL или mSQL?
Конечно, мы еще не дали вам сведений, достаточных для принятия решения. Чтобы 
полностью оценить существующие на сегодняшний день различия между двумя 
продуктами, необходимо прочесть эту книгу и понять тонкости, представленные 
нами здесь. На первый взгляд кажется несомненным, что предпочтение следует 
отдать MySQL. mSQL с течением времени отстала и сейчас уступает в скорости 
работы. Дэвид Хьюз неудовлетворен и работает над версией 2.1, в которой должны 
быть устранены многие нынешние недостатки. А в это же время MySQL движется 
вперед со скоростью света.
Выбор mSQL может быть продиктован имеющимся у вас инструментарием. Поскольку 
mSQL существует дольше, вам может оказаться легче найти инструмент, отвечающий 
вашим специфическим потребностям. К примеру, в момент написания этой книги 
только для mSQL имелся драйвер JDBC, соответствующий JDBC 2.0. Конечно, 
положение изменится к тому времени, когда вы прочтете книгу. Тем не менее при 
выборе базы данных следует руководствоваться соображениями такого типа.
Независимо от того, какую базу данных вы выберете, вы окажетесь в выигрыше. Обе 
эти базы данных обеспечат большее быстродействие, чем при любом другом выборе. 
Для объективного сравнения этих баз данных друг с другом и другими продуктами 
рекомендуем посетить страницу http://www.mysql.com/crash-me-choose.htmy. Она 
находится на домашней странице MySQL, но представленные на ней критерии можно 
свободно проверить, а сама страница сделана очень хорошо.
Глава №2.
Проектирование баз данных
После установки на компьютере СУБД у вас может возникнуть сильный соблазн сразу 
начать создание базы данных, не задумываясь о планировании. Как и в других 
случаях разработки программного обеспечения, такой подход оправдан лишь при 
решении простейших задач. Если вы рассчитываете, что ваша база данных должна 
будет поддерживать хоть какую-то степень сложности, немного планирования и 
проектирования, в конечном итоге, несомненно сбережет ваше время.
Проектирование баз данных
Предположим, у вас есть большая коллекция компакт-дисков, и вы хотите создать 
базу данных, чтобы отслеживать ее. Прежде всего, нужно определить, какие данные 
вы собираетесь хранить. Неплохо начать с того, чтобы подумать, а зачем, 
собственно, вам хранить эти данные. В нашем случае мы, скорее всего, хотим 
иметь возможность найти диск по исполнителю, названию и песне. Раз мы хотим 
искать эти пункты, они должны быть включены в базу данных. Помимо того, часто 
полезно просто перечислить пункты, которые нужно отслеживать. Возможен такой 
список: название CD, фирма звукозаписи, название ансамбля, название песни. В 
качестве отправной точки выберем для хранения данных таблицу, представленную 
как таблица 2-1.
Таблица 2-1. База данных CD, состоящая из одной таблицы
Band NameCD TitleRecord LabelSongsStevie WonderTalking BookMotownYou Are the 
Sunshine of My Life, Maybe Your Baby, Superstition, . . .Miles Davis Quintet
Miles SmilesColumbiaOrbits, Circle, . . .Wayne ShorterSpeak No EvilBlue Note
Witch Hunt, Fee-Fi-Fo-FumHerbie HancockHeadhuntersColumbiaChameleon, Watermelon 
Man, . . .Herbie HancockMaiden VoyageBlue NoteMaiden Voyage(Для краткости мы 
опустили большую часть -песен.) На первый взгляд, эта таблица нам подходит, 
поскольку в ней есть все необходимые данные. При более близком рассмотрении, 
однако, мы сталкиваемся с некоторыми проблемами. Возьмем, к примеру, Herbie 
Hancock. Название ансамбля повторяется дважды - для каждого CD. Это повторение 
неприятно по нескольким причинам. Во-первых, при вводе данных нам приходится 
вводить одно и то же несколько раз. Во-вторых, что более важно, при изменении 
каких-либо данных приходится изменять их в нескольких местах. Что если, к 
примеру, в Herbie вкралась орфографическая ошибка? Пришлось бы исправлять 
данные в двух строках. Та же проблема возникнет, если имя Herbie Hancock в 
будущем изменится (а ля Jefferson Airplane или John Cougar). С добавлением к 
нашей коллекции новых дисков Herbie Hancock увеличивается объем работы, 
необходимой для поддержания непротиворечивости данных.
Другая проблема, вызванная наличием в базе данных всего одной таблицы, связана 
с тем, как хранятся названия песен. Мы храним их, как список песен, в одной 
колонке. Мы столкнемся с кучей проблем, если попытаемся разумно использовать 
эти данные. Представьте себе, как мы будем вводить и поддерживать этот список 
песен. А что если мы захотим хранить еще и длительность песен? Или пожелаем 
осуществлять поиск по названию песни? Довольно быстро становится ясно, что 
хранить песни в таком виде нежелательно.
Вот тут начинает играть свою роль проектирование баз данных. Одна из важнейших 
задач проектирования баз данных - устранение из нее избыточности. Для этого 
используется прием, называемый нормализацией. Прежде чем приступить к 
нормализации, обсудим некоторые фундаментальные понятия реляционных баз данных. 
Модель данных -это диаграмма, показывающая конструкцию вашей базы данных. Она 
состоит из трех основных элементов - сущностей, атрибутов и связей. Пока 
остановимся на сущностях и атрибутах, а о связях поговорим позднее.
Сущности в базе данных
Сущность - это важная вещь или объект, сведения о котором нужно сохранить. Не 
все вещи являются сущностями, а только те, данные о которых должны быть 
сохранены. Сведения о сущностях имеют вид атрибутов и/или связей. Если некий 
кандидат на то, чтобы быть сущностью, не имеет атрибутов или связей, в 
действительности он не является сущностью. В модели базы данных сущности 
представляются в виде прямоугольника с заголовком. Заголовок является именем 
сущности.
Атрибуты сущности
Атрибут описывает данные о сущности, которые нужно сохранить. У каждой сущности 
ноль или более атрибутов, описывающих ее, и каждый атрибут описывает в точности 
одну сущность. Каждый экземпляр сущности (строка таблицы) имеет в точности одно 
значение, возможно, равное NULL, для каждого из своих атрибутов. Значение 
атрибута может быть числом, строкой символов, датой, временем или другим 
базовым значением данных. На первом этапе проектирования базы данных, 
логическом моделировании, нас не заботит то, каким образом будут храниться 
данные.
NULL лежит в основе проблемы, связанной с отсутствующей информацией. Он 
специально используется тогда, когда какая-то часть данных отсутствует. 
Рассмотрим, к примеру, ситуацию, когда на CD нет данных о длительности каждой 
песни. У каждой песни есть длительность, но, глядя на коробку, вы не можете 
сказать, какова она. Хранить длительность как О нежелательно, поскольку это 
было бы неверно. Вместо этого вы записываете длительность как NULL. Если вы 
считаете, что можно сохранить ее как 0 и использовать 0 для обозначения 
«неизвестной длины», то можете попасть в одну из тех западней, которые привели 
к проблеме 2000-го года. В старых системах не только год хранится как две цифры,
 но и придается особое значение величине 9-9-99.
В нашем примере база данных ссылается на ряд объектов - CD, название CD, 
название ансамбля, песни и название фирмы звукозаписи. Какие из них являются 
сущностями, а какие - атрибутами?
Модель данных
Обратите внимание, что мы определяем несколько видов данных (название CD, 
название ансамбля и т. д.), относящихся к каждому CD, и без которых описать CD 
совершенно невозможно. Поэтому CD является одним из тех объектов, которые мы 
хотим описать, и, похоже, является сущностью. Начнем разработку модели данных с 
изображения CD как сущности. На рис. 2-1 показана наша единственная сущность в 
модели данных.

Рис. 2-1. Сущность «CD» в модели данных
По общепринятому соглашению об именовании сущностей имя сущности должно быть в 
единственном числе. Поэтому мы называем таблицу, в которой хранятся CD «CD», а 
не «CDs». Мы используем это соглашение, поскольку каждая сущность дает имя 
экземпляру. Например, «San Francisco 49ers» является экземпляром сущности 
«Футбольная команда», а не «Футбольные команды».
На первый взгляд кажется, что оставшаяся часть базы данных описывает CD. Это 
указывает на то, что она содержит атрибуты CD. На рис. 2-2 они добавлены к 
сущности CD рис. 2-1. В модели данных атрибуты представлены как имена, 
перечисленные в прямоугольнике сущности.
Эта диаграмма проста, но мы еще не закончили. В действительности, мы только 
начали. Ранее мы говорили, что целью моделирования данных является устранение 
избыточности с помощью приема, называемого нормализацией. У нашей базы данных 
прекрасная диаграмма, но мы не покончили с избыточностью, как намеревались. 
Пора нормализовать нашу базу данных.

Рис. 2-2. Сущность «CD» с атрибутами
Нормализация
Е. Ф. Кодд (Е. F. Codd), занимавшийся исследовательской работой в IBM, впервые 
представил концепцию нормализации в нескольких важных статьях, написанных в 
1970-е годы. Задача нормализации остается той же самой и сегодня: устранить из 
базы данных некоторые нежелательные характеристики. В частности ставится задача 
устранить некоторые виды избыточности данных и благодаря этому избежать 
аномалий при изменении данных. Аномалии изменения данных - это сложности при 
операциях вставки, изменения и удаления данных, возникающие из-за структуры 
базы данных. Дополнительным результатом нормализации является конструкция, 
хорошо соответствующая реальному миру. Поэтому в результате нормализации модель 
данных становится более ясной.
Например, предположим, что мы ошиблись при вводе «Herbie Hancock» в нашу базу 
данных и хотим исправить ошибку. Нам потребовалось бы рассмотреть все диски 
этого исполнителя и исправить имя. Если изменения производятся с помощью 
приложения, позволяющего одновременно редактировать только одну запись, нам 
придется редактировать много строк. Было бы гораздо лучше запомнить имя «Herbie 
Hancock» лишь один раз и редактировать его в одном месте.
Первая нормальная форма (1NF)
Общее понятие нормализации подразделяется на несколько «нормальных форм». 
Говорят, что сущность находится в первой нормальной форме, когда все ее 
атрибуты имеют единственное значение. Чтобы признать сущность находящейся в 
первой нормальной форме, нужно удостовериться в том, что каждый атрибут 
сущности имеет единственное значение для каждого экземпляра сущности. Если в 
каком-либо атрибуте есть повторяющиеся значения, сущность не находится в 1NF.
Вернувшись к нашей базе данных, мы обнаруживаем, что повторяющиеся значения 
есть в атрибуте Song (песня), поэтому очевидно, что база не находится в 1NF. 
Сущность с повторяющимися значениями указывает на то, что мы упустили еще по 
крайней мере одну сущность. Обнаружить другие сущности можно, взглянув на 
каждый атрибут и задавшись вопросом «что описывает эта вещь?»
Что описывает атрибут Song? Он перечисляет все песни на CD. Поэтому Song - это 
еще один объект, о котором мы собираем данные, и, возможно, он является 
сущностью. Мы добавим его в свою диаграмму и придадим атрибут Song Name 
(название песни). Чтобы покончить с сущностью Song, спросим себя, чем еще мы 
хотели бы ее охарактеризовать. Мы отметили ранее, что длительность песни мы 
также хотели бы сохранить. Новая модель данных показана на рис. 2-3.

Рис. 2-3. Модель данных с сущностями CD и Song
Теперь, когда Song Name и Song Length являются атрибутами сущности Song, мы 
имеем модель данных с двумя сущностями в 1NF. К сожалению, мы не указали 
никакого способа связать вместе CD и Song.
Уникальный идентификатор
Прежде чем обсуждать связи, мы должны применить к сущностям еще одно правило. У 
каждой сущности должен быть однозначный идентификатор, который мы будем 
называть ID. ID есть атрибут сущности, к которому применимы следующие правила:
* Он уникален для каждого экземпляра сущности.
* Для каждого экземпляра сущности он имеет значение, отличное от NULL в течение 
всего срока существования экземпляра.
* В течение всего времени существования экземпляра его значение не меняется.
ID очень важен, поскольку позволяет узнать, с каким из экземпляров сущности мы 
имеем дело. Выбор идентификатора также существенен, потому что он используется 
для моделирования связей. Если после выбора ID для сущности вы обнаружили, что 
он не удовлетворяет одному из перечисленных правил, это может повлиять на всю 
вашу модель данных.
Новички в моделировании данных часто делают ошибку, выбирая в качестве ID 
неподходящие атрибуты. Если, к примеру, у вас есть сущность Person (человек, 
лицо), может возникнуть соблазн выбрать в качестве идентификатора Name 
(фамилию), поскольку она есть у каждого лица и не меняется. Но что если лицо 
вступает в брак или законным образом хочет изменить фамилию? Или вы допустили 
ошибку при первоначальном вводе фамилии? При каждом из этих событий нарушается 
третье правило для идентификаторов. Еще хуже то, что фамилия окажется не 
уникальной. Если вы не можете стопроцентно гарантировать, что атрибут Name 
уникален, вы нарушаете первое правило для идентификаторов. Наконец, вы считаете,
 что у каждого экземпляра Person фамилия отлична от NULL. Но вы уверены, что 
всякий раз, вводя первоначальные данные в базу, будете знать фамилию? Ваш 
процесс может быть организован так, что при начальном создании записи фамилия 
может быть неизвестна. Из этого следует извлечь тот урок, что при выборе 
неидентифицирующего атрибута в качестве идентификатора возникает много проблем.
Выход в том, чтобы изобрести идентифицирующий атрибут, не имеющий никакого 
иного смысла, кроме как служить идентифицирующим атрибутом. Поскольку этот 
атрибут искусственный и никак не связан с сущностью, мы имеем над ним полный 
контроль и можем обеспечить его соответствие правилам для уникальных 
идентификаторов. На рис. 2-4 к каждой из наших сущностей добавлен искусственный 
ID. На диаграмме уникальный идентификатор изображается как подчеркнутый атрибут.


Рис. 2-4. Сущности CD и Song со своими уникальными идентификаторами
Связи
Идентификаторы наших сущностей позволяют моделировать их связи. Связь описывает 
бинарное отношение между двумя сущностями. Связь может существовать также 
внутри одной сущности. Такая связь называется рекурсивной. Каждая сущность, 
участвующая в связи, описывает-другую и описывается ею. Каждая сторона связи 
имеет две составляющих - имя и степень.
У каждой стороны связи есть имя, описывающее связь. Возьмем две гипотетические 
сущности — Служащий и Отдел. Один вариант связи между ними состоит в том, что 
Служащий «приписан» к Отделу. Этот Отдел «отвечает» за Служащего. Таким образом,
 связь со стороны Служащий называется «приписан», а со стороны Отдел - 
«отвечает».
Степень, называемая также кардинальным числом, показывает, сколько экземпляров 
описывающей сущности должны описывать один экземпляр описываемой сущности. 
Степень выражается с помощью двух разных значений- «один-к-одному» (1) и 
«один-ко-многим» (М). Служащий приписан одновременно только к одному отделу, 
поэтому у сущности Служащий связь с сущностью Отдел «один-к-одному». В обратном 
направлении, отдел отвечает за многих служащих. Поэтому мы говорим, что у 
сущности Отдел связь с сущностью Служащий «один-ко-многим». В результате в 
Отделе может быть и только один Служащий.
Иногда полезно выразить связь словами. Один из способов - вставить разные 
составляющие направления связи в следующую формулу:
сущность1имеет [одну и только одну одну или много] сущностъ2
Согласно этой формуле связь между Служащим и Отделом можно выразить так:
Каждый Служащий должен быть приписан к одному и только одному 
Отделу.
Каждый Отдел может отвечать одному или многим Служащим.

Рис. 2-5. Анатомия связи

Рис. 2-6. Связь CD-'Song
Можно использовать эту формулу для описания сущностей в нашей модели данных. В 
каждом CD содержится много или одна Song, и каждая Song содержится хотя бы в 
одном CD. В нашей модели данных эту связь можно показать, проведя линию между 
двумя сущностями. Степень обозначается прямой линией для связи «один и только 
один» и «птичьей лапой» для связи «один-ко-многим>>. На рис. 2-5 показаны эти 
обозначения.
Как это применимо к связи между Song и CD? На практике Song может содержаться 
на многих CD, но для нашего примера мы этим пренебрежем. На рис. 2-6 показана 
модель данных с обозначенными связями.
Прочно установив связи, мы можем вернуться к процессу нормализации и опять 
улучшить нашу схему. Пока мы лишь нормализовали повторяющиеся песни, 
преобразовав их в отдельную сущность, и смоделировали связь между ней и 
сущностью СD.
Вторая нормальная форма (2NF)
Говорят, что сущность находится во второй нормальной форме, если она уже 
находится в первой НФ, и каждый неидентифицирующий атрибут зависит от всего 
уникального идентификатора сущности. Если некий атрибут не зависит полностью от 
уникального идентификатора сущности, значит, он внесен ошибочно и должен быть 
удален. Нормализуйте такой атрибут либо найдя сущность, к которой он относится, 
либо создав новую сущность, в которую он должен быть помещен.

Рис. 2-7. Модель данных с новой сущностью Artist
В нашем примере «Herbie Hancock» является Band Name (названием ансамбля) для 
двух разных CD. Это показывает, что Band Name не полностью зависит от 
идентификатора CD ID. Это дублирование представляет собой проблему, поскольку 
если мы допустили ошибку при вводе «Herbie Hancock», придется исправлять 
значение в нескольких местах. Это указывает нам, что Band Name должно быть 
частью новой сущности, связанной с CD. Как и раньше, мы решаем эту задачу, 
задав вопрос: «Что описывает название ансамбля?» Оно описывает ансамбль, или, 
вообще говоря, исполнителя. Исполнитель - еще один объект, о котором мы 
собираем данные, и потому, возможно, является сущностью. Мы добавим его к нашей 
схеме с атрибутом Band Name. Поскольку исполнитель может не быть ансамблем, мы 
переименуем атрибут как Artist Name. На рис. 2-7 показано новое состояние 
модели.
Правда, не показаны связи для новой таблицы исполнителей. Ясно, что у каждого 
Artist может быть один или много CD. У каждого CD может быть один или несколько 
Artist. Это показано на рис. 2-8.

Рис. 2-8. Связи сущности Artist в модели данных
Вначале мы присвоили атрибут Band Name сущности CD. Поэтому было естественным 
установить прямую связь между Artist и CD. Но верно ли это? При ближайшем 
рассмотрении оказывается, что следует установить прямую связь между Artist и 
Song. У каждого Artist есть одна или много Song. Каждая Song исполняется одним 
и только одним Artist. Правильные связи показаны на рис. 2-9.
Это не только более разумно, чем связь между Artist и CD, но и решает проблему 
дисков-сборников.

Рис. 2-9. Подлинная связь между Artist и остальной частью модели данных
Виды связей
При моделировании связей между сущностями важно определить оба направления 
связи. После определения обеих сторон связи мы приходим к трем основным видам 
связей. Если оба конца связи имеют степень «один и только один», то связь 
называется «один-к-одному». Как мы позднее убедимся, связи «один-к-одному» 
встречаются редко. В нашей модели данных их нет.
Если одна сторона имеет степень «один или много», а другая сторона имеет 
степень «один и только один», то это связь «один-ко-многим» или «1-к-М». Все 
связи в нашей модели - это связи «один-ко-многим». Этого можно было ожидать, 
поскольку связи «один-ко-многим» наиболее распространены.
И наконец, последний тип связей - когда обе стороны имеют степень 
«один-ко-многим». Такого типа связи называются «многие-ко-мно-гим», или «М-к-М».
 В предыдущей версии нашей модели данных связь Artist-CD имела тип 
«многие-ко-многим».
Уточнение.связей
Как отмечалось ранее, связи «один-к-одному» очень редки. На практике, если в 
процессе моделирования вы столкнетесь с такой связью, следует внимательнее 
изучить свой проект. Такая связь может означать, что две сущности являются на 
самом деле одной, и если это так, их следует объединить в одну.
Связи «многие-ко-многим» встречаются чаще, чем «один-к-одному». В этих связях 
часто есть некоторые данные, которыми мы хотим охарактеризовать связь. Взглянем,
 например, на предыдущую версию нашей модели данных на рис. 2-8, в которой была 
связь «многие-ко-многим» между Artist и CD. Artist имеет связь с CD, поскольку 
у исполнителя есть одна или несколько Song на этом CD. Модель данных на рис. 
2-9 фактически является другим представлением этой связи «многие-ко-многим».
Все связи «многие-ко-многим» нужно разрешать с помощью следующей технологии:
1. Создайте новую сущность, иногда называемую сущностью-связкой. Назовите ее 
подходящим образом. Если вы не можете придумать подходящее название, образуйте 
его из сочетания имен связываемых сущностей, например ArtistCD. В нашей модели 
Song является сущностью-связкой для связи Artist-CD.
2. Свяжите новую сущность с двумя исходными. Каждая из исходных сущностей 
должна иметь связь «один-ко-многим» с сущностью-связкой.
3. Если в новой сущности нет очевидного уникального идентификатора, введите в 
нее идентифицирующие атрибуты исходных сущностей и сделайте эту пару уникальным 
идентификатором новой сущности.
Почти всегда обнаружатся дополнительные атрибуты, принадлежащие новой сущности. 
Если это не так, то все равно необходимо разрешить связь «многие-ко-многим», 
иначе возникнут проблемы при переводе вашей модели данных в физическую схему.

Рис. 2-10. Наша модель данных во второй нормальной форме
Еще о 2NF
Наша модель все еще не приобрела вторую нормальную форму. Значение атрибута 
Record Label (фирма звукозаписи) имеет только одно значение для каждого CD, но 
одно и то же значение его присутствует в нескольких СD. Ситуация сходна с той, 
которая была с атрибутом Band Name. И точно так же дублирование указывает на то,
 что Record Label должна быть частью отдельной сущности. Каждая Record Label 
выпускает один или много CD. Каждый CD выпускается одной и только одной Record 
Label. Модель этой связи представлена на рис. 2-10.
Третья нормальная форма (3NF)
Сущность находится в третьей нормальной форме, если она уже находится во второй 
нормальной форме и ни один неидентифицирующий атрибут не зависит от каких-либо 
других неидентифицирующих атрибутов. Атрибуты, зависящие от других 
неидентифицирующих атрибутов, нормализуются путем перемещения зависимого 
атрибута и атрибута, от которого он зависит, в новую сущность.
Если бы мы пожелали отслеживать адрес Record Label, то столкнулись бы с 
проблемами для третьей нормальной формы. В сущности Record Label должны быть 
атрибуты State Name (название штата) и State Abbreviation (сокращенное название 
штата). Хотя для учета CD эти данные и не нужны, мы добавим их к нашей модели 
для иллюстрации проблемы. На рис. 2-11 показаны адресные данные в сущности 
Record Label.

Рис. 2-11. Адресная информация о фирме звукозаписи в нашей базе данных
Значения State Name и State Abbreviation удовлетворяют первой нормальной форме, 
поскольку имеют только одно значение в каждой записи сущности Record Label. 
Проблема в том, что State Name и State Abbreviation взаимозависимы. Иными 
словами, поменяв State Abbreviation для какой-либо Record Label, мы вынуждены 
будем также изменить State Name. Мы произведем нормализацию, создав сущность 
State с атрибутами State Name и State Abbreviation. На рис. 2-12 показано, как 
связать эту новую сущность с сущностью Record Label.
Теперь, получив третью нормальную форму, мы можем сказать, что наша модель 
данных нормализована. Существуют и другие нормальные формы, имеющие значение с 
точки зрения проектирования баз данных, но их рассмотрение находится за 
пределами нашей книги. В большинстве случаев третьей нормальной формы 
достаточно, чтобы гарантировать правильность проекта базы данных.

Рис. 2-12. Модель данных в третьей нормальной форме
Методология логического моделирования данных
Теперь у нас есть завершенная логическая модель данных. Вспомним, какие шаги 
нужно осуществить, чтобы получить ее:
1. Выявить и смоделировать сущности.
2. Выявить и смоделировать связи между сущностями.
3. Выявить и смоделировать атрибуты.
4. Указать уникальный идентификатор для каждой сущности.
5. Провести нормализацию.
На практике процесс редко происходит в такой последовательности. Как показывает 
наш пример, часто возникают желание и необходимость перескакивать между 
сущностями, связями, атрибутами и идентификаторами. Важно не столько строго 
следовать последовательности шагов, сколько выявить и зафиксировать все данные, 
необходимые для правильного моделирования системы.
Модель данных, которую мы создали в этой главе, очень проста. Мы рассказали, 
как создать модель, соответствующую по типу и сложности тем базам данных, с 
которыми вы, скорее всего, столкнетесь, разрабатывая базы данных для MySQL или 
mSQL. Мы не коснулись целой массы приемов проектирования и понятий, которые не 
имеют большого значения при проектировании маленьких баз данных и могут быть 
найдены в любом учебнике, посвященном проектированию баз данных.
Проектирование физической базы данных
С какой целью мы создавали логическую модель данных? Вам нужно создать базу 
данных, чтобы хранить информацию о CD. Модель данных - это только промежуточный 
шаг. В конечном итоге вы хотели бы получить базу данных MySQL или mSQL, в 
которой можно хранить данные. Как это сделать? При проектировании физической 
базы данных логическая модель переводится в набор операторов SQL, которые 
определяют вашу базу данных MySQL или mSQL.
Поскольку MySQL и mSQL являются реляционными базами данных, относительно 
несложно перевести логическую модель, подобную описанной, в физическую базу 
данных MySQL или mSQL. Вот правила перевода:
1. Объекты становятся таблицами в физической базе данных.
2. Атрибуты становятся колонками в физической базе данных. Для каждой колонки 
нужно выбрать подходящий тип данных.
3. Уникальные идентификаторы становятся колонками, не допускающими значение 
NULL. В физической базе данных они называются первичными ключами (primary keys).
 Вы можете также пожелать создать уникальный индекс по идентификатору, чтобы 
обеспечивать уникальность. Учтите, что в mSQL нет понятия первичного ключа, 
есть просто уникальные индексы. К MySQL это не относится.
4. Отношения моделируются в виде внешних ключей (foreign keys). Мы коснемся их 
позднее.
Применив эти правила к нашей модели (исключая адресную информацию по фирмам 
звукозаписи), получим физическую базу данных, представленную в таблице 2-2.
Таблица 2-2. Определения физических таблиц для базы, данных CD
ТаблицаКолонкаТип данныхПримечанияCDCDIdINTprimary keyCDTitleTEXT(50)Artist
ArtistldINTprimary keyArtistNameTEXT(50)SongSongldINTprimary keySongName
TEXT(50)RecordLabelRecordLabelldINTprimary keyRecordLabelNameTEXT(50)primary 
keyПервое, на что вы можете обратить внимание: в нашей физической схеме из всех 
названий объектов удалены пробелы. Это вызвано тем, что названия нужно 
преобразовать в вызовы SQL, создающие таблицы, поэтому названия таблиц должны 
удовлетворять правилам SQL для образования имен. Кроме того, все первичные 
ключи мы сделали типа INT. Поскольку эти атрибуты искусственные, мы можем 
приписать им любой индексируемый тип. То, что они имеют тип INT, почти 
полностью результат нашего произвола. Почти, поскольку на практике поиск по 
числовым полям в большинстве баз данных осуществляется быстрее, и поэтому 
выгодно назначать первичными ключами числовые поля. Однако мы могли бы выбрать 
для ключевых полей тип CHAR, и все работало бы прекрасно. Выбор должен 
основываться на ваших критериях выбора идентификаторов.
Для остальных колонок установлен тип TEXT с длиной 50. Такое определение 
годится и для MySQL, и для mSQL. Для MySQL, впрочем, лучше было бы выбрать 
VARCHAR, но это несущественно для нашего примера. Выбор правильного типа данных 
для колонок очень важен, но мы не будем сейчас на этом останавливаться, 
поскольку не касались еще типов данных, поддерживаемых MySQL и mSQL.
Теперь у нас есть отправная точка для физической схемы. Мы еще не перевели 
отношения в физическую модель данных. Как указывалось ранее, после уточнения 
логической модели у вас должны остаться отношения типа «один-к-одному» и 
«один-ко-многим» - отношения «М-к-М» разрешаются через таблицы-связки. 
Отношения моделируются путем добавления внешних ключей к одной из участвующих в 
них таблиц. Внешний ключ - это уникальный идентификатор или первичный ключ 
таблицы на другом конце отношения.
Позднее мы коснемся типов данных, поддерживаемых MySQL и mSQL. В каждой из них 
свои правила относительно того, какие типы данных можно индексировать. Ни в 
одной из них, например, нельзя индексировать поля типа TEXT. Поэтому 
недопустимо иметь колонку первичного ключа типа TEXT.
Чаще всего отношение имеет тип «1-к-М». Ему соответствует первичный ключ со 
стороны «1», помещенный в таблицу на стороне «многие». В нашем примере это 
означает, что нужно сделать следующее:
* Поместить колонку RecordLabelId в таблицу CD.
* Поместить колонку CDId в таблицу Song.
* Поместить колонку Artistic! в таблицу Song. Полученная схема показана в 
таблице 2-3.
Таблица 2-3. Физическая модель данных для базы данных CD
ТаблицаКолонкаТип данныхПримечанияCDCdldINTprimary keyCDTitleTEXT(50)
RecordLabelldINTforeign keyArtistArtistldINTprimary keyArtistNameTEXT(50)Song
SongldINTprimary keySongNameTEXT(50)CdldINTforeign keyArtistldINTforeign key
RecordLabelRecordLabelldINTprimary keyRecordLabelNameTEXT(50)В нашей модели нет 
связей типа «один-к-одному». Если бы они были, то нужно было бы взять одну из 
таблиц и ввести в нее колонку внешнего ключа, соответствующую первичному ключу 
другой таблицы. Теоретически не важно, которую из таблиц вы выберете, но 
практические соображения могут определять, какую из колонок лучше сделать 
внешним ключом.
Теперь у нас есть полная физическая схема базы данных. Осталось перевести эту 
схему на SQL. Для каждой таблицы в схеме вы пишете одну команду CREATE TABLE. 
Обычно для поддержки уникальности создается уникальный индекс по первичным 
ключам.
В некотором смысле мы сейчас забегаем вперед. Вы, возможно, не знакомы с SQL, а 
в задачи данной главы не входит знакомство с версиями SQL, поддерживаемыми 
MySQL и mSQL. Все же, вот два простых сценария для создания базы данных CD. 
Первый сценарий, пример 2-1, составлен для MySQL, пример 2-2 — для mSQL.
Пример 2-1. Сценарий создания базы данных CD в MySQL
CREATE TABLE CD (CDID INT NOT NULL,
RECORD_LABEL_I INT, CD_TITLE TEXT, PRIMARY KEY (CD_ID))
CREATE TABLE Artist (ARTIST_ID INT NOT NULL, ARTIST_NAMETEXT,
PRIMARY KEY (ARTIST_ID)) CREATE TABLE Song (SONG_ID INT NOT NULL, CD_ID INT, 
SONG_NAME TEXT, PRIMARY KEY (SONG_ID))
CREATE TABLE RecorLabel(RECORD LABEL_ID INT NOT NULL, RECORD_LABEL_NAME TEXT, 
PRIMARY KEY(RECORD_LABEL_ID))
Пример 2-2. Сценарий создания базы данных CD в mSQL
CREATE TABLE CD (CD_ID INT NOT NULL,
RECORD_LABEL_IDINT, CD_TITLE TEXT(50))
CREATE UNIQUE INDEX CD_IDX ON 0(DCD.ID)
CREATE TABLE ArtistARTIST_ID INT NO NULL,
ARTIST_NAMETEXT(50))
CREATE UNIQUE INDEX Artist_IDX ON Artist (ARTIST_ID) 
CREATE TABLE Song (SONG_ID INT NOT NULL, CD_ID INT,
SONG_NAME TEXT(50))
CREATE UNIQUE INDEX Song_IDX ON Song (SONG_ID)
CREATE TABLE RecordLabel (RECORD_LABEL_IDINT NOT NULL,
RECORD_LABEL_NAMEEXT(50)) 
CREATE UNIQUE INDEX RecordLabel_IDX
ON RecordLabel(RECORD_LABEL_ID)
Модели данных разрабатываются так, чтобы не зависеть от базы данных. Поэтому вы 
можете взять технику и модель данных, созданную в этой главе, и применить ее не 
только к MySQL и mSQL, но и к Oracle, Sybase, Ingres и любой другой РСУБД. В 
следующих главах мы подробно обсудим, как соединить ваши новые знания о 
проектировании баз данных с MySQL и mSQL.
Глава №3.
Установка
Подобно большинству сервисов, СУБД MySQL и mSQL работают как фоновые процессы, 
в Unix-системах называемые также демонами. В данной главе обсуждается процесс 
их распаковки и установки.
MySQL
Прежде чем начать установку MySQL, нужно ответить на пару вопросов.
1. Собираетесь ли вы устанавливать MySQL как пользователь root или какой-либо 
другой пользователь?
MySQL не требует для своей работы прав суперпользователя, но при установке с 
правами root вы даете каждому пользователю вашей системы доступ к одному 
экземпляру программы. Если у вас нет прав суперпользователя, установку придется 
произвести в свой исходный каталог. Однако, даже если вы установите MySQL как 
суперпользователь, лучше запускать под другим логином. Благодаря этому данные 
вашей базы данных можно защитить от других пользователей, установив для 
конкретных пользователей MySQL права только чтения файлов данных. Кроме того, 
при компрометации защиты базы данных нарушитель получает доступ только к 
учетной записи отдельного пользователя MySQL, не имеющей привилегий за 
пределами базы данных.
2. Будете ли вы устанавливать MySQL из исходного кода или откомпилированных 
модулей?
Имеется много откомпилированных двоичных пакетов MySQL. Это экономит время, но 
уменьшает возможности настройки при установке. Для установки из исходного кода 
вам потребуется компилятор С и другие инструменты разработчика. Если они у вас 
имеются, то преимущества установки из исходного кода обычно перевешивают мелкие 
неудобства.
Эти два вопроса взаимосвязаны. При установке из двоичного пакета вы должны быть 
зарегистрированы как root. Установка из двоичного пакета использует некоторые 
данные о путях, зашитые в двоичные файлы, что вынуждает вас регистрироваться 
при установке как тот, кто создал прекомпилирован-ный пакет. MySQL позволяет 
задать параметры командной строки, переопределяющие эти пути, но обычно меньше 
хлопот доставляет установка из исходного кода.
В любом случае сначала необходимо получить дистрибутив.
Таблица 3-1. Список серверов Интернета, с которых можно взять экземпляр 
исходного кода или двоичных файлов MySQL
АзияКореяKREONethttp://linux.kreonet.re.hr/mysql/ЯпонияSoft Agencyhttp://www.
softagency.co.jp/MySQL/Nagoya Syouka Universityhttp://mirror.nucba.ac.
jp/mirror/mysql/ Nagoya Syouka Universityftp://mirror.nucba.ac.jp/mirror/ 
mysql/ HappySizehttp://www.happysize.co.jp/mysql/HappySizeftp://ftp.happysize.
co.jp/pub/mysql/СингапурHJChttp://mysql.hjc.edu.sg/HJCftp://ftp.hjc.edu.
sg/mysql/ТайваньNCTUhttp://mysql.taconet.com.tw/TTNhttp://mysql.ttn.net
АвстралияАвстралияAARNet/Queenslandhttp://mirror.aarnet.edu.au/mysql/
AARNet/Queenslandftp://mirror.aarnet.edu.au/pub/ mysql/ Blue Planet/Melbourne
http://mysql.bluep.comBlue Planet/Melbourneftp://mysql.bluep.com/pub/mirrorl/ 
mysql/ Tashttp://ftp.tas.gov.au/mysql/Tasftp://ftp.tas.gov.au/pub/mysql/Африка
Южная АфрикаThe Internet Solution/ Johannesburgftp://ftp.is.co.za/linux/mysql/
ЕвропаАвстрияUniversity of Technology/Viennahttp://gd.tuwien.ac.at/db/mysql/
University of Technology/Viennaftp://gd.tuwien.ac.at/db/mysql/БолгарияNaturella
ftp://ftp.ntrl.net/pub/mirror/mysql/ДанияAkehttp://mysql.ake.dkSunSITE
http://sunsite.auc.dk/mysql/SunSITEftp://sunsite.auc.dk/pub/databases/ mysql/ 
ЭстонияTradenethttp://mysql.tradenet.eeФинляндияEUnethttp://mysql.eunet.fi
ФранцияMinethttp://www.minet.net/devel/mysql/ГерманияBonn University, Bonn
http://www.wipol.uni-bonn.de/ MySQL/ Bonn University, Bonnhttp://www.wipol.
uni-bonn.de/ MySQL/ Wolfenbuettelhttp://www.fh-wolfenbuettel.de/ftp/ 
pub/database/ mysql/ Wolfenbuettelftp://ftp.fh-wolfenbuettel.de/pub/ database/ 
mysql/ Staufenhttp://mysql.staufen.deГрецияNTUA, Athenshttp://www.ntua.
gr/mysql/NTUA, Athensftp://ftp.ntua.gr/pub/databases/ ВенгрияXeniahttp://xenia.
sote.hu/ftp/mirrors/ Xeniaftp://xenia.sote.hu/pub/mirrors/ ИзраильNetvision
http://mysql.netvision.net.ilИталияTeta Srlhttp://www.teta.it/mysql/Польша
Sunsitehttp://sunsite.icm.edu.pl/mysql/Sunsiteftp://sunsite.icm.edu.
pl/pub/unix/ Португалияlerianethttp://mysql.leirianet.ptlerianetftp://ftp.
leirianet.pt/pub/mysql/РоссияDirectNethttp://mysql.directnet.ruIZHCOM
http://mysql.udm.netIZHCOMhttp://mysql.udm.net
РумынияBucharesthttp://www.lbi.ro/MySQL/Bucharestftp://ftp.lbi.ro/mirrors/ftp.
tcx.seTimisoarahttp://www.dnttm.ro/mysql/Timisoaraftp://ftp.dnttm.ro/pub/mysql 
ШвецияSunethttp://ftp.sunet.se/pub/unix/ databases/ relational/ my sql/ Sunet
ftp://ftp.dnttm.ro/pub/mysql тcхhttp://www.tcx.seтcхftp://www.tcx.seтcх
http://www.mysql.com (Primary Site)тcхftp://ftp.mysql.com (Primary Site)Англия
Omnipotent/UKhttp://mysql.omnipotent.netOmnipotent/UKftp://mysql.omnipotent.net
PHG/UKhttp://ftp.plig.org/pub/mysql/PliG/UKftp://ftp.plig.org/pub/mysql/Украина
РАСОhttp://mysql.paco.net.uaРАСОftp://mysql.paco.net.uaСеверная АмерикаКанада
Trychttp://web.tryc.on.ca/mysql/СШАCircle Net/North Carolinahttp://www.mysql.
netDIGEXftp://ftp.digex.net/pub/database/ Gina net/Floridahttp://www.gina.
net/mysql/Hurricane Electric/San Josehttp://mysql.he.netNetcasting/West Coast
ftp://ftp.netcasting.net/pub/mysql/Phoenixhttp://phoenix.acs.ttu.edu/mysql/
pingzero/Los Angeleshttp://mysql.pingzero.netЮжная АмерикаЧилиAmerikanclaris
http://www.labs.amerikanclaris.cl/ visionhttp://mysql.vision.clПодключившись к 
серверу FTP, войдите в каталог Downloads. В нем будут перечислены несколько 
версий MySQL, например:
MySQL-3.21
MySQL-3.22
MySQL-3.23
Самый высокий номер версии соответствует нестабильному выпуску, в котором 
производится добавление и проверка новых характеристик. Отдельные подверсии его 
будут иметь пометки 'alpha', 'beta' или 'gamma'. Предыдущая версия является 
текущей стабильной версией. Эта версия тщательно проверена и считается 
свободной от ошибок. Доступны также более ранние архивные версии.
Если разрабатываемая версия находится на этапе 'alpha', вам определенно следует 
придерживаться стабильной версии, если только вы не любитель острых ощущений. В 
случае когда разрабатываемая версия находится на стадии 'beta', возможно, 
следует выбрать предыдущую версию, если только в новой версии нет крайне 
необходимых для вас характеристик или устойчивость системы, на которой вы 
работаете, не очень критична. С другой стороны, версией 'gamma' можно уверенно 
пользоваться при отсутствии в ней известных конфликтов с вашей системой.
Вы можете точно проверить, на какой стадии находится конкретная версия MySQL, 
перейдя в ее каталог. Например, каталог MySQL-3.22 может выглядеть следующим 
образом:
mysql-3.22.19-beta-sgi-irix6,4-mip.tgz 
mysql-3.22.21a-beta-ibm-aix4.2.1.0-rs6000.tgz
mysql-3.22.31-pc-linux-gnu-i586.tgz 
mysql-3.22.33-sun-solaris2.6-sparc.tgz 
mysql-3.22.33.tar.gz
Файлы, имена которых включают названия машин и операционных систем, являются 
двоичными версиями для этих систем. Если название машины не указано, как в 
последней строке, то это исходный код. Если к файлу не присоединена метка 
'alpha', 'beta' или 'gamma' - это стабильная версия. Что касается двух 
последних файлов списка, то первый - откомпилированная версия для Sun Solaris 
на машине Spare, а последний - исходный код. Прочие, более старые версии 
существуют, поскольку у команды разработчиков не всегда есть время и 
возможность откомпилировать каждую подверсию MySQL на каждой существующей 
операционной системе и аппаратной конфигурации. В действительности, большая 
часть прекомпилированных версий предоставлена обычными пользователями, которым 
удалось успешно откомпилировать последнюю версию на своей системе.
Зная это, вы можете теперь выбрать версию MySQL, которую хотите использовать, и 
загрузить исходный код, если собираетесь компилировать MySQL, или двоичный 
дистрибутив для вашей машины, если он существует. Когда отсутствует двоичный 
дистрибутив, точно соответствующий вашей конфигурации, проверьте, нет ли его 
для слегка отличной конфигурации. Например, mysql-3.22.32a-ibm-aix4.2.1.
0-powerpc.tgz может работать также на версии AIX 4.1.4 на том же типе машин. 
Если вы не можете таким образом подобрать работающую версию, попробуйте 
поискать в более старых версиях MySQL. Если и это не удастся, придется 
компилировать исходный код. В случае успешной компиляции и запуска MySQL можно 
предоставить откомпилированные двоичные файлы команде разработчиков MySQL для 
включения в архив.
Установка из исходного кода
Загрузив дистрибутив с исходным кодом, распакуйте архив с помощью команды:
gunzip - с mysql-x.xx.xx.tar.gz | tar xvf -
где mysql-x. xx. xx . tar. gz - имя загруженного вами файла. В результате в 
рабочем каталоге будет создан каталог mysql-x. xx. xx. Перейдите в него. 
Запустите сценарий configure в рабочем каталоге. Вызовите его как . /configure, 
чтобы случайно не запустить программу с тем же именем, находящуюся где-либо в 
другом месте. Во многих случаях установка прекрасно проходит без задания 
каких-либо параметров, но при возникновении трудностей можно использовать 
многочисленные параметры, информацию о которых можно вывести на экран, задав 
ключ -help. Вот наиболее употребительные:
--without-server
В результате компилируются все имеющиеся клиенты MySQL, но не сервер.
-prefix
Устанавливается каталог инсталляции, отличный от каталога по умолчанию (/usr/ 
local/ ).
-with-low-memory
Эта опция запрещает компилятору использовать некоторые виды оптимизации, 
требующие много памяти при компиляции. С ее помощью устраняется большинство 
ошибок, связанных с нехваткой памяти при компиляции.
-localstatedir
Используется для назначения каталога для файлов базы данных, отличающегося от 
принятого по умолчанию (/usr/local/var).
-with-charset
Используется для выбора набора символов, отличного от принятого по умолчанию 
(lati.nl). На момент написания книги доступны наборы символов big5, danish, 
cp1251, cp1257, croat, czech, dec8, dos,
euc_kr, germanl, Hebrew, hp8, hungarian, koi8_ru, koi8_ukr, latin1, Iatin2, 
swe7, usa7, win1251, win1251u, kr, ujis, sjis, tis620.
После завершения выполнения сценария configure запустите make в рабочем 
каталоге. В результате будет произведена полная компиляция.
По завершении компиляции команда make install установит все в нужное место.
Если вы впервые устанавливаете на данной машине MySQL или все файлы баз данных 
MySQL были удалены после предыдущей инсталляции, выполните следующую команду, 
чтобы создать структуру баз данных и административные таблицы:
./scripts/mysql_install_db
При этом запустится также демон сервера. Чтобы убедиться в том, что он работает,
 перейдите в инсталляционный каталог (по умолчанию / usr/local/) и введите 
команду:
./bin/mysqladmin version 
На экран будет выведено что-то, близкое к следующему:
mysqladmin Ver 7.11 Distrib 3.22.23b, for linux on 1586
TCX Datakonsult AB, by Monty
Server version 3.22.23b-debug
Protocol version 10
Connection Localhost via UNIX socket
UNIX socket /tmp/mysql.sock
Uptime: 6 sec
Threads: 1 Questions: 1 Slow queries: 0 Opens: 6 Flush tables: 1 Open
tables: 2 Memory in use: 1093K Max memory used: 1093K
Итак, последовательность шагов установки такова:
gzip - с mysql-x.xx. xx. tar. gz | tar xvf -
cd mysql-x.xx.xx
./configure
make
make install
./scripts/mysql_install_db
./bin/mysqladmin version
Установка двоичного дистрибутива
Загрузив двоичный дистрибутив, вы должны выбрать каталог для установки файлов 
MySQL. Чаще всего выбирается /usr/local/mysql, но это в значительной мере 
зависит от потребностей ваших пользователей, и имеющихся у вас прав доступа.
Перейдите в каталог на уровень выше, чем тот, в котором вы хотите разместить 
дистрибутив MySQL. Например, если вы хотите использовать /usr/local/mysql, 
перейдите в /usr/local. Для распаковки дистрибутива выполните команду:
gunzip - с /tmp/mysql-x.xx.xx-fflymac/line. tgz | tar xvf -
Здесь /tmp - имя каталога, в который вы загрузили дистрибутив MySQL, a mysql-x.
xx.xx-mymachine.tgz - имя загруженного файла.
В результате в текущем каталоге будет создан каталог mysql-x.xx.xx mysql. Если 
вы хотите, чтобы файлы были просто в каталоге mysql, создайте связь:
In - s mysql-x.xx.xx mysql
Теперь проверьте, содержит ли двоичный пакет таблицы назначения прав доступа. 
Перейдите в каталог mysql/mysql. Если он не существует или пуст, вам придется 
создать таблицы самому. Вернитесь назад, на один уровень, в главный каталог 
установки mysql и выполните команду:
scripts/mysql_install_db
Эту команду нужно выполнить только один раз. Для запуска демона MySQL введите:
bin/safe_mysqld --log & 
Чтобы убедиться, что демон правильно работает, введите:
bin/mysqladmin version 
Ответ должен быть примерно таким:
Mysqladmin Ver 6.3 Distrib 3.21.33, for sun-solaris2.6 on spare
TCX Datakonsult AB, by Monty
Server version 3.21.17-alpha
Protocol version 10
Connection Localhost via UNIX socket
TCP Port 3333
UNIX socket /tmp/mysql.sock
Uptime: 13 sec
Running threads: 1 Questions: 20 Reloads: 2 Open Tables: 3
mSQL
Первым шагом в установке mSQL является получение дистрибутива исходного кода. 
На момент написания этой книги самые новые версии mSQL распределялись только с 
веб-страницы Hughes Technology на http://www.hughes.com.avl. Автор mSQL 
предпочел официально не распространять двоичные дистрибутивы mSQL. Если на 
вашей машине нет компилятора С, то вам следует либо установить его, либо 
скомпилировать на такой же машине с той же операционной системой и перенести 
результат.
Полученный дистрибутив с исходным кодом mSQL распакуйте командой:
gunzip - с msql-2.0.4.1.tar.gz | tar xvf -
В результате в рабочем каталоге будет образован каталог с именем msq 1-2.0.4.1. 
Перейдите в него.
Создайте на своей машине инсталляционный каталог командой:
make target
Теперь перейдите в каталог targets. В нем должен быть новый каталог с названием 
вашей операционной системы и платформы, например, Solaris-2.6-Spare или Linux-2.
0. 33-1386. Перейдите в этот каталог.
В рабочем каталоге запустите сценарий setup. Лучше запустите его как . /setup, 
чтобы командный процессор не запустил программу setup из какого-нибудь другого 
каталога. Сценарий сконфигурирует исходный код для компиляции. После выполнения 
сценария рассмотрите файл site.mm и измените необходимые параметры для 
настройки своей локальной установки. В частности, вы, возможно, захотите 
изменить переменную INST_DIR, задающую каталог, в который устанавливается mSQL. 
Если конфигурация вас устраивает, для компиляции mSQL выполните команду:
make all
После компиляции установите mSQL в выбранный вами каталог с помощью команды:
make install
Вся последовательность шагов при инсталляции выглядит следующим образом:
gzip - с msql-x.x.x.tar.gz tar xvf -
cd msql-x.x.x
make target
cd targets/myOS-mymachine
./setup
make all
make install
Глава №4.
MySQL
MySQL является, возможно, самым ярким программным проектом после выхода Linux. 
В то время как mSQL заслуживает уважения за то, что столкнула дело управления 
базами данных с мертвой точки, MySQL умело воспользовалась моментом. Сейчас она 
не больше и не меньше, как серьезный конкурент большим СУБД в области 
разработки баз данных малого и среднего масштаба. В самом начале MySQL просто 
стала заменой устаревающему ядру mSQL версии 1. Как отмечалось в Главе 1, 
признаки старения mSQL проявились в виде проблем со стабильностью и 
неспособностью удовлетворить растущие требования, которые обрушились на нее 
благодаря успеху. MySQL использовала основы проекта mSQL и теперь превосходит 
ее по набору характеристик и одновременно по производительности.
Проект
Опираясь на наследство, полученное от mSQL, TcX решила, что MySQL должна быть 
не медленнее mSQL, обладая при этом большим набором возможностей. В то время 
mSQL задавала тон в производительности баз данных, так что задачу себе ТсХ 
поставила непростую. Особыми целями проектирования MySQL были скорость, 
надежность и простота использования. Чтобы достичь такой производительности, в 
ТсХ приняли решение сделать многопоточным внутренний механизм MySQL. 
Многопоточное приложение одновременно выполняет несколько задач - так, как если 
бы одновременно выполнялось несколько экземпляров приложения.
Сделав MySQL многопоточной, ТсХ дала пользователям много выгод. Каждое входящее 
соединение обрабатывается отдельным потоком, при этом еще один всегда 
выполняющийся поток управляет соединениями, поэтому клиентам не приходится 
ждать завершения выполнения запросов других клиентов. Одновременно может 
выполняться любое количество запросов. Пока какой-либо поток записывает данные 
в таблицу, все другие запросы, требующие доступа к этой таблице, просто ждут, 
пока она освободится. Клиент может выполнять все допустимые операции, не 
обращая внимания на другие одновременные соединения. Управляющий поток 
предотвращает одновременную запись какими-либо двумя потоками в одну и ту же 
таблицу.
Такая архитектура, конечно, более сложна, чем однопоточная архитектура mSQL. 
Однако выигрыш в скорости благодаря одновременному выполнению нескольких 
запросов значительно превосходит потери скорости, вызванные увеличением 
сложности.
Другое преимущество многопоточной обработки присуще всем многопоточным 
приложениям. Несмотря на то что потоки совместно используют память процесса, 
они выполняются раздельно. Благодаря этому разделению выполнение потоков на 
многопроцессорных машинах может быть распределено по нескольким ЦП. На рис. 4-1 
показана эта многопоточная природа сервера MySQL.

Рис. 4-1. Клиент-серверная архитектура MySQL
Помимо выигрыша в производительности, полученного благодаря многопоточности, 
MySQL поддерживает большее подмножество SQL, чем mSQL. MySQL поддерживает более 
десятка типов данных, а также функции SQL. Ваше приложение может получить 
доступ к этим функциям через команды ANSI SQL.
MySQL фактически расширяет ANSI SQL несколькими новыми возможностями. В их 
числе новые функции (ENCRYPT, WEEKDAY, IF и другие), возможность 
инкрементирования полей (AUTO_INCREMENT и LAST_INSERT_ID), а также возможность 
различать верхний и нижний регистры.
ТсХ намеренно опустила некоторые возможности SQL, встречающиеся в больших базах 
данных. Наиболее заметно отсутствие транзакций и встроенных процедур. Как и 
Дэвид Хьюз в mSQL, ТсХ решила, что реализация этих возможностей нанесет слишком 
сильный удар по производительности. Однако ТсХ продолжает работу в этом 
направлении, но так, чтобы от потери производительности страдали только те 
пользователи, которым такие возможности действительно необходимы.
С 1996 года ТсХ использует MySQL в среде, где имеется более 40 баз данных, 
содержащих 10 000 таблиц. Из этих 10 000 более 500 таблиц имеют, в свою очередь,
 более 7 миллионов записей - около 100 Гбайт данных.
Установка MySQL
Прежде чем использовать MySQL, ее необходимо установить. MySQL работает почти 
на любой известной Unix-платформе, а также под управлением Windows 9x, Windows 
NT и OS/2. Для Windows 9x и Windows NT требуется приобрести лицензию. Если вы 
хотите лишь протестировать работу этой СУБД, имеется более старая бесплатная 
версия.
Дистрибутив MySQL существует как в двоичном виде, так и в виде исходного текста.
 Если вы не прочь внести свой вклад в проект MySQL, добавить к нему свои 
усовершенствования или просто не можете найти двоичного дистрибутива для своей 
платформы, то необходимо взять дистрибутив с исходным кодом. Большинству 
пользователей, впрочем, следует брать двоичный дистрибутив. Самые свежие 
дистрибутивы - двоичные и в виде исходных текстов - можно найти на http://www.
mysql.com 
Если вы получите дистрибутив в виде исходного текста, то перед установкой нужно 
его скомпилировать. В любом случае следует руководствоваться инструкциями, 
имеющимися в дистрибутиве.
Запуск MySQL
Как правило, сервер баз данных работает постоянно. В конце концов, какой смысл 
иметь базу данных, если нельзя получить данные. ТсХ создавала MySQL, имея это в 
виду, поэтому MySQL работает под Unix как демон, и как служба — под Windows NT. 
В Windows 95 есть только грубый аналог, реализуемый помещением ярлыка 
исполняемого приложения в папку Автозагрузка (StartUp). Важной особенностью 
работы под Windows 95 является то, что при создании каждого потока происходит 
утечка примерно 200 байт оперативной памяти. Поэтому под Windows 95 не следует 
надолго оставлять MySQL работающей. К Windows 98 и Windows NT это не относится.
Запуск MySQL осуществляется с помощью сценария safe_mysqld. Под Unix этот файл 
устанавливается по умолчанию как /usr/local/bin/ safe_mysqld. Это сценарий для 
командного процессора Борна, и вы можете редактировать его, чтобы изменять 
принятые по умолчанию параметры. Все параметры, которые вы зададите в 
safe_mysqld, будут переданы непосредственно демону MySQL.
MySQL — ветвящийся демон. Когда вы ее запускаете, программа создает свою копию 
и выполняется как фоновый процесс. Поэтому вам не нужно ничего делать, чтобы 
заставить MySQL выполняться в фоновом режиме. Если же для запуска MySQL вы 
используете сценарий safe_mysqld, то вы должны перевести его в фоновый режим:
/usr/local/mysql/bin/safe_mysqld &
Причина, по которой вы должны запускать safe_mysqld в фоновом режиме (и по 
которой нужно запускать именно safe_mysqld, а не mysqld) в том, что сценарий 
safe_mysqld запускает mysqld, а затем непрерывно проверяет, выполняется ли 
mysqld. Если выполнение MySQL неожиданно прекратится, safe_mysqld ее 
перезапустит.
Теперь, когда вы знаете, как запускать MySQL, нужно сделать так, чтобы MySQL 
стартовала и заканчивала работу вместе с компьютером, на котором она 
выполняется. Под Windows NT, конечно, достаточно установить MySQL как службу. 
Под Windows 9x нужно поместить ярлык сценария запуска MySQL в папку Startup. 
Под Unix, как и почти всегда бывает в этом мире, заставить MySQL стартовать и 
завершаться вместе с системой несколько сложнее. Unix-системы обычно ищут 
сценарии начального запуска где-то в каталоге /etc - в /etc/rc.d или /etc/ init.
d. Вы должны узнать у системного администратора или в документации, куда именно 
нужно помещать сценарии запуска/завершения. Дистрибутив MySQL содержит в 
каталоге support_j'lies файл mysql.ser-ver. Этот сценарий и будет служить 
сценарием запуска/завершения.
Администрирование базы данных
Теперь, когда у вас есть свежеустановленная и запущенная MySQL, нужно первым 
делом поменять пароль суперпользователя сервера, выполнив из каталога, в 
который установлена MySQL, команду:
./bin/mysqladmin -u root password 'mynewpasswd'
При работающей и защищенной MySQL вы можете заняться некоторыми начальными 
задачами администрирования, чтобы MySQL смогла начать вам служить.
Утилита mysqladmin
Главным инструментом администрирования баз данных в MySQL служит утилита 
mysqladmin. С ее помощью вы можете создавать, уничтожать и контролировать свой 
сервер и поддерживаемые им базы данных.
Создание баз данных
Ваш сервер бесполезен, пока нет баз данных, которые он обслуживает. С помощью 
mysqladmin можно создавать новые базы данных:
mysqladmin -p create DATABASENAME
Параметр -р указывает, что вы хотите, чтобы было выдано приглашение для ввода 
пароля суперпользователя, который вы задали раньше. Если вы введете правильный 
пароль, то mysqladmin создаст новую пустую базу данных с именем, которое вы 
указали. Поскольку в MySQL база данных - это каталог с группой файлов, команда 
mysqladmin create создает новый каталог, который будет содержать файлы базы 
данных. Например, если вы создали базу данных с именем «mydata», в каталоге 
data, содержащемся в директории, в которую установлена MySQL, будет создан 
каталог mydata.
Поскольку базы данных и таблицы MySQL хранятся как файлы файловой системы, вы 
столкнетесь с неприятными различиями -в поведении реализаций для Unix и Win32. 
Именно, все файловые системы для Win32 нечувствительны к регистру, в то время 
как файловые системы Unix различают регистр. В результате имена баз данных и 
таблиц различаются по регистру в Unix и не различаются в Win32.
Удаление базы данных
В процессе разработки приложения вам, вероятно, потребуется создать несколько 
баз данных для поддержки процесса разработки. Например, обычной практикой в 
разработке приложений баз данных является создание отдельных баз данных для 
разработки, тестирования и работы. По завершении разработки следует избавиться 
от этих промежуточных баз данных. Утилита mysqladmin позволяет удалить базу 
данных с помощью параметра «drop»:
mysqladmin -p drop DATABASENAME
Как и в команде mysqladmin create, DATABASENAME является именем базы данных, 
которую нужно уничтожить. MySQL не позволит вам случайно удалить базу данных. 
После ввода этой команды она предупредит вас, что удаление базы данных 
потенциально очень опасно и попросит вас подтвердить свое намерение. После 
удаления базы данных вы можете убедиться в том, что в каталоге data больше нет 
каталога, служившего ранее этой базой данных.
Переименование и копирование баз данных
В MySQL нет утилиты для переименования и копирования баз данных. Поскольку база 
данных - это просто файлы в некотором каталоге, можно, соблюдая осторожность, 
переименовывать и копировать базы данных с помощью операционной системы. Хотя 
использование команд операционной системы позволяет переименовывать и 
копировать базы данных, результат не сохранит параметров защиты исходных таблиц,
 поскольку MySQL хранит данные по защите в таблице системной базы данных. Для 
того чтобы полностью скопировать базу данных, вам потребуется также 
продублировать ее информацию по защите, хранимую в системной базе данных MySQL. 
Мы подробнее рассмотрим систему защиты MySQL далее в этой главе.
Состояние сервера
В утилите mysqladmin очень много команд, позволяющих контролировать состояние 
сервера MySQL. Ввод команды mysqladmin status обеспечивает выдачу состояния 
сервера в одной строке, которая выглядит следующим образом:
Uptime: 395 Threads: 1 Questions: 14 Slow queries: 0
Opens: 10 Flush tables: 1 Open tables: 6
Выводимые величины означают следующее: Uptime
Число секунд, в течение которых сервер запущен и работает. Threads
Число потоков, взаимодействующих с базой в данный момент. Вы всегда увидите 
хотя бы один поток - тот, который подсчитывает все остальные потоки. Сервер 
имеет также три других потока, невидимых данной команде, - один обрабатывает 
сигналы, другой управляет всеми другими потоками и третий ждет входящих 
соединений.
Questions
Число запросов, переданных базе данных с момента запуска.
Slow queries
Число запросов, выполнение которых потребовало больше времени, чем время, 
указанное в конфигурации. Соответствующий ключ в конфигурации - 
long_query_tiroe . Мы рассмотрим параметры конфигурации далее в этой главе.
Opens
Число таблиц, открытых с момента запуска сервера.
Flush tables
Количество команд flush, refresh и reload.
Open tables
Число таблиц, открытых в данный момент. Поскольку MySQL мно-гопоточна, каждая 
таблица одновременно может быть открыта несколько раз. Например, можно 
одновременно выполнять любое число команд SELECT по одной и той же таблице. По 
этой причине число открытых таблиц может быть больше, чем общее число таблиц в 
системе.
Если компиляция MySQL производилась с параметром --with-debug , то mysqladmin 
status показывает также текущую и максимальную величину используемой памяти.
Если вас интересует более общая статическая информация, то выполните команду 
mysqladmin version. Она выдает на экран следующее:
bin/mysqladmin Ver 7.8 Distrib 3.22.17, for sun-solaris2.6 on spare TCX 
Datakonsult AB, by Monty
Server version 3.22.17
Protocol version 10
Connection Localhost via Unix socket
Unix socket /tmp/;ny3ql. sock
Uptime: 23 mm 58 sec
Threads: 1 Questions: 15 Slow queries: 0 Opens: 10 Flush tables: 1 Open tables: 
6
Последняя строка совпадает, конечно, с теми данными, которые показывает 
mysqladmin status. Остальные данные совершенно другие.
Server version
Версия запущенного сервера MySQL. Protocol version
Версия коммуникационного протокола MySQL, который поддерживает сервер. Если у 
вас возникли трудности с инструментарием, который использует коммуникационный 
протокол MySQL, вы можете сравнить это значение с тем, которое ожидает ваша 
программа.
Connection
Метод подключения к серверу. В нашем примере клиент общается с MySQL через 
сокет Unix. Если вы обращаетесь к удаленному серверу, в этой позиции будет имя 
машины, с которой вы подключились.
Unix socket
Имя файла сокета, который вы используете для обмена данными с сервером. Если вы 
связываетесь с MySQL через TCP/IP, вместо этого пункта будет указан пункт TCP 
port с номером порта MySQL.
Uptime
Суммарное время работы сервера.
Две другие команды, mysqladmin variables и mysqladmin extended-status, 
предлагают дополнительную информацию.
Поскольку MySQL многопоточна, отследить активность процесса с помощью команды 
Unix ps не просто. Несмотря на то что выполняется несколько потоков, в списке 
процессов будет указан только один процесс. MySQL позволяет справиться с этим с 
помощью команды mysqladmin processlist, которая перечисляет все активные потоки 
в виде чудесно представленной таблички:

Здесь точно указано, чем занят каждый процесс. Выдаваемые величины имеют 
следующий смысл:
Id
Внутренний идентификационный номер потока. Это значение не имеет отношения к 
каким-либо системным ID процессов. Вы можете использовать это число в команде 
mysqladmin kill, чтобы завершить поток.
User
Пользователь, подключенный к серверу через этот поток.
Host
Имя узла, с которого подключился пользователь.
db
База данных, к которой подключен пользователь.
Command
Тип команды, выполняемой потоком. Команда может иметь один из следующих типов:
Sleep
Поток ждет ввода пользователя. Большинство процессов должно находиться в этом 
состоянии.
Quit
Поток в процессе завершения.
Init DB
Поток готовит выбранную базу к взаимодействию. Клиент одновременно может 
обмениваться данными только с одной базой, но переключение между базами можно 
осуществить в любой момент.
Query
Поток выполняет реальный запрос. Хотя наибольшая часть взаимодействия с базой 
данных происходит в виде запросов, эти команды производятся очень быстро и 
редко появляются в выдаче.
Field list
Поток создает список полей в таблице.
Create DB
Поток создает новую базу данных.
Drop DB
Поток удаляет базу данных.
Reload
Поток перезагружает таблицы доступа MySQL. После перезагрузки все новые потоки 
будут использовать обновленные таблицы доступа.
Shutdown
Поток находится в процессе завершения всех других потоков и закрытия сервера.
Statistics
Поток генерирует статистику. 
Processes
Этот поток анализирует другие потоки. С этим значением будет показан поток, 
выполняющий данную команду.
Connect
Поток в процессе установления входящего соединения с клиентом. 
Kill
Этот поток завершает другой поток.
Refresh
Поток очищает все буферы и сбрасывает журнальные файлы.
Файлы журналов MySQL дают еще один способ получения полезной информации для 
администрирования сервера. MySQL создает главный журнал, если mysqld 
запускается с параметром --log. Этот журнал ведется в файле 
/usr/local/var/HOSTNAME.log, где HOSTNAME - имя машины, на которой запущен 
MySQL. В этот журнал записываются подключения к серверу и команды, посылаемые 
ему клиентами.
Задав параметр -debug для mysqld (или safe_mysqld), вы заставите MySQL посылать 
в журнал дополнительную информацию. Пакет отладки, используемый MySQL, имеет 
десятки параметров, большинство из которых вы никогда не будете использовать. 
Наиболее часто используется установка -d:t:o,FILENAME, где FILENAME - имя 
журнала отладки, который вы хотите использовать. При задании этого параметра в 
журнал будут заноситься практически все действия сервера, шаг за шагом.
MySQL поддерживает еще один журнал, пригодный для чтения. Если запустить MySQL 
с параметром -log-update, будет создан файл с именем HOSTNAME. #, где HOSTNAME 
имя машины, a #- уникальное число. В этом журнале содержатся все изменения, 
вносимые в таблицы баз данных. Этот журнал создается в виде SQL, поэтому все 
операции можно воспроизвести на другом сервере баз данных.
Завершение работы сервера
Следующая команда производит корректное завершение работы сервера MySQL:
mysqladmin -p shutdown
Эта команда - самый правильный способ завершения работы сервера. Если вы 
запустили MySQL с помощью safe_mysqld и пытаетесь закрыть сервер каким-либо 
другим способом, safe_mysqld просто запустит еще один экземпляр сервера. Можно 
также безопасно закрыть сервер традиционной Unix-командой kill, но никогда не 
пользуйтесь kill-9.
Параметры командной строки для mysqladmin
Утилита mysqladmin - очень богатый инструмент со множеством параметров 
командной строки. Общий ее формат
mysqladmin OPTIONS COMMAND1 COMMAND2 . . . COMMANDn
Иными словами, можно одновременно задавать несколько команд. Будет выполнена 
даже такая последовательность команд как, скажем,
mysqladmin -p create silly drop silly
Эта команда одним махом создаст и уничтожит базу данных «silly». Вот перечень 
команд, которые можно передать mysqladmin:
create DATABASENAME
Создает новую базу данных с указанным именем.
drop DATABASENAME
Удаляет базу данных с указанным именем. 
extended-status
Выдает расширенное сообщение о статусе сервера.
flush-hosts
Немедленно записывает все буферизованные изменения на удаленных компьютерах.
flush-logs
Немедленно записывает все буферизованные изменения в журналы. 
flush-tables
Немедленно записывает все буферизованные изменения в таблицы. 
flush-privileges
То же, что reload.
killID1,ID2.....IDn
Завершает потоки с заданными IDs. 
password NEWPASSWORD
Заменяет пароль на новое значение.
ping
Проверяет, работает ли еще mysqld.
processlist
Выдает список активных потоков.
reload
Заново загружает все таблицы доступа. 
refresh
Записывает буферизованные изменения во все таблицы и закрывает и открывает все 
журналы.
shutdown
Завершает работу сервера.
status
Выдает краткое сообщение о состоянии сервера.
variables
Выдает значения имеющихся переменных. 
version
Выдает данные о версии сервера.
Кроме команд поддерживаются также следующие параметры: 
-# LOG
Выдача отладочной информации в журнал. Часто это 'd:t:o,FILENAME'.
-f
Не запрашивать подтверждение на удаление таблицы и переходить к следующей 
команде даже при невозможности выполнить эту.
-? или --help
Выдача подсказки по использованию утилиты msqladmin. 
-С
Использовать сжатие в протоколе клиент/сервер.
-Н HOST
Подключиться к указанному компьютеру. 
-р [PASSWORD]
Использовать указанный пароль для проверки прав пользователя. 
Если пароль не указан, пользователю будет выдано приглашение для ввода пароля.
-Р PORT
Использовать для подключения указанный порт. 
-i SECONDS
Повторно выполнять команды через заданный промежуток времени.
-s
Выйти без сообщений, если соединение с сервером невозможно установить.
-S SOCKET
Файл для использования в качестве сокета Unix. 
-t TIMEOUT
Тайм-аут для соединения.
-u USER
Имя для регистрации пользователя, если оно отлично от текущего.
-V
Выдать информацию о версии и завершить работу.
-w COUNT
Ждать и повторить попытку заданное число раз, если сервер в данный момент не 
готов.
Резервирование данных
Нельзя переоценить важность регулярного резервирования данных. Без 
работоспособной резервной копии в результате аварии питания могут быть потеряны 
месяцы и годы работы. В то же время при хорошо спланированном резервировании 
можно за короткое время восстановить данные почти при любой аварии.
В главе 5 «mSQL» приводится подробное изложение роли команды msqldump при 
резервировании данных mSQL. MySQL поддерживает почти идентичную 
функциональность в виде команды mysqldump. Мы рекомендуем изучить этот пункт, 
чтобы понять роль mysqldump при полном резервировании баз данных. В данном 
параграфе мы остановимся на следующем наиболее важном виде резервирования - 
инкре-ментном резервировании.
Хотя технически полного резервирования данных вполне достаточно для 
восстановления после потери данных, его иногда трудно осуществить. Когда у вас 
много данных, файлы, необходимые для полного резервирования, могут занимать 
слишком большое дисковое пространство. Поэтому общепринято осуществлять полное 
резервирование раз в неделю или через небольшие промежутки времени, а ежедневно 
производить резервирование данных, изменившихся с момента последнего полного 
резервирования. Это называется инкрементным резервированием.
При использовании MySQL инкрементное резервирование можно производить, 
используя такую возможность сервера баз данных, как «update log» - журнал 
изменений MySQL. Если сервер баз данных mysqld запущен с параметром 
--log-update, то все изменения в базе данных будут сохраняться в файле в виде 
команд SQL. Изменения будут сохраняться в порядке их производства. В результате 
получается файл, который, будучи обработан монитором mysql, воспроизведет все 
действия, произведенные над базой данных. Если журнал хранится с самого 
образования базы данных, то будет восстановлен весь жизненный цикл базы данных, 
который приведет ее в текущее состояние.
С большей пользой журнал, ведущийся с некоторого определенного момента, 
например, от последнего резервирования базы данных, можно использовать для 
приведения резервной копии в текущее состояние. Такова технология инкрементного 
резервирования. Производите регулярное (скажем, раз в неделю) полное 
резервирование базы данных. Затем каждый день копируйте журнал изменений на 
магнитную ленту или выделенную область жесткого диска. Сохраняйте копии всех 
ежедневных журналов изменений, начиная с даты последнего полного резервирования.
 Это позволяет восстановить базу данных в случае аварии, а также все данные, 
утраченные с момента последнего резервирования. Поскольку журнал изменений 
является текстовым файлом, можно просмотреть команды SQL для поиска конкретных 
данных.
Каким бы методом вы не пользовались для резервирования, производите его часто и 
периодически проверяйте возможность реального восстановления своих данных. 
Многие администраторы баз данных старательно сохраняли резервные данные лишь 
для того, чтобы в один прекрасный день убедиться, что в результате ошибки - 
оператора, программы или носителя информации - их резервные копии стали 
абсолютно бесполезны.
Система безопасности
Вам не только нужно иметь надежный доступ к своим данным, но и быть уверенным, 
что у других нет никакого доступа к ним. MySQL использует собственный сервер 
баз данных для обеспечения безопасности. При первоначальной установке MySQL 
создается база данных под названием «mysql». В этой базе есть пять таблиц: db, 
host, user, tab-les_priv, и columns_priv . Более новые версии MySQL создают 
также базу данных с названием func, но она не имеет отношения к безопасности. 
MySQL использует эти таблицы для определения того, кому что позволено делать. 
Таблица user содержит данные по безопасности, относящиеся к серверу в целом. 
Таблица host содержит права доступа к серверу для удаленных компьютеров. И 
наконец, db, tables_priv и со-lumns_priv управляют доступом к отдельным базам 
данных, таблицам и колонкам.
Мы кратко рассмотрим все таблицы, поддерживающие безопасность в MySQL, а затем 
рассмотрим технологию их использования при обеспечении защиты ядром MySQL.
Таблица user
Таблица user имеет вид, показанный в Таблице 4-1:
Таблица 4-1. Таблица user
ПолеТипNullКлючЗначениеПримеч.по умолчаниюHostchar(60)PRIUserchar(16)PRI
ПолеТипNullКлючЗначениеПримеч.по умолчаниюPasswordchar(16)Select_privenum('N',
'Y')NInsert priv enum('N','Y')   N Update_privenum('N','Y')NDelete_privenum('N',
'Y')NCreate_privenum('N','Y')NDrop privenum('N','Y')NReload privenum('N','Y')N
Shutdown_privenum('N','Y')NProcess_privenum('N','Y')NFile_privenum('N','Y')N
Grant_privenum('N','Y')NReferences_privenum('N','Y')NIndex_privenum('N','Y')N
Alter_privenum('N','Y')NВ колонках Host и User можно использовать символ «% », 
заменяющий произвольную последовательность символов. Например, имя узла 
«chem%lab» включает в себя «chembiolab», «chemtestlab» и т. д. Специальное имя 
пользователя «nobody» действует как одиночный «% », то есть охватывает всех 
пользователей, не упомянутых где-либо в другом месте. Ниже разъясняется смысл 
различных прав доступа:
Select_priv
Возможность выполнять команды SELECT.
Insert__priv
Возможность выполнять команды INSERT.
Update_priv
Возможность выполнять команды UPDATE.
Delete_priv
Возможность выполнять команды DELETE.
Createjyriv
Возможность выполнять команды CREATE или создавать базы данных.
Drop_priv
Возможность выполнять команды DROP для удаления баз данных. 
Reload_priv
Возможность перезагружать информацию о доступе с помощью mysqladmin reload.
Shutdown_priv
Возможность останавливать сервер через mysqladmin shutdown. 
Process_priv
Возможность управлять процессами сервера.
File_priv
Возможность читать и записывать файлы с помощью команд типа SELECT INTO OUTFILE 
и LOAD DATA INFILE.
Grant_priv
Возможность давать привилегии другим пользователям. 
Index_priv
Возможность создавать и уничтожать индексы.
Alter_priv
Возможность выполнять команду ALTER TABLE.
В MySQL есть специальная функция, позволяющая скрыть пароли от любопытных глаз. 
Функция password() зашифровывает пароль. Ниже показано, как использовать 
функцию password() в процессе добавления пользователей в систему.
INSERT INTO user (Host, User, Password, Select_priv,
Insert_priv, Update_priv, Dclete_priv)
VALUES ('%', 'bob', password('mypass'), 'Y', 'Y', 'Y'.'Y')
INSERT INTO user (Host, User, Password, Select_priv)
VALUES ('athens.imaginary.com', 'jane', '', 'Y')
INSERT INTO user (Host, User, Password)
VALUES ('%', 'nobody', ")
INSERT INTO user (Host, User, Password, Select_pnv,
Insert_priv, Updatejriv, Delete_priv)
VALUES ('athens.imaginary.com', 'nobody',
password('thispass'), 'Y', 'Y', 'Y', 'Y')
Имена пользователей MySQL обычно не связаны с именами пользователей 
операционной системы. По умолчанию кли-ентские средства MySQL используют при 
регистрации имена пользователей операционной системы. Для них, однако, не 
требуется обязательного соответствия. В большинстве клиентских приложений MySQL 
можно с помощью параметра -и подключиться к MySQL, используя любое имя. Точно 
так же ваше имя как пользователя операционной системы не появится в таблице 
user, если не будет специально включено в нее с присвоением прав.
Первый созданный нами пользователь, «bob», может подключаться к базе данных с 
любого компьютера и выполнять команды SELECT, INSERT, UPDATE и DELETE. Второй 
пользователь, «jane», может подключаться с «athens.imaginary.com», не имеет 
пароля и может выполнять только SELECT. Третий пользователь - «nobody» - с 
любой машины.'Этот пользователь вообще ничего не может делать. Последний 
пользователь -«nobody» - с машины «athens.imaginary.com», он может выполнять 
SELECT, INSERT, UPDATE и DELETE, как и пользователь «bob.»
Как MySQL производит сопоставление? Возможно, вы обратили внимание, что 
некоторое имя может соответствовать на деле нескольким записям. Например, 
«[email protected]» соответствует и «nobody@%», и «nobody@athens.
imaginary.com». Прежде чем осуществлять поиск в таблице user, MySQL сортирует 
данные следующим образом:
1. Сначала ищется соответствие для узлов, не содержащих масок « % », при этом 
пустое поле Host трактуется как «% ».
2. Для одного и того же узла сначала проверяется соответствие имен, не 
содержащих масок. Пустое поле User трактуется как содержащее «%».
3. Первое найденное соответствие считается окончательным.
В предыдущем примере пользователь сначала будет сравниваться с «nobody» из 
«athens.imagmary.com», поскольку «athens.imaginary.com» в порядке сортировки 
стоит выше «% ». Поскольку имена компьютеров сортируются раньше имен 
пользователей, значения привилегий для компьютера, с которого вы подключаетесь, 
имеют приоритет перед любыми конкретными правами, которые у вас могут быть. 
Например, если таблица user содержит записи:
HostUser% 
athens .imaginary .comjaneи jane подключается с «athens.imaginary.com», то 
MySQL будет использовать привилегии, данные «athens.imaginary.com».
Таблица db
Вы могли обратить внимание, что в таблице user не упоминаются конкретные базы 
данных и таблицы. Таблица user управляет сервером в целом. Однако на сервере 
обычно находится несколько баз данных, которые служат различным целям и, 
соответственно, обслуживают разные группы пользователей. Права доступа к 
отдельным базам данных хранятся в таблице db. Эта таблица имеет структуру, 
представленную в таблице 4-2:
Таблица 4-2. Таблица db
ПолеТипNullКлючЗначение по умолчаниюПримеч.Hostchar(60)PRIDbchar(32)PRIUser
char(16)PRISelect privenum('N','Y')NInsert_privenum('N','Y')NUpdate_priv
enum('N','Y')NDelete privenum('N','Y')NCreate_privenum('N','Y')NDrop_priv
enum('N','Y')NReferen-enum('N','Y')Nces_privIndex_privenum('N','Y')NAlter_priv
enum('N','Y')NЭта таблица во многом похожа на таблицу user. Основное отличие в 
том, что вместо колонки Password имеется колонка Db. Таблица управляет правами 
пользователей в отношении определенных баз данных. Поскольку привилегии, 
указанные в таблице user, относятся ко всему серверу в целом, права, 
присвоенные пользователю в таблице user, перекрывают права, присвоенные тому же 
пользователю в таблице db. Например, если пользователю в таблице user разрешают 
доступ типа INSERT, это право действует в отношении всех баз данных, вне 
зависимости от того, что указано в таблице db.
Наиболее эффективно создание в таблице user записей для всех пользователей, в 
которых не даны никакие права. В этом случае пользователь может лишь 
подключиться к серверу, не выполняя никаких действий. Исключение делается 
только для пользователя, назначенного администратором сервера. Все остальные 
должны получить права доступа через таблицу db. Каждый пользователь должен 
присутствовать в таблице user, иначе он не сможет подключаться к базам данных.
Те же правила, которые действуют в отношении колонок User и Host в таблице user,
 действуют и в таблице db, но с некоторой особенностью. Пустое поле Host 
вынуждает MySQL найти запись, соответствующую имени узла пользователя, в 
таблице host. Если такой записи не найдено, MySQL отказывает в доступе. Если 
соответствие найдено, MySQL определяет права как пересечение прав, определяемых 
таблицами host и db. Иными словами, в обеих записях разрешение должно иметь 
значение «Y», иначе в доступе отказывается.
Таблица host
Таблица host служит особой цели. Ее структура показана в таблице 4-3:
Таблица 4-3. Таблица Host
ПолеТипNullКлючЗначение по умолчаниюПримеч.Hostchar(60)PRIDbchar(32)PRI
Select_privenum('N','Y')NInsert_privenum('N','Y')NUpdate_privenum('N','Y')N
Delete_privenum('N','Y')NCreate_privenum('N','Y')NDrop_privenum('N','Y')N
Grant_privenum('N','Y')NReferen-enum('NYY')Nces_privIndex_privenum('N','Y')N
Alter_privenum('N','Y')NТаблица host позволяет задать основные разрешения на 
межкомпьютерном уровне. При проверке прав доступа MySQL ищет в таблице db 
соответствие имени пользователя и его машине. Если он находит запись, 
соответствующую имени пользователя, поле host которой пусто, MySQL обращается к 
таблице host и использует пересечение обоих прав для определения окончательного 
права доступа. Например, у вас может быть группа серверов, которые вы считаете 
менее защищенными, чем остальная часть сети. Вы можете запретить для них все 
права записи. Если «bob» заходит с одной из таких машин, и его запись в таблице 
db содержит пустое поле host, ему будет запрещена операция записи, даже если 
она разрешена ему согласно таблице db.
Таблицы tables_priv и colums_priv
Эти две таблицы, по сути, уточняют данные, имеющиеся в таблице db. Именно, 
право на всякую операцию сначала проверяется по таблице db, затем по таблице 
tables_priv , затем по таблице columns_priv . Операция разрешается, если одна 
из них дает разрешение. С помощью этих таблиц можно сузить область действия 
разрешений до уровня таблиц и колонок. Управлять этими таблицами можно через 
команды SQL GRANT и REVOKE.
Последовательность контроля доступа
Теперь вы знаете, какие элементы участвуют в системе защиты MySQL. Соединим их 
вместе и покажем, как можно ими пользоваться в реальных ситуациях. MySQL 
осуществляет контроль доступа в два этапа. Первый этап - подключение. 
Необходимо подключиться к серверу, прежде чем пытаться что-либо сделать.
При подключении проводятся две проверки. Сначала MySQL проверяет, есть ли в 
таблице user запись, соответствующая имени пользователя и машины, с которой он 
подключается. Поиск соответствия основывается на правилах, которые мы обсудили 
раньше. Если соответствие не найдено, в доступе отказывается. В случае когда 
соответствующая запись найдена и имеет непустое поле Password , необходимо 
ввести правильный пароль. Неправильный пароль приводит к отклонению запроса на 
подключение.
Если соединение установлено, MySQL переходит к этапу верификации запроса. При 
этом сделанные вами запросы сопоставляются с вашими правами. Эти права MySQL 
проверяет по таблицам user, db, host, tables_priv и columns__priv . Как только 
найдено соответствие в таблице user с положительным разрешением, команда 
немедленно выполняется. В противном случае MySQL продолжает поиск в следующих 
таблицах в указанном порядке:
1. db
2. tables_priv
3. columns_priv
Если таблица db содержит разрешение, дальнейшая проверка прекращается и 
выполняется команда. Если нет, то MySQL ищет соответствие в таблице tables_priv 
. Если, к примеру, это команда SELECT, объединяющая две таблицы, то 
пользователь должен иметь разрешения для обеих этих таблиц. Если хотя бы одна 
из записей отказывает в доступе или отсутствует, MySQL точно таким же способом 
проверяет все колонки в таблице columns_priv .
Утилита mysqlaccess
Освоение системы защиты MySQL поначалу может показаться вам затруднительным. 
Несколько упрощает дело имеющаяся в MySQL утилита mysqlaccess. Эта команда 
является сценарием на языке Perl , который, исходя из имен машины, пользователя 
и базы данных, точно показывает, что данный пользователь может делать и почему. 
Например, команда mysqlaccess nobody isp.com mydata может вывести следующее:
Access-rights
for USER 'nobody', from HOST 'isp.com', to DB 'mydata'

BEWARE: Everybody can access your DB as user 'nobody'
: from host 'isp.com' WITHOUT supplying a password. : Be very careful about 
it!!
The following rules are used: db : 'isp.com','mydata','nobody','Y','Y','Y','Y',
'N',
'N','N','N','N','N'
host : 'Not processed: host-field is not empty in db-table.' 
user : '%', 'nobody', ", 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N'
(Выводится, в частности, предупреждение о том, что база доступна любому, 
регистрирующемуся как «nobody» с машины «isp.com» без ввода пароля, в связи с 
чем нужно проявлять осторожность.)
Как видите, даже если вы полностью разобрались с системой безопасности MySQL, 
утилиту mysqlacces полезно использовать для контроля системы безопасности 
вашего сервера.
Изменение прав доступа
MySQL загружает таблицы доступа при запуске сервера. Преимуществом такого 
подхода по сравнению с динамическим обращением к таблицам является скорость. 
Отрицательная сторона состоит в том, что изменения, производимые в таблицах 
доступа MySQL, не сразу начинают действовать. Для того чтобы сервер увидел эти 
изменения, необходимо выполнить команду mysqladmin reload. Если таблицы 
изменяются с помощью SQL-команд GRANT или REVOKE, явно перегружать таблицы не 
требуется.
По каким-то причинам в некоторых дистрибутивах MySQL сценарий mysqlaccess 
указывает на нестандартное расположение исполняемых файлов Perl. Если при 
попытке выполнить mysqlaccess вы получаете сообщение «command not found», то 
это, скорее всего, ваш случай. Вам необходимо изменить строку 1 сценария 
mysqlaccess, чтобы она указывала на правильный путь к Perl, обычно 
/usr/local/bin/perl.
Утилиты MySQL
ТсХ распространяет MySQL с большим набором вспомогательных утилит, однако набор 
утилит, предлагаемых сторонними разработчиками, еще богаче. В этом параграфе мы 
постараемся дать краткий обзор этих инструментов, отложив полное описание до 
главы 18 «Справочник по РНР и Lite».
Утилиты командной строки (Command Line Tools)
isamchk
Производит проверку файлов, содержащих данные базы. Эти файлы называются 
ISAM-файлами (ISAM - метод индексированного последовательного доступа). Эта 
утилита может устранить большую часть повреждений ISAM-файлов. Мы подробнее 
опишем ее ниже.
isamlog
Читает создаваемые MySQL журналы, относящиеся к ISAM-файлам. Эти журналы можно 
использовать для воссоздания таблиц или воспроизведения изменений, внесенных в 
таблицы в течение некоторого промежутка времени.
mysql
Создает прямое подключение к серверу баз данных и позволяет вводить запросы 
непосредственно из приглашения MySQL.
mysqlaccess
Модифицирует таблицы прав доступа MySQL и отображает их в
удобном для чтения виде. Использование этой утилиты — хороший способ изучения 
структуры таблиц доступа MySQL.
mysqladmin
Осуществляет административные функции. С помощью этой утилиты можно добавлять и 
удалять целые базы данных, а также завершать работу сервера.
mysqlbug
Составляет для ТсХ отчет о возникшей в MySQL неполадке. Отчет будет также 
послан в почтовый список рассылки MySQL, и армия добровольцев MySQL будет 
исследовать проблему.
mysqldump
Записывает все содержимое таблицы, включая ее структуру, в файл в виде 
SQL-команд, которыми можно воссоздать таблицу. Выходные данные этой утилиты 
можно использовать для воссоздания таблицы в другой базе или на другом сервере.
mysqlimport
Считывает данные из файла и вводит их в таблицу базы данных. Это должен быть 
файл с разделителями, где разделитель может быть любого обычного вида, например,
 запятая или кавычки.
mysqlshow
Выводит на экран структуру баз данных, имеющихся на сервере, и таблицы, из 
которых они состоят.
Утилиты сторонних разработчиков
Ни один поставщик или разработчик не может самостоятельно предоставить все 
необходимые для программного продукта средства поддержки. Продукты с открытым 
исходным кодом, такие как Linux, имели столь потрясающий успех не только 
благодаря проделанной Линусом Торвальдсом работе по созданию ядра Linux, но и 
благодаря сотням, если не тысячам, программ для Linux сторонних разработчиков. 
MySQL также значительно выиграл от работы подобных добровольцев. Хотелось бы 
перечислить все имеющиеся программы, но этот перечень ежедневно меняется. Ниже 
мы попытались составить представление о том, что имеется в наличии. За самым 
свежим списком обратитесь на домашнюю страницу MySQL: http://www.mysql.
com/Contrib. 
Утилиты преобразования баз данных
access_to_mysql
Преобразует базы данных Microsoft Access в таблицы MySQL. Включается в Access в 
виде функции, позволяющей сохранять таблицы в формате, позволяющем 
экспортировать их в MySQL.
dbf2mysql
Конвертирует файлы dBASE (DBF) в таблицы MySQL. Хотя dBASE утратил популярность,
 формат DBF установился как наиболее распространенный для передачи данных между 
различными приложениями баз данных. Все главные настольные приложения баз 
данных могут читать и писать DBF-файлы. Это приложение полезно для 
экспорта/импорта данных в коммерческие настольные базы данных.
Export sql/Importsql
Конвертирует базы данных Microsoft Access в MySQL и обратно. Эти утилиты 
являются функциями Access, которые можно использовать для экспорта таблиц 
Access в формате, пригодном для чтения MySQL. С их помощью можно также 
преобразовывать SQL-выход MySQL в вид, пригодный для чтения Access.
Интерфейсы CGI
РНР
Создает HTML-страницы с использованием специальных тегов, распознаваемых 
анализатором РНР. РНР имеет интерфейсы к большинству основных баз данных, 
включая MySQL и mSQL. Мы более подробно расскажем о РНР в главе 12 «РНР и 
другие средства поддержки управления HTML со стороны баз данных».
Mysql-webadmin
Осуществляет веб-администрирование баз данных MySQL. Используя это средство, 
можно просматривать таблицы и изменять их содержимое с помощью HTML-форм.
Mysqladm
Осуществляет веб-администрирование баз данных MySQL. Эта CGI-программа 
позволяет просматривать таблицы через WWW, добавлять таблицы и изменять их 
содержимое.
www-sql
Создает HTML-страницы из таблиц баз данных MySQL. Эта программа осуществляет 
разбор HTML-страниц в поисках специальных тегов и использует извлеченные данные 
для выполнения команд SQL на сервере MySQL.
Клиентские приложения
Mysqlwinadmn
Позволяет администрировать MySQL из Windows. С помощью этого средства можно 
выполнять функции mysqladmin из графического интерфейса.
xmysql
Обеспечивает полный доступ к таблицам баз данных MySQL для клиента X Window 
System. Поддерживает групповые вставки и удаления.
xmysqladmin
Позволяет осуществлять администрирование MySQL из X Window System. Это 
инструмент для графического интерфейса, позволяющий создавать и удалять базы 
данных и управлять таблицами. С его помощью можно также проверять, запущен ли 
сервер, перегружать таблицы доступа и управлять потоками.
Интерфейсы программирования
MyODBC
Реализует ODBC API к MySQL в Windows.
Db.py
Обеспечивает доступ MySQL к сценариям Python. Для повышения производительности 
этот модуль осуществляет буферизацию извлекаемых данных. Программирование на 
Python для MySQL мы излагаем в главе 11, а подробное справочное руководство по 
Python представлено в главе 20.
Vdb-dflts
Реализует библиотеку Vdb для MySQL. Vdb - не зависящий от типа базы данных API 
для С, позволяющий единому клиенту иметь доступ к различным серверам баз данных.
 Клиенты Vdb могут использовать этот API для досупа к базам данных MySQL.
Delphi-interface
Предоставляет API доступа к MySQL для среды Delphi, выпускаемой Inprise. С 
помощью этого API любое приложение Delphi получает доступ к базам данных MySQL.
dump2h
Преобразует структуры таблиц MySQL в файлы заголовков С. Эта программа 
принимает обычный файл, создаваемый mysqldump и генерирует заголовочный файл С, 
описывающий таблицу в виде структуры (st ruct) на С.
mm.mysql.jdbc
Реализует стандартный API JDBC (Java Database Connectivity -доступ к базам 
данных из Java). В главе 14 «Java и JDBC» подробно обсуждается программирование 
на Java с использованием этого API, а в главе 22 «Справочник по JDBC» 
представлено полное справочное руководство по JDBC 2.0.
twzJdbcForMysql
Реализация JDBC API для Java.
Mysqltcl
Реализует интерфейс Tel к MySQL.
MySQLmodule
Реализует доступ к MySQL из Python.
Mysql-c++
Объектно-ориентированная оболочка MySQL С API для доступа из приложений на C++.
MySQL++
Обеспечивает объектно-ориентированный доступ к MySQL для приложений на C++,
Pike-mysql
Позволяет пользователям известного веб-сервера Roxen разрабатывать 
интернет-приложения с доступом к MySQL.
Sqlscreens
Генерирует экраны баз данных на Tcl/Tk на основе баз данных MySQL. Позволяет 
разработчикам строить специализированные . GUI, привязанные к таблицам MySQL.
Squile
Позволяет создавать сценарии на Guile для доступа к таблицам MySQL.
Wintcl
Поддерживает встраивание кода Tel в HTML-файлы. С помощью этого средства легко 
разрабатывать веб-приложения, способные осуществлять доступ к базам данных 
MySQL.
Разное
Emacs-sql-mode
Адаптирует стандартный режим SQL для Emacs для поддержки особенностей 
синтаксиса SQL в MySQL. Вводит отступы, выделяет синтаксис и довершает команды, 
что облегчает работу с SQL.
findres
Отыскивает в таблицах MySQL зарезервированные слова. Эта-программа ищет в 
таблицах MySQL зарезервированные слова SQL, которые могут нарушить правильную 
работу других баз данных, поддерживающих SQL.
Hyalog
Сохраняет в таблице MySQL исходящие факсимильные сообщения. Эта программа 
отслеживает факсы, отправляемые программой HylaFax, и сохраняет их копии в базе 
данных MySQL.
mod_auth_mysql
Осуществляет аутентификацию пользователей сервера Apache. Обычно Apache 
осуществляет контроль доступа с помощью простых текстовых файлов, содержащих 
имена пользователей и зашифрованные пароли. Данный модуль позволяет управлять 
доступом через базу данных MySQL.
mod_log_mysql
Регистрирует трафик WWW, проходящий через сервер Apache, в базе данных MySQL.
mysqlpasswd
Обеспечивает добавление, удаление и изменение записей о пользователях, хранимых 
в MySQL модулем mod_auth_mysql из состава Apache.
Mysql_watchdog
Осуществляет контроль за MySQL с целью обеспечения его непрерывного 
функционирования с нормальными параметрами.
Nsapi_auth_mysql
Аутентифицирует пользователей на веб-сервере Netscape. 
Pam_mysql
Предоставляет интерфейс РАМ (Pluggable Authentication Module -подключаемый 
модуль аутентификации) к MySQL. РАМ обеспечивает проверку пользователей для 
ряда служб, включая стандартную регистрацию в системе.
Wuftpd-mysql
Позволяет регистрировать в базе данных MySQL трафик FTP через демон WuFTP.
Настройка производительности
Разница между хорошим администратором баз данных и первоклассным 
администратором состоит в том, что один знает, как управлять сервером баз 
данных, а второй знает, как сервер живет и дышит. Решение проблем 
производительности часто лежит на пути глубокого понимания того, как работает 
MySQL, что дает возможность оптимизировать работу приложения, используя все 
возможности сервера.
MySQL имеет три потенциальных «узких места» при любом подключении. Во-первых, 
это сетевое соединение клиента с сервером. Во-вторых, это время решения таких 
задач, как, скажем, построение индексов. И наконец, проблема может быть связана 
с дисковым вводом/выводом. MySQL предоставляет доступ к переменным, с помощью 
которых ее функционирование можно настроить в соответствии со средой приложения.
 Все эти переменные можно установить, используя параметр -О в команде mysqld. 
Например, переменная back_log принимает значение 15 в результате добавления к 
mysqld параметра -О backjtog=15. Ниже следует список полезных переменных.
bach_log
Количество одновременных подключений по TCP/IP в очереди. При наличии большого 
числа удаленных пользователей, одновременно подключающихся к вашей базе данных, 
может потребоваться увеличить это число. Отрицательной стороной большого 
значения является некоторый рост использования памяти и загрузки ЦП.
key_buffer
Буфер, выделяемый для хранения последних использовавшихся ключей. Если запросы 
выполняются слишком медленно, увеличение этого значения может оказаться 
благотворным. Отрицательный эффект - увеличение расхода памяти.
max Connections
Число одновременных соединений, разрешенное сервером баз данных. Если при 
активной работе пользователи иногда получают отказ в доступе, возможно, это 
число следует увеличить. Отрицательное последствие - увеличение загрузки 
сервера, то есть рост использования ЦП, расхода памяти и дискового ввода/вывода.

table_cache
Буфер, используемый для хранения данных, к которым происходит частое обращение. 
Если выделить под них память, то резко сокращается объем обращений к диску. 
Отрицательный эффект - существенное увеличение расхода памяти.
Структура хранения данных в MySQL
Для хранения каждой таблицы MySQL используется три файла. Например, средних 
размеров таблица mytable может выглядеть так:
-rw-rw-- - 1 root root 1034155 Jun 3 17:08 mytable.ISD
-rw-rw---- 1 root root 50176 Jun 3 17:08 mytable.ISM
-rw-rw-- - 1 root root 9114 Jun 3 14:24 mytable.frm
В файле ISD хранятся фактические данные. В файле ISM хранятся данные о ключах и 
прочие внутренние данные, необходимые MySQL для быстрого поиска данных в файле 
ISD. Файл f rm содержит структуру самой таблицы.
Файл ISM наиболее важен для функционирования MySQL. Он настолько важен, что ему 
посвящена целая утилита isamchk. Запуск isamchk -d выводит сведения о таблице:
# isamchk -d mytable
ISAM file: mytable
Data records: 1973 Deleted blocks: 0
Recordlength: 343
Record format: Packed
table description:
Key Start Len Index Type
1 2 50 unique text packed stripped
Важное поле, которое нужно отметить, это «Deleted blocks» (удаленные блоки). 
Если его значение слишком велико, то файл понапрасну занимает много лишнего 
места. К счастью, это пространство можно освободить. В результате выполнения 
следующей команды таблица будет просмотрена и создана заново, при этом будут в 
большинстве своем устранены ошибки и высвобождено свободное пространство:
isamchk -r mytable
Еще большего увеличения скорости можно добиться, применив к таблице команду 
Isamchk -а. Эта команда анализирует размещение данных в таблице. Ее следует 
выполнить после вставки или удаления большого числа записей.
Восстановление поврежденных таблиц
При авариях сервера или по другим естественным причинам таблица базы данных 
может оказаться поврежденной. С помощью isamchk обеспечивается несколько 
уровней восстановления:
isamchk mytable
При запуске isamchk во время работы сервера может потребоваться выполнить 
mysqladmin reload, чтобы сервер «увидел» исправленную таблицу.
Эта команда исправляет большинство обычных ошибок в таблице. Добавление 
параметров -г и -v приводит к выводу дополнительных сведений о том, что было 
нарушено. Использование нескольких -и увеличивает подробность вывода сведений.
isamchk -rq mytable
Эта команда осуществляет быструю проверку и при необходимости исправление 
только файла ISM, файл ISD при этом не проверяется.
isamchk -e mytable
С этим параметром производится полная проверка и исправление всего, что можно, 
и устранение любых повреждений. Такая проверка обычно производится значительно 
дольше, чем обычная. Выполнение команды прекращается в момент столкновения с 
первой серьезной ошибкой. Для продолжения проверки даже после нахождения 
серьезных повреждений передается параметр -v. Тем самым гарантируется 
отсутствие повреждений в результирующей таблице, но при этом может произойти 
потеря некоторых данных.
Прежде чем выполнять команду, способную изменить содержимое таблицы, всегда 
делайте резервную копию данных. Утилита isamchk очень хороша для исправления 
ошибок, но иногда это означает уничтожение поврежденных данных, входящих в 
конфликт с остальными данными таблицы. При наличии резервной копии можно 
восстановить данные, уничтоженные утилитой isamchk.
Удаление и замена ключей
Иногда ключи замедляют скорость работы с базой данных. Если, к примеру, вы 
намерены ввести большой объем данных, индексирование ключей после каждой 
вставки может оказаться очень неэффективным. Кроме того, если ваша таблица 
имеет поврежденные ключи, в результате безоглядного исправления таблицы 
утилитой isamchk может произойти потеря данных, связанных с ключом.
В этих случаях оказывается полезным временное удаление ключей из таблицы и 
воссоздание их после завершения опасной работы. Следующая команда удаляет ключи 
из таблицы:
isamchk -rq -k0
Если вы готовы снова вставить ключи, это можно сделать командой:
isamchk -rq
Прежде чем ввести команду isamchk с параметром -r, завершите работу сервера, 
иначе таблица может оказаться повреждений.
Команда isamchk предоставляет столько возможностей, что вам, вероятно, станет 
сложно разобраться во всех них. Следует, однако, руководствоваться следующими 
соображениями:
* Если база данных новая, почаще выполняйте isamchk, -а. В большинстве 
приложений баз данных основной массив данных вводится в начале существования 
базы. Если выполнять isamchk с параметром, указывающим на необходимость анализа 
данных всякий раз, когда размер базы данных удваивается, можно быть уверенным в 
эффективности хранения данных.
* Раз или два в год выполняйте команду isamchk -d. Если число удаленных блоков 
в ваших таблицах составляет существенную часть дискового пространства, 
выполните isamchk -r для перестройки таблиц с высвобождением ненужного места. 
Если ваше приложение таково, что приходится удалять много старых данных и 
вводить новые, выполняйте isamchk -d каждые две недели, а если число удаленных 
блоков быстро растет, может понадобиться выполнять isamchk -r регулярно - раз в 
месяц.
* За исключением операций удаления и замены ключей, которые нужно производить 
всякий раз, когда одновременно вводился несколько десятков записей, все 
остальные виды isamchk следует выполнять только в ответ на появившуюся в базе 
данных несовместность.
Устранение неполадок
Даже в самых совершенных программах возникают проблемы. К счастью, многие из 
проблем, с которыми вы можете столкнуться, уже с кем-то случались. Ниже 
приводится ряд часто встречавшихся проблем при администрировании MySQL.
Изменения в таблицах доступа не действуют.
Не забывайте выполнять команду mysqladmin reload после внесения изменений в 
таблицы доступа.
При высокой загрузке MySQL отказывает в подключении.
1. Сначала уточните число соединений, допускаемых сервером. Команда mysqladmin 
variables покажет его значение в поле max_connec-tions. Можно увеличить это 
число, запустив mysqld с параметром -О max_connections=###, где ### - предел, 
который вы хотите установить.
2. Можно также проверить значение back_log , которое определяет размер очереди, 
создаваемой MySQL для входящих соединений, равное 5 по умолчанию. Версии MySQL 
до 3.22 позволяли увеличить это значение до 64, но в более поздних версиях его 
можно увеличить до 1024. Однако оно может быть ограничено до 64 вашей 
операционной системой.
3. Наконец, эта проблема может быть вызвана ограничением числа дескрипторов 
файлов. Симптомом этого является полный отказ в подключениях при запуске MySQL 
большого числа потоков. Unix-системы позволяют устанавливать число дескрипторов 
файлов разными способами, поэтому следует справиться в системной документации о 
том, как это сделать.
MySQL сообщает о невозможности найти файл, который явно существует, или 
сообщает об ошибках во время его чтения.
В большинстве случаев эта проблема связана с числом дескрипторов файлов, о 
котором говорилось выше. Однако если увеличить буфер таблиц MySQL, ему не 
потребуется открывать так много файлов, и вы сможете избавиться от этой 
проблемы. По умолчанию величина буфера таблиц равна 64. Можно увеличить его 
через значение переменной table_cache .
Число потоков начинает расти, и потоки не завершаются,
В некоторых системах с установленным NFS, а также в Linux, есть проблемы с 
механизмом блокировки файлов. Результатом может быть замораживание потоков. 
Команда mysqladmin processlist поможет выявить эту проблему. Если в поле 
«Command» против замороженных потоков стоит «System lock», запустите mysqld с 
параметром --skip_ locking.
Глава №5.
mSQL
Концепции баз данных и их проектирование имеют очень важное значение, но вы, 
вероятно, хотите приступить к непосредственной работе с MySQL или mSQL. He 
исключено, что вы уже выбрали ту или иную СУБД соответственно своим 
потребностям. Возможно, однако, вы надеетесь, что эта книга поможет вам принять 
такое решение. В этой главе мы подробно разберем mSQL. Если вы уже стали 
приверженцем MySQL, то эту главу можно пропустить. Напротив, если вас 
привлекает mSQL или вы хотите больше узнать о внутренних механизмах обеих баз 
данных, следует начать с этой главы.
mSQL является реляционной системой управления базами данных (РСУБД), открывшей 
эру дешевых баз данных малого и среднего масштаба с поддержкой SQL. Малые 
размеры, впечатляющая производительность и простота изучения сделали ее 
предпочтительным выбором растущего числа разработчиков программ для Интернет, 
которым не достает времени, чтобы стать экспертами в области программирования 
баз данных. Автор mSQL намеренно стремился к достижению этих целей, приступая к 
созданию программного продукта, способного заполнить зияющий пробел в ряду 
РСУБД.
Архитектура
Дэвид Хьюз преследовал три цели, создавая mSQL:
* mSQL должна быть быстрой.
* mSQL должна быть компактной.
* mSQL должна обеспечивать множественность одновременных подключений.
Высокая скорость была главной целью mSQL. Поскольку в большинстве коммерческих 
SQL-серверов разработчики стараются реализовать полную спецификацию SQL2, а 
кроме того, и собственные расширения языка, им приходится расплачиваться 
производительностью и размерами. MSQL, напротив, жертвует некоторыми наиболее 
изощренными возможностями коммерческих серверов в пользу скорости. Для проекта 
Minerva требовалась возможность быстрого выполнения большого числа простых 
SQL-запросов. Именно это позволяет делать mSQL.
Скорость и размеры идут рука об руку. Как обнаружил Хьюз, если начать с самого 
основания и реализовать лишь самые необходимые функции, можно разработать 
SQL-сервер, который будет требовать столь мало ресурсов, что для его успешного 
использования не потребуется отдельной машины. В результате, mSQL обладает 
значительной частью функциональности основных РСУБД, требуя значительно меньших 
ресурсов.
Скорости и размера, достигнутых в mSQL, было бы достаточно для того, чтобы 
успешно заменить Postgres в проекте Minerva. Хьюз, однако, хотел изменить и ту 
модель поведения, которая, собственно, заставила его искать альтернативу. Хьюз 
спроектировал mSQL так, чтобы та могла обрабатывать множественные одновременные 
подключения в рамках одного процесса. В результате получается маленький, 
быстрый, эффективный SQL-сервер, способный одновременно обрабатывать несколько 
запросов - локально или по сети.
Для реализации своих проектных целей Хьюзу пришлось ограничить функциональность 
сервера. Диалект SQL, поддерживаемый mSQL, является подмножеством стандарта 
ANSI SQL2, содержащим наиболее употребительные команды, такие как CREATE, 
INSERT, SELECT, UPDATE и DELETE. Хьюз отказался от ресурсоемких операций, вроде 
поддержки транзакций. В том типе приложений, которые используют mSQL, 
функциональность, опущенная Хьюзом, обычно не требуется.
mSQL является однопоточным сервером с очередью. Одновременно к серверу может 
подключиться любое число клиентов - до определенного предела. При отправке 
клиентом запроса к серверу mSQL ставит запрос в синхронную очередь и 
обрабатывает все запросы последовательно по одному. Эффективность такого 
решения зависит, таким образом, от способности сервера быстро обработать каждый 
запрос. Если запросы вовремя не обрабатывать, очередь будет расти, что в итоге 
приведет к краху сервера из-за превышения системных ограничений. Поэтому 
скорость является решающим фактором для успешной работы mSQL. На рис. 5-1 
показана работа очереди mSQL и однопоточная работа.
Однопоточная сущность mSQL устраняет необходимость в пакетной обработке. 
Поскольку запросы выполняются поочередно, они не способны помешать один другому.
 Конечно, было бы неплохо, если бы mSQL поддерживала транзакции, но в них нет 
необходимости для нормальной работы ядра базы данных при тех целях, которые 
ставились перед mSQL.
mSQL поддерживает два типа соединений со стороны клиента. Удаленные клиенты 
подключаются к серверу через известный порт TCP/IP. Используя TCP/IP, база 
данных mSQL может предоставлять доступ любому компьютеру в мире через Интернет. 
Локальные соединения тоже могут производиться через TCP/IP, но лучшей 
производительности можно добиться, используя стандартный сокет Unix, что 
эффективнее примерно на 20%.

Рис. 5-1. Архитектура клиент,/сервер в mSQL
С mSQL связан набор программ, позволяющих осуществлять полный доступ к базе 
данных. Монитор msql позволяет пользователю непосредственно направлять запросы 
серверу. Хотя во время разработки этот инструмент полезен, большинству 
пользователей необходим какой-либо интерфейс для доступа к базе данных 
посредством какого-либо приложения. Для поддержки разработки приложений mSQL 
имеет встроенный API на языке С, позволяющий любой С-программе соединяться с 
сервером mSQL через TCP/IP или сокет Unix.
mSQL поддерживает также сетевой протокол, позволяющий подключаться к серверу по 
сети, используя другие языки, без С API. С помощью этих двух интерфейсов 
разработчики, использующие множество языков, разработали библиотеки для 
подключения к mSQL почти из любого известного языка. В данной книге 
рассказывается об использовании API для С, Perl, Java и Python.
Версии mSQL
После выхода mSQL сообщество разработчиков программ немедленно подверглось его 
воздействию. Впервые появилась возможность работы с доступным по цене, 
поддерживающим SQL, ядром базы данных. Одной из поразительных особенностей было 
то, что оно не только было сравнимо по производительности с основными 
коммерческими продуктами, но на практике было быстрее - иногда более, чем в 100 
раз -в тех областях, для которых предназначалось.
Однако в наше время вычислительная среда долго не стоит на месте. С 
возникновением широкомасштабного сотрудничества через Интернет не стало 
проектов, недоступных для преданных им групп программистов. К 1996 году стали 
появляться другие недорогие реализации SQL, MySQL в их числе, и mSQL перестала 
существовать в одиночестве.
В продолжение 1990-х Хьюз разрабатывал и совершенствовал mSQL. Однако ядро базы 
данных в итоге достигло той точки, где дальнейшая разработка требовала 
глубокого пересмотра всего проекта. Такая большая работа потребовала бы много 
времени, поскольку новый проект влечет новые ошибки и промахи. Одновременно 
необходимо осуществлять и поддержку существующего продукта. Таким образом, mSQL 
2 появилась как переработка ядра базы данных при продолжении одновременной 
поддержки существующего продукта - mSQL 1.
mSQL 2 вышла в то время, когда первоначальный продукт начал устаревать. 
Проблемы с устойчивостью и отсутствие важных функциональных возможностей, таких,
 как поддержка достаточного числа типов данных, заставляли искать другие 
решения, например MySQL. mSQL 2 обеспечила устранение многочисленных ошибок, 
досаждавших пользователям последних версий mSQL 1, и добавила многочисленные 
новые возможности, сохраняя при этом верность первоначальным целям проекта. 
Расширилось подмножество ANSI SQL, поддерживаемое mSQL, и было добавлено 
несколько новых типов данных. Был переработан способ индексирования, 
значительно повысивший мощь системы.
Основные изменения, произведенные в mSQL 2 в сравнении с mSQL 1, следующие:
Возросшие устойчивость и производительность
В первом выпуске mSQL 2 были решены все известные проблемы со стабильностью в 
mSQL 1. Были устранены утечки памяти, а код тщательно протестирован для 
выявления ошибок. Общая производительность выросла, несмотря на добавление 
новых характеристик.
Улучшенная поддержка индексов
В первой версии mSQL использовалась очень слабая схема индексирования. В каждой 
таблице можно было иметь только один индекс, состоящий только из одной колонки, 
- первичный ключ. В mSQL 2 индексирование полностью переработано с целью 
поддержки более сложных и часто встречающихся задач. Теперь можно иметь 
несколько индексов для каждой таблицы и составлять их более чем из одной 
колонки. Индексирование теперь поддерживает индексные файлы как в виде В-дерева,
 так и в стиле AVL.
Дополнительные типы данных
В mSQL 2 добавились многие типы данных, что приближает его к полной реализации 
спецификации ANSI SQL2. Наряду с MONEY, DATE и TIME mSQL 2 поддерживает теперь 
и тип TEXT. В первоначальной версии mSQL все поля были фиксированной длины, и 
поэтому текстовые поля типа CHAR имели предустановленный размер. Часто для 
поддержки таких атрибутов, как адреса электронной почты или названия книг, 
приходилось определять большое поле типа CHAR, что приводило к неоправданному 
расходу памяти. Например, для поля адреса электронной почты вы определили бы 
поле CHAR(35). Даже если адрес оказывался «[email protected]», mSQL использовал 
все 35 символов поля. Еще хуже то, что если адрес оказывался длиннее 35 
символов, вам сильно не повезло. Новый тип данных TEXT решает обе проблемы, 
позволяя вам задать среднюю длину поля. Все, превышающее этот размер, будет 
храниться в буфере переполнения. При меньшем размере лишние символы не будут 
записываться. К сожалению, поля типа TEXT имеют недостатки, не позволяющие 
использовать их в качестве индексов и употреблять в предложениях типа LIKE.
Улучшенный сервис и поддержка API
Стандартный инструментарий, поставляемый с mSQL, улучшен с целью поддержки всех 
новых характеристик. Хьюз добавил новые функции, такие как, например, 
копирование и переименование таблиц в msqladmin. Приложение W3-msql для 
взаимодействия с WWW существенно переделано и дополнено. Язык сценариев 
переработан в Lite - язык с прямой поддержкой взаимодействия WWW и баз данных.
Если вы новичок в mSQL, то почти наверняка начнете работать с mSQL 2. Если вы 
имеете дело с уже работающей системой, то следует скрупулезно учитывать 
различия между обеими версиями, особенно если вы собираетесь перейти на mSQL 2.
Установка mSQL
Первым шагом при работе с mSQL является, естественно, загрузка и установка. Как 
вы это сделаете, зависит от типа предполагаемой платформы. mSQL появилась как 
приложение для Linux, и это та платформа, которую поддерживает Хьюз. Если у вас 
работает какая-то разновидность Unix, mSQL, скорее всего, сможет на ней 
работать. Даже если нет, mSQL поставляется с исходным текстом, и опытный 
С-программист исправит места, создающие несовместимость. Дистрибутив для Unix 
находится по адресу http://www.hughes.com.au.
Если вы работаете под Windows или OS/2, для вас тоже не все потеряно: 
переложения для Win32 и OS/2 также активно поддерживаются. Последние версии 
mSQL для PC находятся по адресу http://blnet.com/ msqlpc/. Хотя эти приложения 
относительно новые, они всегда немного отстают от самых свежих версий, 
предоставляемых Хьюзом. В момент написания книги номер текущей версии для Unix 
был 2.0.7, текущей версии для Win32 - 2.0.4.1, и текущей версии для OS/2 - 2.06.
 Меньше повезло пользователям Мае. На Макинтош перенесены только клиентские 
средства для mSQL.
Процедура установки зависит от платформы. Пользователям Unix придется 
компилировать свой дистрибутив, а для Win32 и OS/2 поставляются 
прекомпилированные двоичные файлы. Поскольку процедура установки меняется от 
одной версии к другой, мы не станем здесь останавливаться на ее подробностях. 
Вам следует изучить документацию, предоставленную вместе с вашим дистрибутивом, 
поскольку она наверняка соответствует точной процедуре установки для вашей 
версии.
Запуск mSQL
mSQL - это действительно единственное ядро базы данных типа «завел и поехал». 
Иными словами, можно установить mSQL, запустить сервер и сразу заняться делом. 
Серверный процесс mSQL называется msql2d (для серверов mSQL 1 он называется 
msqld). Этот исполняемый файл и все утилиты, поступающие с дистрибутивом mSQL, 
находятся в каталоге bin. Запустить экземпляр mSQL можно, просто введя msql2d 
без всяких параметров командной строки.
Такая реализация по умолчанию не всегда вас удовлетворит. В большинстве случаев 
потребуется отредактировать файл msql.conf в каталоге дистрибутива mSQL. Этот 
файл конфигурации mSQL 2 (в mSQL 1 он отсутствует) позволяет определить 
несколько часто используемых параметров. Его изменение обычно необходимо тогда, 
когда вы используете какой-нибудь прекомпилированный дистрибутив.
Демон mSQL - не ветвящийся процесс. Это означает, что запуск его из командной 
строки оставит процесс работать на терминале, пока вы явно не нажмете CTRL-C, 
чтобы прекратить его, или не переведете процесс в фоновый режим. Под Unix можно 
запустить сервер mSQL из командной строки в фоновом режиме, введя команду:
msqld2 &
Следующий сценарий запускает процесс сервера mSQL при запуске системы и 
корректно завершает его при остановке системы:
#!/bin/sh
if [ $1 - "start" ]; then 
if [ -x /usr/local/Hughes/bin/msql2d ]; then
su msql -c '/usr/local/Hughes/bin/nisql2d &'
fi
else
if [ $1 = "stop" ]; then 
if [ -x /usr/local/Hughes/bin/msqladmin ]; then
su msql -c '/usr/local/Hughes/bin/msqladmin shutdown'
fi
fi
fi
В этом сценарии предполагается, что вы запускаете mSQL в Unix с идентификатором 
пользователя msql. Разумеется, его нужно заменить конкретным ID пользователя, а 
также заменить /usr/'local/Hughes именем каталога, в который вы установили mSQL.

Поскольку версия для Win32 не работает пока как служба NT, можно запускать mSQL 
из папки Автозагрузка (StartUp), просто поместив ярлык для файла msql2d.exe в 
папку Автозагрузка (использование команды msqladmin мы опишем ниже в данной 
главе).
Хотя mSQL является очень устойчивой программой, иногда случаются какие-то 
неполадки, и сервер «умирает». В особенности ранние версии mSQL имели проблемы 
с устойчивостью, приводившие к неожиданному краху сервера. На этот случай 
желательно запустить какое-либо средство для проверки состояния сервера баз 
данных.
Приведенный ниже сценарий Unix старательно проверяет, работает ли еще демон 
msql2d. Если сервер не активен, он перезапускается, и администратору машины 
посылается сообщение.
#!/bin/sh
# Извлечь ID процесса демона базы данных
# Это годится для mSQL 2; для mSQL 1
# Строка должна быть другой:
# PID='cat /usr/local/Minerva/msqld.pid' PID='cat /usr/local/Hughes/msq!2d.pid'
# Далее проверяется активность процесса сервера.
# Эта строка пригодна для систем BSD (Linux)
ALIVE='ps aux grep $PID | grep -v grep | awk '{print $2}"
# Для систем SysV (Solaris) раскомментируйте следующую строку 
#ALIVE='ps -et grep $PID | grep -v grep | awk '{print $2}"
if [ $ALIVE ]
then
REALLY_ALIVE='msqladmin version' DATE='date'
#Если 'ERROR', или если
# выдачи вообще не было, msqladmin
# не могла подключиться к серверу баз данных
if ! echo $REALLY_ALIVE | grep "^ERROR"
then
exit
fi
if [ ! $REALLY_ALIVE ] 
then exit;
fi
else
# Для mSQL 1 должно быть /usr/local/Minerva/hin/msqld &
# for mSQL installations /usr/local/Hughes/bin/msql2d &
mail -s "mSQL daemon restarted" [email protected] < /usr/backups/database1.sql. daily 
msqldump database2 > /usr/backups/database2.sql. daily
msqldump database3 > /usr/backups/database3.sql. daily
В этом примере создается дамп трех разных баз данных в одном каталоге.
Расширение daily используется для указания на то, что резервные копии создаются 
ежедневно. Как часто вы будете резервировать данные, зависит от их важности, 
размера и типа имеющихся у вас носителей. Поскольку mSQL позволяет создавать 
только полные дампы, размер резервных копий может быть очень большим в системах,
 содержащих большой объем данных. Если у вас достаточно места, то неплохо 
делать отдельные резервные копии для каждого дня недели или даже двух недель 
или месяца. По окончании цикла ленты используются заново, если это необходимо; 
а при записи на жесткий диск переписываются файлы. При такой схеме всегда есть 
данные за одну неделю. При создании резервных копий на жестком диске можно 
объединить отдельные ежедневные копии в одну ежедневную копию, перезаписываемую 
каждый день. В этом случае следует также иметь отдельную еженедельную копию, 
чтобы восстановить случайно удаленные данные, отсутствующие в последней дневной 
копии. Такую схему можно использовать, только если вы ограничены в пространстве 
для резервирования.
Другой метод резервирования основывается на простоте структуры файлов данных 
mSQL. В отличие от некоторых других пакетов, mSQL хранит данные в обычных 
файлах операционной системы, поэтому можно обращаться с ними как со всякими 
другими файлами. Полную резервную копию mSQL можно сделать, остановив сервер и 
создав tar-архив каталога данных mSQL. Предварительно сервер следует остановить,
 в противном случае данные могут оказаться неполными или поврежденными.
Восстановление данных из резервных копий производится столь же просто, как 
создание копий. Дампы, создаваемые msqldump, имеют стандартную форму SQL и 
могут быть обработаны монитором msql. Эти дампы содержат команды для создания 
как таблиц, так и данных, поэтому нужно либо удалить существующие таблицы, либо 
удалить из дампов команды CREATE TABLE. Если вы восстанавливаете только 
отдельные строки данных, можно просто скопировать их из дампа и подать на вход 
монитора msql.
При восстановлении данных из архивной копии каталога данных mSQL возможно 
только полное восстановление сохраненного состояния. Нельзя восстановить 
какую-то часть данных, и все изменения, произведенные после создания последней 
резервной копии, будут утеряны. Для проведения этого восстановления просто 
остановите сервер и затем введите резервный файл в каталог данных mSQL. После 
перезапуска сервера он окажется точно в том состоянии, которое было перед 
созданием копии, за исключением того, что будут присутствовать вновь 
добавленные базы данных, сохраненные в неприкосновенности.
Выбор метода зависит от ваших потребностей. Создать двоичный архив очень просто,
 и восстановление при этом происходит очень быстро. Однако при этом нельзя 
делать частичное восстановление, и вновь добавленные данные будут утеряны. С 
другой стороны, создание дампа в виде SQL может занять много времени, хотя он 
допускает частичное восстановление, правда, с некоторыми усилиями. Кроме того, 
дамп SQL можно создать в любой момент, в то время как для создания архива 
требуется завершить работу сервера, что может оказаться решающим фактором при 
интенсивной работе.
И последнее, что следует учитывать, - вопрос переносимости. В отличие от 
двоичной резервной копии, дамп SQL - текстовый и целиком состоит из SQL-команд. 
При незначительной модификации, главным, образом для удаления специфического 
SQL, дамп SQL может быть импортирован любым совместимым со стандартом SQL 
сервером. Это очень удобный способ перемещения данных, если возникает 
необходимость перейти на новый сервер SQL.
Система безопасности
Система безопасности, поддерживаемая сервером mSQL, может, в зависимости от 
точки зрения, показаться как достоинством, так и недостатком. С одной стороны, 
ей легче управлять, чем в любой другой РСУБД. Эта легкость достигается 
благодаря упрощенности. К сожалению, такая упрощенность недопустима для 
сколько-нибудь сложных приложений баз данных.
mSQL управляет безопасностью с помощью файла msql.acl, который находится в 
каталоге установки mSQL. Расширение .acl образовано от «Access Control List» - 
«Список контроля доступа» - очень гибкой системы авторизации, с некоторого 
времени используемой в ряде операционных систем и приложений. Формат файла msql.
acl следующий:
database=mydata
read=*
write=*
host=*
access=local,remote
database=mynewdata read=*
wriite=admin,root host=* access=local
Для каждой базы данных есть ряд опций. Строки read и write указывают, каким 
пользователям вы хотите предоставить право чтения (SELECT) базы или записи 
(INSERT, UPDATE, DELETE) в базу данных. Строка host показывает, какие машины 
могут иметь удаленный доступ к базе. Если строка access содержит «local», 
значит, разрешены локальные подключения через сокеты Unix, а если содержит 
«remote», то разрешены удаленные подключения по TCP.
В файле ACL допустим символ-маска «*» в полях read, write и host. Поэтому можно 
иметь такой ACL:
database=mynewdata
read=*
write=msql*
host=*. client.com,"isp.com
access=local, remote
Этот ACL означает, что любой пользователь любой машины в client.com, а также 
любой пользователь любой машины в любом домене, оканчивающемся на isp.com - 
например, wisp.com или lisp.com, - может иметь подключение к базе данных. Эти 
пользователи могут осуществлять чтение данных, но только пользователи, чьи 
имена начинаются с «msql», могут вносить в нее изменения.
По умолчанию все права отсутствуют, поэтому если вы пропустите строку write, 
никто не сможет модифицировать базу данных. Отдельные пользователи и машины 
могут исключаться с помощью префикса «-» перед их именем. Рассмотрим пример:
dataoase=moredata
read=-bob,*
write=jane
host=-junk. isp.com,*, isp.com
access=local,remote
Этот ACL разрешает подключение всем хостам домена isp.com, за исключением junk.
isp.com. Кроме того, чтение разрешено всем пользователям, кроме пользователя 
«bob». Только «jane» имеет право записи в базе данных. Поскольку по умолчанию 
установлен отказ в доступе, конкретно указывать, кому отказано в доступе, как 
«bob'y»» бессмысленно, если строка не содержит также символа «*».
mSQL действует согласно первому обнаруженному соответствию. Например, строка 
read=*,-bob дает пользователю «bob» право чтения.
Как указывалось ранее в этой главе, команда msqladmin reload перезагружает ACL 
после внесения вами изменений. Если вы ее не выполните, внесенные изменения 
будут учтены только при следующем перезапуске сервера.
Утилиты mSQL
Об одной из поставляемых с mSQL утилит, msqladmin, мы уже рассказали. mSQL 
содержит семь основных утилит, составляющих основу взаимодействия с ней. В 
дополнение к этим основным утилитам mSQL
поддерживает облегченную утилиту обработки сценариев Lite и интерфейс к WWW под 
названием W3-mSQL. Помимо того, существуют многочисленные средства сторонних 
разработчиков. Сейчас мы подробно остановимся на базовых утилитах, поставляемых 
с mSQL, и пробежим по списку утилит «со стороны». К Lite и W3-mSQL мы обратимся 
позднее.
Утилиты командной строки
Каждая утилита командной строки имеет подробную подсказку, разъясняющую ее 
синтаксис. В основном этот синтаксис является копией команды msqladmln. Именно, 
параметр -h позволяет указать машину, а параметр -/ позволяет задать имя 
конкретного файла конфигурации.
msql
Это интерфейс командной строки к mSQL, позволяющий интерактивно выполнить 
команду SQL для заданной базы данных. Кроме обычных параметров, отмеченных выше,
 вы задаете имя базы данных, к которой хотите обратиться. Из всех утилит эта, 
вероятно, используется наиболее часто.
msqldump
Эта команда выводит все содержимое базы данных или таблицы, включая саму 
структуру таблицы, в виде ряда команд SQL. Результат работы этой утилиты можно 
использовать для создания резервной копии базы данных и воссоздания ее на 
другой машине.
msqlimport
Эта команда читает форматированный файл данных и добавляет их в указанную 
таблицу базы данных. Файл может иметь различный формат, в том числе с 
разделителем-запятой и кавычками.
relshow
Эта утилита выводит структуру базы данных и находящихся в ней таблиц. Она 
полезна, если вам нужно узнать, какие таблицы есть в базе данных или какие 
колонки существуют в нужной таблице.
msqlexport
Эта утилита выводит содержимое таблицы на стандартное устройство вывода в виде 
текстового файла с разделителями. Многие другие СУБД и приложения, такие как 
Microsoft Excel, могут читать этот файл и импортировать из него данные.
Поддержка сторонними разработчиками
Как и для любого популярного в сети Интернет программного продукта, существуют 
многочисленные программы сторонних разработчиков, поддерживающие mSQL. Они 
охватывают диапазон от утилит конвертирования до интерфейсов программирования. 
Как бы вы ни применяли mSQL, вы наверняка будете использовать хотя бы один из 
перечисленных здесь продуктов сторонних разработчиков. Конечно, этот список не 
может претендовать на полноту, поскольку состав имеющихся утилит ежедневно 
меняется. Самые свежие списки утилит
сторонних разработчиков можно получить с веб-серверов Hughes и mSQL PC, о 
которых шла речь ранее в этой главе.
Утилиты преобразования баз данных
dbf2msql
Преобразует файлы DBF в таблицы mSQL. DBF - это формат файлов базы данных dBASE,
 бывшей когда-то ведущей настольной базой данных. Хотя dBASE утратил 
популярность, формат DBF установился как наиболее распространенный для передачи 
данных между различными приложениями баз данных. Все главные настольные 
приложения баз данных могут читать и писать DBF-файлы. Это приложение полезно 
для экспорта/импорта данных в коммерческие настольные базы данных.
mSQLpp
Конвертирует ESQL (Ingres Embedded SQL - встроенный SQL для Ingres) в SQL, 
доступный для mSQL. ESQL встраивается прямо в исходный код программ на С, чтобы 
облегчить доступ к базам данных из С. Эта программа конвертирует файл исходного 
кода С с ESQL в файл исходного кода С, использующий стандартный API mSQL.v Она 
предназначена для работы в качестве препроцессора и обычно позволяет с помощью 
фильтрации использовать ESQL-файлы с mSQL без всякой модификации.
Интерфейсы CGI
РНР
Создает HTML-страницы со специальными тегами, распознаваемыми анализатором РНР. 
РНР содержит интерфейсы к большинству основных баз данных, включая MySQL и mSQL.
 PHP более подробно освещается в главе 12 «РНР и другие средства поддержки HTML,
 управляемого базами данных».
dbadmln
Обеспечивает интерфейс CGI к mSQL. Это программа CGI, позволяющая обращаться к 
любой таблице базы данных mSQL, как если бы она была формой HTML. Можно 
модифицировать данные в таблице и далее осуществлять операции над самой базой 
данных.
Jate
Полный интерфейс CGI к mSQL. Jate имеет много сервисов, все они доступны через 
формы HTML. Можно просматривать и редактировать данные, а также настраивать 
вывод. Jate импортирует данные плоского файла через текстовые поля HTML. Она 
также оптимизирует некоторые данные и поисковые запросы перед отправкой их на 
сервер базы данных.
mSQLCGI
Еще один CGI-интерфейс к таблицам mSQL. Эта программа позволяет просматривать и 
модифицировать таблицы mSQL через WWW с использованием форм HTML. Особенностью 
этого интерфейса является необходимость обработки каждой таблицы, которую вы 
хотите использовать, специальной прилагаемой программой, прежде чем к ней можно 
будет получить доступ через Web.
Клиентские приложения
dbview
Показывает структуру базы данных mSQL. Эта утилита сходна с relshow, но имеет 
некоторые дополнительные возможности. Например, dbview показывает количество 
записей в каждой таблице.
XfSQL
Обеспечивает полный доступ к данным таблиц mSQL в качестве клиента Xforms для X 
Window System. С помощью этого инструмента можно добавлять, удалять и 
просматривать данные таблиц в X Window System.
XmSQL
Обеспечивает полный доступ к данным таблиц mSQL как независимый от библиотеки 
клиент X Window System. Благодаря этому она будет компилироваться на любой 
системе X Window.
mSQLsql
Отображает форматированные таблицы. Используя эту утилиту, можно просматривать 
таблицу mSQL в различных видах, включая настраиваемые рамки и разделители для 
форматированных ASCII-таблиц. Можно также генерировать HTML-таблицы, используя 
заданные пользователем параметры.
mSQLwin-relshow
Аналог утилиты relshow для графического интерфейса Windows.
Интерфейсы программирования
ConNExS
Предоставляет интерфейс между mSQL и электронной таблицей NexS. NexS является 
популярной электронной таблицей с возможностью интерактивной связи с внешним 
источником данных. ConNExS позволяет таблицам mSQL служить источником данных 
для электронных таблиц NexS. Все изменения в электронной таблице будут 
отображены в связанной с ней таблицей mSQL.
mSQLBase
Предоставляет API SQLBase как С-оболочку для программ, работающих с mSQL. 
SQLBase API - это API доступа к базам данных независимого разработчика, 
поддерживающий несколько основных серверов SQL. Эта программа транслирует mSQL 
API в SQLBase API, в результате чего клиенты SQLBase могут работать с mSQL.
mSQLCLI
Инкапсулирует С API для mSQL таким образом, что клиенты ODBC под OS/2 могут 
работать с mSQL. ODBC - распространенный независимый от баз данных API, 
поддерживаемый большинством баз данных под OS/2 и Windows. Эта оболочка 
реализует стандартные средства ODBC, поддерживаемые mSQL, но только для 
операционной системы OS/2. Она содержит минимальный уровень функциональности 
ODBC.
msqldll
Упаковывает С API для mSQL в виде DLL для Windows. С помощью этой DLL можно 
создавать приложения для Windows, используя Visual Basic или другой инструмент 
для программирования в Windows, работающий с DLL.
MsqlJava
Создает оболочку сетевого протокола TCP/IP mSQL для Java API, напоминающую mSQL 
С API. Помогает быстро начать создавать приложения Java разработчикам, которые 
уже знают mSQL С API, но не знакомы со стандартом JDBC API. MsqlJava работает 
только с JDK 1.0.
mSQL-JDBC
Реализует стандарт Java Database Connectivity (JDBC) API поверх сетевого 
протокола TCP/IP mSQL. Этот пакет поддерживает максимальный уровень 
функциональности JDBC, возможный для mSQL в среде JDK 1.1 и JDK 1.2 (Java 2), 
включая стандарт JDBC 2.O. В главе 14 «Java и JDBC» подробно обсуждается 
программирование на Java с использованием этого API, а в главе 22 «Справочник 
по JDBC» представлено полное справочное руководство по JDBC 2.0.
MsqlODBC
Реализует ODBC API для mSQL 1 в Windows. Дэвид Хьюз в настоящее время работает 
над реализацией для mSQL 2.
mSQLPerl
Обеспечивает сценариям Perl доступ к базам данных mSQL. В главе 10 «Perl», 
подробно обсуждается программирование на Perl для MySQL и mSQL, а в главе 21 
«Справочник по Perl», представлено полное справочное руководство по mSQLPerl.
mSQLPython
Обеспечивает сценариям Python доступ к базам данных mSQL. В главе 11 «Python», 
подробно обсуждается программирование на Python для MySQL и mSQL, а в главе 20 
«Справочник по Python», представлено полное справочное руководство по 
mSQLPython.
mSQLRexx
Поддерживает доступ к mSQL из REXX, языка сценариев, наиболее часто 
используемого в OS/2.
mSQLTCL
Позволяет программам на Tel иметь доступ к базам данных mSQL. Поддержка 
включает многие расширения Tcl, в том числе Tcl/Tk и Expect.
mSQLVdb
Обеспечивает доступ к базам данных mSQL через библиотеку базы данных Vdb. Vdb - 
не зависящий от типа базы данных API для С, позволяющий единому клиенту иметь 
доступ к различным серверам баз данных. Клиенты Vdb могут использовать этот API 
для доступа к базам данных mSQL.
zmsql
Обеспечивает объектно-ориентированный доступ к базам данных mSQL для программ 
на C++.
Разное
mod_auth_msql
Осуществляет аутентификацию пользователей сервера Apache. Обычно Apache 
осуществляет контроль доступа с помощью простых текстовых файлов, содержащих 
имена пользователей и зашифрованные пароли. Данный модуль позволяет управлять 
доступом через базу данных mSQL.
mSQLEmacs
Расширяет базовую поддержку режима SQL в Emacs, обеспечивая отступы и выделение 
цветом для mSQL-диалекта SQL.
msqlexpire
Удаляет из таблиц mSQL устаревшие данные. Для использования этой программы 
нужно иметь в таблице mSQL колонку, содержащую возраст данных. Эта программа 
находит в таблице данные старше указанного возраста и удаляет их. Можно 
потребовать, чтобы msqlexpire посылала уведомления по электронной почте после 
каждого удаления.
mSQLSSL
Вводит в mSQL поддержку защищенных сетевых соединений по протоколу SSL. Чтобы 
использовать этот продукт, необходимо скомпилировать mSQL вместе с ним. Будучи 
установленным, полностью защищает ваши сетевые соединения от любопытных глаз.
Sqs
Генерирует уникальные числовые идентификаторы для таблиц базы данных. После 
установки этой программы на сервере как демона, любое число клиентов может 
соединяться с демоном, чтобы создавать, читать или удалять последовательности.
Глава №6.
Диалект SQL, используемый в MySQL и mSQL
Для чтения и записи в базах данных MySQL и mSQL используется структурированный 
язык запросов (SQL). Используя SQL, можно осуществлять поиск, вводить новые 
данные или удалять данные. SQL является просто основополагающим инструментом, 
необходимым для взаимодействия с MySQL и mSQL. Даже если для доступа к базе 
данных вы пользуетесь каким-то приложением или графическим интерфейсом 
пользователя, где-то в глубине это приложение генерирует SQL-команды.
SQL является разновидностью «естественного языка». Иными словами, команда SQL 
должна читаться, по крайней мере на первый взгляд, как. предложение английского 
языка. У такого подхода есть как преимущества, так и недостатки, но факт 
заключается в том, что этот язык очень непохож на традиционные языки 
программирования, такие как С, Java или Perl.
В этой главе мы рассмотрим язык SQL, как он реализован в MySQL и mSQL. По 
большей части, диалект MySQL является надмножеством диалекта mSQL. Мы 
старательно отметим те случаи, где два диалекта расходятся. Однако в основном 
эта глава относится и к одной, и к другой СУБД.
Основы SQL
SQL «структурирован» в том отношении, что он следует определенному набору 
правил. Компьютерной программе легко разобрать на части сформулированный запрос 
SQL. Действительно, в книге издательства O'Reilly «lex & у асе», написанной 
Джоном Ливайном, Тони Мэйсоном и Дугом Брауном (John Levine, Tony Mason, Doug 
Brown), реализована грамматика SQL для демонстрации процесса создания программы,
 интерпретирующей язык! Запрос (query) - это полностью заданная команда, 
посылаемая серверу баз данных, который выполняет запрошенное действие. Ниже 
приведен пример SQL-запроса:
SELECT name FROM people WHERE name LIKE 'Stac%'
Как можно видеть, это предложение выглядит почти как фраза на ломаном 
английском языке: «Выбрать имена из список люди, где имена похожи на Stac». SQL 
в очень незначительной мере использует форматирование и специальные символы, 
обычно ассоциируемые с компьютерными языками. Сравните, к примеру, 
«$++;($*++/$|);$&$л„;$!» в Perl и «SELECT value FROM table» в SQL.
История SQL
В IBM изобрели SQL в начале 1970-х, вскоре после введения д-ром Е. Ф. Коддом (Е.
 F. Codd) понятия реляционной базы данных. С самого начала SQL был легким в 
изучении, но мощным языком. Он напоминает естественный язык, такой как 
английский, и поэтому не утомляет тех, кто не является техническим специалистом.
 В 1970-х это достоинство было еще более важным, чем сегодня.
В начале 1970-х не было случайных хакеров. Дети росли, не изучая BASIC и не 
создавая собственных веб-страничек. Люди, программировавшие компьютеры, знали 
все о том, как эти компьютеры работают. SQL был предназначен для армии 
несведущих в технике бухгалтеров, а также делового и управленческого персонала, 
которым принес бы пользу доступ к мощи реляционной базы данных.
SQL действительно был настолько популярен среди пользователей, для которых 
предназначался, что в 1980-х компания Oracle выпустила первую в мире 
общедоступную коммерческую SQL-систему. Oracle SQL был хитом сезона и породил 
вокруг SQL целую индустрию. Sybase, Informix, Microsoft и ряд других компаний 
вышли на рынок с собственными разработками реляционных систем управления базами 
данных (РСУБД), основанных на SQL.
В то время когда Oracle и ее конкуренты вышли на сцену, SQL был новинкой, и для 
него не существовало стандартов. Лишь в 1989 году комиссия по стандартам ANSI 
выпустила первый общедоступный стандарт SQL. Сегодня его называют SQL89. К 
несчастью, этот новый стандарт не слишком углублялся в определение технической 
структуры языка. Поэтому, хотя различные коммерческие реализации языка SQL 
сближались, различия в синтаксисе делали задачу перехода с одной реализации 
языка на другую нетривиальной. Только в 1992 году стандарт ANSI SQL вступил в 
свои права.
Произносится как «сиквел» или «эс-кю-эль». Некоторые люди относятся с 
благоговением к произношению SQL. He обращайте на них внимания. Однако нужно 
заметить, что в MySQL и mSQL правильное произношение -«эс-кю-эль».
Стандарт 1992 года обозначают как SQL92 или SQL2. Стандарт SQL2 включил в себя 
максимально возможное количество расширений, добавленных в коммерческих 
реализациях языка. Большинство инструментов, работающих с различными базами 
данных, основывается на SQL2 как на способе взаимодействия с реляционными 
базами данных. Однако, из-за очень большой широты стандарта SQL2, реляционные 
базы, реализующие полный стандарт, очень сложные и ресурсоемкие.
SQL2 - не последнее слово в стандартах SQL. В связи с ростом популярности 
объектно-ориентированных СУБД (ООСУБД) и объектно-реляционных СУБД (ОРСУБД) 
возрастает давление с целью принятия объектно-ориентированного доступа к базам 
данных в качестве стандарта SQL. Ответом на эту проблему должен послужить SQL3. 
Он не является пока официальным стандартом, но в настоящее время вполне 
определился и может стать официальным стандартом где-то в 1999 году.
С появлением MySQL и mSQL проявился новый подход к разработке серверов баз 
данных. Вместо создания очередной гигантской РСУБД с риском не предложить 
ничего нового в сравнении с «большими парнями», были предложены небольшие и 
быстрые реализации наиболее часто используемых функций SQL.
Архитектура SQL
Как мы уже отмечали, SQL больше напоминает естественный человеческий, а не 
компьютерный язык. SQL добивается этого сходства благодаря простой четкой 
императивной структуре. Во многом походя на предложение английского языка, 
отдельные команды SQL, называемые запросами, могут быть разбиты на части речи. 
Рассмотрим следующие примеры.
CREATE TABLE people (name CHAR(10)) 
глагол дополнение расширенное определение
INSERT INTO people VALUES('me') 
глагол косвенное прямое
дополнение дополнение
SELECT name FROM people WHERE name LIKE '%e'
глагол прямое косвенное придаточное дополнение дополнение предложение
Большинство реализаций SQL, включая MySQL и mSQL, нечувствительны к регистру: 
неважно, в каком регистре вы вводите ключевые слова SQL, если орфография верна. 
Например, CREATE из верхнего примера можно записать и так:
cREatE ТАblЕ people (name cHaR(10))
Нечувствительность к регистру относится только к ключевым словам SQL. Ради 
удобочитаемости все ключевые слова SQL в этой книге записаны заглавными буквами.
 Мы рекомендуем такой стиль как хороший, «опробованный на практике» способ. В 
MySQL и mSQL имена баз данных, таблиц и колонок к регистру чувствительны. Но 
это характерно не для всех СУБД. Поэтому, если вы пишете приложение, которое 
должно работать с любыми СУБД, не следует использовать имена, различающиеся 
одним только регистром.
Первый элемент SQL-запроса - всегда глагол. Глагол выражает действие, которое 
должно выполнить ядро базы данных. Хотя остальная часть команды зависит от 
глагола, она всегда следует общему формату: указывается имя объекта, над 
которым осуществляется действие, а затем описываются используемые при действии 
данные. Например, в запросе CREATE TABLE people (char(10)) используется глагол 
CREATE, за которым следует дополнение (объект) TABLE .Оставшаяся часть запроса 
описывает таблицу, которую нужно создать.
SQL-запрос исходит от клиента - приложения, предоставляющего фасад, с помощью 
которого пользователь взаимодействует с базой данных. Клиент составляет запрос, 
основываясь на действиях пользователя, и посылает его серверу SQL. После этого 
сервер должен обработать запрос и выполнить указанные действия. Сделав свою 
работу, сервер возвращает клиенту одно или несколько значений.
Поскольку основная задача SQL - сообщить серверу баз данных о том, какие 
действия необходимо выполнить, он не обладает гибкостью языка общего назначения.
 Большинство функций SQL связано с вводом и выводом из базы: добавление, 
изменение, удаление и чтение данных. SQL предоставляет и другие возможности, но 
всегда с оглядкой на то, как они могут использоваться для манипулирования 
данными в базе.
Создание и удаление таблиц
Успешно установив MySQL или mSQL, вы можете приступить к созданию своей первой 
таблицы. Таблица, структурированное вместилище данных, является основным 
понятием реляционных баз. Прежде чем начать вводить данные в таблицу, вы должны 
определить ее структуру. Рассмотрим следующую раскладку:

каждого поля, а также возможные дополнительные сведения о полях. Тип данных 
поля определяет, какого рода данные могут в нем содержаться. Типы данных SQL 
сходны с типами данных в других языках программирования. Полный стандарт SQL 
допускает большое разнообразие типов данных. MySQL реализует большую их часть, 
в то время как mSQL -лишь несколько наиболее полезных.
Общий синтаксис для создания таблиц следующий:
CREATE TABLE table_name (colutnn_namel type [modifiers] [, column_name2 type 
[modifiers]] )
Какие идентификаторы - имена таблиц и колонок - являются допустимыми, зависит 
от конкретной СУБД. mSQL обеспечивает поддержку имен в объеме, близком к 
минимальному. В качестве идентификатора он допускает любую последовательность 
букв набора ISO 8859-1 (Latin 1), цифр и знака «-», длиной до 20 символов. 
Идентификатор должен начинаться с буквы. Проблемы вызывает ограничение на 
использование только ISO 8859-1. Для хорошей переносимости SQL нужно избегать 
имен, начинающихся не с допустимой буквы. MySQL предоставляет больше 
возможностей. Длина идентификатора может быть до 64 символов, допустим символ 
«$», и первым символом может быть цифра. Более важно, однако, что MySQL 
допускает использование любых символов из установленного в системе локального 
набора.
Колонка - это отдельная единица данных в таблице. В таблице может содержаться 
произвольное число колонок, но использование больших таблиц бывает 
неэффективным. Вот здесь правильное проектирование базы данных, обсуждавшееся в 
главе 2, начинает играть важную роль. Создав правильно нормализованные таблицы, 
можно объединять их («join») для осуществления поиска в данных, размещенных в 
нескольких таблицах. Механику объединения таблиц мы обсудим позднее в данной 
главе.
Как и бывает в жизни, разрушить легче, чем создать. Следующая команда удаляет 
таблицу:
DROP TABLE Lable_name
Эта команда не оставит и следа от таблицы в базе данных. MySQL уничтожит все 
данные удаленной таблицы. Если у вас не осталось резервной копии, нет абсолютно 
никакого способа отменить действие данной операции. Мораль этой истории: всегда 
храните резервные копии и будьте очень внимательны при удалении таблиц. В один 
«прекрасный» день это вам пригодится.
В MySQL можно одной командой удалить несколько таблиц, разделяя их имена 
запятыми. Например, DROP TABLE people, animals, plants удалит эти три таблицы. 
Можно также использовать модификатор IF EXISTS для подавления ошибки в случае 
отсутствия удаляемой таблицы. Этот модификатор полезен в больших сценариях, 
предназначенных для создания базы данных и всех ее таблиц. Прежде чем создавать 
таблицу, выполните команду DROP TABLE table_name IF EXISTS.
Типы данных в SQL
Каждая колонка таблицы имеет тип. Как уже указывалось, типы данных SQL сходны с 
типами данных традиционных языков программирования. В то время как во многих 
языках определен самый минимум типов, необходимых для работы, в SQL для 
удобства пользователей определены дополнительные типы, такие как MONEY и DATE. 
Данные типа MONEY можно было бы хранить и как один из основных числовых типов 
данных, однако использование типа, специально учитывающего особенности денежных 
расчетов, повышает легкость использования SQL, которая является одной из 
главных его целей.
В главе 15 «Справочник по SQL» дается полное справочное руководство по типам 
SQL, поддерживаемым MySQL и mSQL. В таблице 6-1 дан сокращенный список, 
состоящий из наиболее употребительных типов, поддерживаемых в обоих языках.
Таблица 6-1. Наиболее употребительные типы, данных, поддерживаемые как MySQL, 
так и mSQL
Тип данныхОписаниеINTЦелое число. В MySQL INT может быть со знаком или без 
знака, в то время как mSQL имеет отдельный тип UINT для беззнаковых целых.REAL
Число с плавающей запятой. Этот тип допускает больший диапазон значений, чем 
INT, но не обладает его точностью.TEXT(length)Символьная величина переменной 
длины. В mSQL значение length используется как предположение о том, какой длины 
будут хранимые строки. Можно сохранять и строки большей длины, но ценой потери 
производительности. В MySQL TEXT - лишь один из нескольких типов данных 
переменного размера.DATEСтандартное значение даты. Хотя формат хранения даты 
различен в MySQL и mSQL, оба ядра могут использовать тип DATE для хранения 
произвольных дат, относящихся к прошлому, настоящему и будущему. Оба ядра 
правильно решают «проблему 2000».TIMEСтандартное значение времени. Этот тип 
используется для хранения времени дня безотносительно какой-либо даты. При 
использовании вместе с датой позволяет хранить конкретную дату и время. В MySQL 
есть дополнительный тип DATETIME для совместного хранения даты и времени в 
одном поле.CHAR(length)Символьная величина фиксированной длины. Поля типа CHAR 
не могут содержать строки длины большей, чем указанное значение. Поля меньшей 
длины дополняются пробелами. Вероятно, это наиболее употребительный тип в любой 
реализации SQL.  
«MySQL поддерживает атрибут UNSIGNED для всех числовых типов. Этот модификатор 
позволяет вводить в колонку только положительные (беззнаковые) числа. 
Беззнаковые поля имеют верхний предел значений вдвое больший, чем у 
соответствующих знаковых типов. Беззнаковый TINYINT - однобайтовый числовой тип 
MySQL - имеет диапазон от 0 до 255, а не от -127 до 127, как у своего знакового 
аналога.
Та и другая СУБД имеют больше типов, чем перечислено выше. Особенно большое 
число типов поддерживает MySQL. Однако на практике в основном используются 
перечисленные типы. В mSQL выбор типа данных сводится к выбору типа, наиболее 
близкого к данным, которые вы собираетесь хранить. Размер данных, которые вы 
собираетесь хранить, играет гораздо большую роль при разработке таблиц MySQL.
Числовые типы данных
Прежде чем создавать таблицу, вы должны хорошо представить себе, какого рода 
данные вы будете в ней хранить. Помимо очевидного решения о том, будут это 
числовые или символьные данные, следует выяснить примерный размер хранимых 
данных. Если это числовое поле, то каким окажется максимальное значение? Может 
ли оно измениться в будущем? Если минимальное значение всегда положительно, 
следует рассмотреть использование беззнакового типа. Всегда следует выбирать 
самый маленький числовой тип, способный хранить самое большое мыслимое значение.
 Если бы, к примеру, требовалось хранить в поле численность населения штата, 
следовало бы выбрать беззнаковый INT. Ни в каком штате не может быть 
отрицательной численности населения, и для того, чтобы беззнаковое поле типа 
INT не могло вместить число, представляющее его население, численность 
населения этого штата должна примерно равняться численности населения всей 
Земли.
Символьные типы
С символьными типами работать немного труднее. Вы должны подумать не только о 
максимальной и минимальной длине строки, но также о среднем размере, частоте 
отклонения от него и необходимости в индексировании. В данном контексте мы 
называем индексом поле или группу полей, в которых вы собираетесь осуществлять 
поиск — в основном, в предложении WHERE. Индексирование, однако, значительно 
сложнее, чем такое упрощенное определение, и мы займемся им далее в этой главе. 
Здесь важно лишь отметить, что индексирование по символьным полям происходит 
значительно быстрее, если они имеют фиксированную длину. В действительности, 
mSQL даже не позволяет индексировать поля переменной длины. Если длина строк не 
слишком колеблется или, что еще лучше, постоянна, то, вероятно, лучше выбрать 
для поля тип CHAR. Пример хорошего кандидата на тип CHAR — код страны. 
Стандартом ISO определены двухсимвольные коды для всех стран (US для США, FR 
для Франции и т. д.). Поскольку эти коды состоят ровно из двух символов, 
CHAR(2) будет правильным выбором для данного поля.
Чтобы подходить для типа CHAR, поле необязательно должно быть фиксированной 
длины, но длина не должна сильно колебаться. Телефонные номера, к примеру, 
можно смело хранить в поле CHAR(13), хотя длина номеров различна в разных 
странах. Просто различие не столь велико, поэтому нет смысла делать поле для 
номера телефона переменным по длине. В отношении поля типа CHAR важно помнить, 
что, вне зависимости от реальной длины хранимой строки, в поле будет ровно 
столько символов, сколько указано в его размере — не больше и не меньше. 
Разность в длине между размером сохраняемого текста и размером поля заполняется 
пробелами. Не стоит беспокоиться по поводу нескольких лишних символов при 
хранении телефонных номеров, но не хотелось бы тратить много места в некоторых 
других случаях. Для этого существуют текстовые поля переменной длины.
Хороший пример поля, для которого требуется тип данных с переменной длиной, 
дает URL Интернет. По большей части адреса Web занимают сравнительно немного 
места - http://www.ora.com, http:// www.hughes.com.au, http://www.mysql.com - и 
не представляют проблемы. Иногда, однако, можно наткнуться на адреса подобного 
вида: http://www.winespectator.com/Wine/Spectator/ 
_notes\5527293926834323221480431354? Xvl I =&Xr5=&Xvl =& type-region-search- 
code=&Xal 4=flora+springs&Xv4=.
Если создать поле типа CHAR длины, достаточной для хранения этого URL, то почти 
для каждого другого хранимого URL будет напрасно тратиться весьма значительное 
пространство. Поля переменной длины позволяют задать такую длину, что 
оказывается возможным хранение необычно длинных значений, и в то же время не 
расходуется напрасно место при хранении обычных коротких величин. В MySQL и 
mSQL подход к этой проблеме различный.
Поля переменной длины в MySQL
Если вы используете только mSQL, этот раздел можно пропустить. Преимуществом 
текстовых полей переменной длины в MySQL является то, что они используют ровно 
столько места, сколько необходимо для хранения отдельной величины. Например, 
поле типа VARCHAR(255) , в котором хранится строка «hello, world», занимает 
только двенадцать байтов (по одному байту на каждый символ плюс еще один байт 
для хранения длины).
В отличие от стандарта ANSI, в MySQL поля типа VARCHAR не дополняются пробелами.
 Перед записью из строки удаляются лишние пробелы.
Сохранить строки, длина которых больше, чем заданный размер поля, нельзя. В 
поле VARCHAR(4) можно сохранить строку не длиннее 4 символов. Если вы 
попытаетесь сохранить строку «happy birthday», MySQL сократит ее до «happ». 
Недостатком подхода MySQL к хранению полей переменной длины, в сравнении с mSQL,
 является то, что не существует способа сохранить необычную строку, длина 
которой превосходит заданное вами значение. В таблице 6-2 показан размер 
пространства, необходимого для хранения 144-символьного URL, 
продемонстрированного выше, и обычного, 30-символьного URL,
Таблица 6-2. Пространство памяти, необходимое для различных символьных типов 
MySQL
Тип данныхПространство для хранения строки из 144 символовПространство для 
хранения строки из 30 символовМаксимальная длина строкиСНАR(150)150150255
VARCHAR(ISO)14531255TINYTEXT(ISO)14531255ТЕХТ(150)1463265535MEDIUM-ТЕХТ(150)147
3316777215LONGTEXT(150)148344294967295Если через годы работы со своей базой 
данных вы обнаружите, что мир изменился, и поле, уютно чувствовавшее себя в 
типе VARCHAR(25) , должно теперь вмещать строки длиной 30 символов, не все 
потеряно. В MySQL есть команда ALTER TABLE , позволяющая переопределить размер 
поля без потери данных.
ALTER TABLE mytable MODIFY tnycolumn LONGTEXT
Поля переменной длины в mSQL
Если вас интересует только MySQL, этот раздел можно пропустить. Символьные поля 
переменной длины в mSQL позволяют задать длину как средний размер строки, 
которая будет в нем храниться. Каждая величина, вводимая в это поле, займет, по 
крайней мере, столько места, сколько вами задано, но поле может хранить и более 
длинные строки. Для этого база данных создает таблицу переполнения, в которой 
хранит лишние данные. Недостаток такого подхода проявляется в снижении 
производительности и невозможности индексировать поля переменной длины.
Остановимся немного на последствиях различий в подходе. Чтобы сохранить все 
вышеперечисленные URL в поле типа CHAR, потребуется колонка типа CHAR(144). При 
таком развитии событий четыре упомянутые URL займут 576 байт (144 х 4), хотя 
фактически хранится только 216 байт данных. Остальные 360 байт- просто 
потерянное пространство. Если помножить эту цифру на тысячи и миллионы строк, 
то можно понять, что это представляет собой серьезную проблему. Если же 
использовать поле переменной длины типа ТЕХТ(30), то для хранения 216 байт 
данных требуется только 234 байта (30 X 3 + 144). Всего лишь 18 байт потеряно. 
Экономия составила 41%!
Двоичные типы данных
В mSQL нет поддержки двоичных данных. В MySQL, напротив, есть целый ряд 
двоичных типов данных, соответствующих своим символьным аналогам. Двоичными 
типами, поддерживаемыми MySQL, являются CHAR BINARY , VARCHAR BINARY , TINYBLOB,
 BLOB, MEDIUMBLOB и LONGBLOB. Практическое отличие между символьными типами и 
их двоичными аналогами основано на принципе кодировки. Двоичные данные просто 
являются куском данных, которые MySQL не пытается интерпретировать. Напротив, 
символьные данные предполагаются представляющими текстовые данные из 
используемых человеком алфавитов. Поэтому они кодируются и сортируются, 
основываясь на правилах, соответствующих рассматриваемому набору символов. 
Двоичные же данные MySQL сортирует в порядке ASCII без учета регистра.
Перечисления и множества
MySQL предоставляет еще два особых типа данных, не имеющих аналога в mSQL. Тип 
ENUM позволяет при создании таблицы указать список возможных значений 
некоторого поля. Например, если бы у вас была колонка с именем «фрукт», в 
которую вы разрешили бы помещать только значения «яблоко», «апельсин», «киви» и 
«банан», ей следовало бы присвоить тип ENUM:
CREATE TABLE meal(meal_id INT NOT NULL PRIMARY KEY,
фрукт ENUM('яблоко', 'апельсин', 'киви', 'банан'))
При записи значения в эту колонку оно должно быть одним из перечисленных 
фруктов. Поскольку MySQL заранее знает, какие значения допустимы для этой 
колонки, она может абстрагировать их каким-либо числовым типом. Иными словами, 
вместо того, чтобы хранить в колонке «яблоко» в виде строки, MySQL заменяет его 
однобайтовым числом, а «яблоко» вы видите, когда обращаетесь к таблице или 
выводите из нее результаты.
Тип MySQL SET работает аналогично, но позволяет одновременно хранить в поле 
несколько значений.
Другие типы данных
Любые мыслимые данные можно хранить с помощью числовых или символьных типов. В 
принципе, даже числа можно хранить в символьном виде. Однако то, что это можно 
сделать, не означает, что это нужно делать. Рассмотрим, к примеру, как хранить 
в базе данных денежные суммы. Можно делать это, используя INT или REAL. Хотя 
интуитивно REAL может показаться более подходящим - в конце концов, в денежных 
суммах нужны десятичные знаки, - на самом деле более правильно использовать INT.
 В полях, содержащих значения с плавающей запятой, таких как REAL, часто 
невозможно найти число с точным десятичным значением. Например, если вы вводите 
число 0.43, которое должно представлять сумму $0.43, MySQL и mSQL могут 
записать его как 0.42999998. Это небольшое отличие может вызвать проблемы при 
совершении большого числа математических операций. Сохраняя число как INT и 
устанавливая десятичную точку в нужное место, можно быть уверенным, что его 
значение представляет именно то, что вам требуется.
К чему такие хлопоты? Не лучше ли было бы, если бы MySQL и mSQL обеспечивали 
некий тип данных, специально предназначенный для денежных сумм? MySQL и в 
меньшей степени mSQL предоставляют специальные типы данных для таких случаев. 
Одним из них является тип MONEY, другим- DATE. Полное описание всех типов 
данных можно найти в главе 17 «Программы и утилиты для MySQL и mSQL».
Индексы
Хотя MySQL и mSQL обеспечивают более высокую производительность, чем любые 
большие серверы баз данных, некоторые задачи все же требуют осторожности при 
проектировании базы данных. Например, если таблица содержит миллионы строк, 
поиск нужной строки в ней наверняка потребует длительного времени. Как 
указывалось в главе 2, в большинстве баз данных поиск облегчается благодаря 
средству, называемому индексом.
Индексы способствуют хранению данных в базе таким образом, который позволяет 
осуществлять быстрый поиск. К несчастью, ради скорости поиска приходится 
жертвовать дисковым пространством и скоростью изменения данных. Наиболее 
эффективно создавать индексы для тех колонок, в которых вы чаще всего 
собираетесь осуществлять поиск. MySQL и mSQL поддерживают одинаковый синтаксис 
для создания индексов:
CREATE INDEX index_name ON tablename (column1,
column2,
columnN)
MySQL позволяет также создавать индекс одновременно с созданием таблицы, 
используя следующий синтаксис:
CREATE TABLE materials (id INT NOT NULL,
name CHAR(50) NOT NULL,
resistance INT, 
melting_pt REAL,
INDEX indexl (id, name), 
UNIQUE INDEX index2 (name))
В этом примере для таблицы создается два индекса. Первый индекс indexl состоит 
из полей id и name. Второй индекс включает в себя только поле name и указывает, 
что значения поля name должны быть уникальными. Если вы попытаетесь вставить в 
поле name значение, которое уже есть в этом поле в какой-либо строке, операция 
не будет осуществлена. Все поля, указанные в уникальном индексе, должны быть 
объявлены как NOT NULL .
Хотя мы создали отдельный индекс для поля name, отдельно для поля id мы не 
создавали индекса. Если такой индекс нам понадобится, создавать его не нужно - 
он уже есть. Когда индекс содержит более одной колонки (например, name, rank, 
nserial_number), MySQL читает колонки в порядке слева направо. Благодаря 
используемой MySQL структуре индекса всякое подмножество колонок с левого края 
автоматически становится индексом внутри «главного» индекса. Например, когда вы 
создаете индекс name, rank, serial_number, создаются также «свободные» индексы 
name и name вместе с rank. Однако индексы rank или name и seri-al_number не 
создаются, если не потребовать этого явно.
MySQL поддерживает также семантику ANSI SQL для особого индекса, называемого 
первичным ключом. В MySQL первичный ключ - это уникальный индекс с именем 
PRIMARY. Назначив при создании таблицы колонку первичным ключом, вы делаете ее 
уникальным индексом, который будет поддерживать объединения таблиц. В следующем 
примере создается таблица cities с первичным ключом id.
CREATE TABLE cities (id INT NOT NULL PRIMARY KEY,
name VARCHAR(100),
pop MEDIUMINT,
founded DATE)
Прежде чем создавать таблицу, нужно решить, какие поля будут ключами (и будут 
ли вообще ключи). Как уже говорилось, любые поля, которые будут участвовать в 
объединении таблиц, являются хорошими кандидатами на роль первичного ключа. 
Подробно обсуждение того, как проектировать таблицы с хорошими первичными 
ключами, можно найти в главе 2.
Последовательности и автоинкрементирование
Лучше всего, когда первичный ключ не имеет в таблице никакого иного значения, 
кроме значения первичного ключа. Для достижения этого лучшим способом является 
создание числового первичного ключа, значение которого увеличивается при 
добавлении в таблицу новой строки. Если вернуться к примеру с таблицей cities, 
то первый введенный вами город должен иметь id, равный 1, второй - 2, третий - 
3, и т. д. Чтобы успешно управлять такой последовательностью первичных ключей, 
нужно иметь какое-то средство, гарантирующее, что в данный конкретный момент 
только один клиент может прочесть число и увеличить его на единицу. В базе 
данных с транзакциями можно создать таблицу, скажем, с именем sequence , 
содержащую число, представляющее очередной id. Когда необходимо добавить новую 
строку в таблицу, вы читаете число из этой таблицы и вставляете число на 
единицу большее. Чтобы эта схема работала, нужно быть уверенным, что никто 
другой не сможет произвести чтение из таблицы, пока вы не ввели новое число. В 
противном случае два клиента могут прочесть одно и то же значение и попытаться 
использовать его в качестве значения первичного ключа в одной и той же таблице.
Ни MySQL, ни mSQL не поддерживают транзакции, поэтому описанный механизм нельзя 
использовать для генерации уникальных чисел. Использовать для этих целей 
команду MySQL LOCK TABLE обременительно. Тем не менее обе СУБД предоставляют 
свои варианты понятия последовательности, позволяющие генерировать уникальные 
идентификаторы, не беспокоясь о транзакциях.
Последовательности в MySQL
При создании таблицы в MySQL можно одну из колонок специфицировать как 
AUTO_INCREMENT . В этом случае, при добавлении новой строки, имеющей значение 
NULL или 0 в данной колонке, автоматически будет происходить замена на значение 
на единицу больше, чем наибольшее текущее значение в колонке. Колонка с 
модификатором AUTO_INCREMENT должна быть индексирована. Ниже приведен пример 
использования поля типа AUTOJNCREMENT :
CREATE TABLE cities (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
pop MEDIUMINT,
founded DATE)
Когда вы первый раз добавляете строку, поле id получает значение 1, если в 
команде INSERT для него используется значение NULL или 0. Например, следующая 
команда использует возможность AUTO_INCREMENT:
INSERT INTO cities (id, name, pop)
VALUES (NULL, 'Houston', 3000000)
Если вы выполните эту команду, когда в таблице нет строк, поле id получит 
значение 1, а не NULL. В случае, когда в таблице уже есть строки, полю будет 
присвоено значение на 1 большее, чем наибольшее значение id в данный момент.
Другим способом реализации последовательностей является использование значения, 
возвращаемого функцией LAST_INSERT_ID :
UPDATE table SET id=LAST_INSERT_ID (id+1);
Последовательности в mSQL
Каждая таблица в mSQL может иметь одну связанную с ней последовательность. 
Синтаксис создания последовательности следующий:
CREATE SEQUENCE ON table_name [VALUE start STEP incr]
Начальное значение задается числом start, а шаг увеличения при каждом 
последующем обращении - числом incr. По умолчанию, последовательность 
начинается с 1 и каждый раз возрастает на 1. Например:
CREATE SEQUENCE ON mytable VALUE 100 STEP 5
Создается последовательность в таблице mytable, начальным значением которой 
будет 100, а при каждом обращении оно будет увеличиваться на 5. Вторым 
значением, следовательно, будет 105.
Для доступа к последовательности нужно выбрать из таблицы специальную колонку с 
именем _seq:
SELECT _seq FROM table_name
В результате вы получите очередное значение последовательности и 
инкрементируете его.
Управление данными
Первое, что вы делаете, создав таблицу, это начинаете добавлять в нее данные. 
Если данные уже есть, может возникнуть необходимость изменить или удалить их.
Добавление данных
Добавление данных в таблицу является одной из наиболее простых операций SQL. 
Несколько примеров этого вы уже видели. Как MySQL, так и mSQL поддерживают 
стандартный синтаксис INSERT:
INSERT INTO table_name (columnl, column2, ..., columnN)
VALUES (value!, value2, .... valueN)
Данные для числовых полей вводятся как они есть. Для всех других полей вводимые 
данные заключаются в одиночные кавычки. Например, для ввода данных в таблицу 
адресов можно выполнить следующую команду:
INSERT INTO addresses (name, address, city, state, phone, age)
VALUES( 'Irving Forbush', ' 123 Mockingbird Lane', 'Corbin', 'KY', '(800) 
555-1234', 26)
Кроме того, управляющий символ - по умолчанию '\' — позволяет вводить в 
литералы одиночные кавычки и сам символ '\':
# Ввести данные в каталог Stacie's Directory, который находится
# в c:\Personal\Stacie
INSERT INTO files (description, location)
VALUES ('Stacie\'s Directory', 'C: \\Personal\\Stacie')
MySQL позволяет опустить названия колонок, если значения задаются для всех 
колонок и в том порядке, в котором они были указаны при создании таблицы 
командой CREATE. Однако если вы хотите использовать значения по умолчанию, 
нужно задать имена тех колонок, в которые вы вводите значения, отличные от 
установленных по умолчанию. Если для колонки не установлено значение по 
умолчанию и она определена как NOT NULL , необходимо включить эту колонку в 
команду INSERT со значением, отличным от NULL. В mSQL значение по умолчанию 
всегда NULL. MySQL позволяет указать значение по умолчанию при создании таблицы 
в команде CREATE.
Более новые версии MySQL поддерживают нестандартный вызов INSERT для 
одновременной вставки сразу нескольких строк:
INSERT INTO foods VALUES (NULL, 'Oranges', 133, 0, 2, 39),
(HULL, 'Bananas', 122, 0, 4, 29), (NULL, 'Liver', 232, 3, 15, 10)
Хотя поддерживаемый MySQL нестандартный синтаксис удобно использовать для 
быстрого выполнения задач администрирования, не следует без крайней нужды 
пользоваться им при написании приложений. Как правило, следует придерживаться 
стандарта ANSI SQL2 настолько близко, насколько MySQL и mSQL это позволяют. 
Благодаря этому вы получаете возможность перейти в будущем на какую-нибудь 
другую базу данных. Переносимость особенно важна для тех, у кого потребности 
среднего масштаба, поскольку такие пользователи обычно предполагают 
когда-нибудь перейти на полномасштабную базу данных.
MySQL поддерживает синтаксис SQL2, позволяющий вводить в таблицу результаты 
запроса SELECT:
INSERT INTO foods (name, fat)
SELECT food_name, fat_grams FROM recipes
Обратите внимание, что число колонок в INSERT соответствует числу колонок в 
SELECT. Кроме того, типы данных колонок в INSERT должны совпадать с типами 
данных в соответствующих колонках SELECT. И, наконец, предложение SELECT внутри 
команды INSERT не должно содержать модификатора ORDER BY и не может производить 
выборку-из той же таблицы, в которую вставляются данные командой INSERT.
Изменение данных
Добавление новых строк в базу данных - лишь начало ее использования. Если ваша 
база не является базой данных «только для чтения», вам, вероятно, понадобится 
периодически изменять данные. Стандартная команда SQL для изменения данных 
выглядит так:
UPDATE table_name
SET column1=value1, column2=value2, ..., columnN=valueN
[WHERE clause]
В mSQL значение, присваиваемое колонке, должно быть литералом и иметь тот же 
тип, что и колонка. MySQL, напротив, позволяет вычислять присваиваемое значение.
 Можно даже вычислять значение, используя значение другой колонки:
UPDATE years
SET end_year - begin_year+5
В этой команде значение колонки end_year устанавливается равным значению 
колонки begin_year плюс 5 для каждой строки таблицы.
Предложение WHERE
Возможно, вы уже обратили внимание на предложение WHERE. В SQL предложение 
WHERE позволяет отобрать строки таблицы с заданным значением в указанной 
колонке, например:
UPDATE bands
SET lead_singer = 'Ian Anderson'
WHERE band_name = 'Jethro Tull'
Эта команда — UPDATE - указывает, что нужно изменить значение в колонке 
lead_singer для тех строк, в которых band_name совпадает с «Jethro Tull.» Если 
рассматриваемая колонка не является уникальным индексом, предложение WHERE 
может соответствовать нескольким строкам. Многие команды SQL используют 
предложение WHERE, чтобы отобрать строки, над которыми нужно совершить операции.
 Поскольку по колонкам, участвующим в предложении WHERE, осуществляется поиск, 
следует иметь индексы по тем их комбинациям, которые обычно используются.
Удаление
Удаление данных - очень простая операция. Вы просто указываете таблицу, из 
которой нужно удалить строки, и в предложении WHERE задаете строки, которые 
хотите удалить:
DELETE FROM table_name [WHERE clause]
Как и в других командах, допускающих использование предложения WHERE, его 
использование является необязательным. Если предложение WHERE опущено, то из 
таблицы будут удалены все записи! Из всех удаляющих данные команд SQL эта легче 
всего может привести к ошибке.
Запросы
Самая часто используемая команда SQL - та, которая позволяет просматривать 
данные в базе: SELECT. Ввод и изменение данных производятся лишь от случая к 
случаю, и большинство баз данных в основном занято тем, что предоставляет 
данные для чтения. Общий вид команды SELECT следующий:
SELECT column1, column2, ..., columnN
FROM table1, table2, .... tableN
[WHERE clause]
Этот синтаксис, несомненно, чаще всего используется для извлечения данных из 
базы, поддерживающей SQL. Конечно, существуют разные варианты для выполнения 
сложных и мощных запросов, особенно в MySQL. Мы полностью осветим синтаксис 
SELECT в главе 15.
В первой части команды SELECT перечисляются колонки, которые вы хотите извлечь. 
Можно задать «*», чтобы указать, что вы хотите извлечь все колонки. В 
предложении FROM указываются таблицы, в которых находятся эти колонки. 
Предложение WHERE указывает, какие именно строки должны использоваться, и 
позволяет определить, каким образом должны объединяться две таблицы.
Объединения
Объединения вносят «реляционность» в реляционные базы данных. Именно 
объединение позволяет сопоставить строке одной таблицы строку другой. Основным 
видом объединения является то, что иногда называют внутренним объединением. 
Объединение таблиц заключается в приравнивании колонок двух таблиц:
SELECT book, title, author, name
FROM author, book
WHERE book, author = author, id
Рассмотрим базу данных, в которой таблица book имеет вид, как в таблице 6-3.
Таблица 6-3. Таблица книг
IDTitleAuthorPages1The Green Mile48942Guards, Guards!2302
IDTitleAuthorPages3Imzadi33544Gold14055Howling Mad3294А таблица авторов author 
имеет вид таблицы 6-4. 
Таблица 6-4. Таблица авторов
IDNameCitizen1Isaac AsimovUS2Terry PratchetUK3Peter Davidus4Stephen Kingus5Neil 
GaimanUKВ результате внутреннего объединения создается таблица, в которой 
объединяются поля обеих таблиц для строк, удовлетворяющих запросу в обеих 
таблицах. В нашем примере запрос указывает, что поле author в таблице book 
должно совпадать с полем id таблицы author. Результат выполнения этого запроса 
представлен в таблице 6-5.
Таблица 6-5. Результаты запроса с внутренним объединением
Book TitleAuthor NameThe Green MileStephen KingGuards, Guards!Terry Pratchet
ImzadiPeter DavidGoldIsaac AsimovHowling MadPeter DavidВ этих результатах нет 
автора с именем Neil Gaiman, поскольку его author, id не найден в таблице book, 
author. Внутреннее объединение содержит только те строки, которые точно 
соответствуют запросу. Позднее в этой главе мы обсудим понятие внешнего 
объединения, которое оказывается полезным в случае, когда в базу данных внесен 
писатель, у которого нет в этой базе книг.
Псевдонимы
Полные имена, содержащие имена таблиц и колонок, зачастую весьма громоздки. 
Кроме того, при использовании функций SQL, о которых мы будем говорить ниже, 
может оказаться затруднительным ссы-
латься на одну и ту же функцию более одного раза в пределах одной команды. 
Псевдонимы, которые обычно короче и более выразительны, могут использоваться 
вместо длинных имен внутри одной команды SQL, например:
# Псевдоним колонки
SELECT long_field_names_are_annoying AS myfield
FROM table_name
WHERE myfield = 'Joe'
# Псевдоним таблицы в MySQL
SELECT people.names, tests.score
FROM tests, really_long_people_table_name AS people
# Псевдоним таблицы в mSQL
SELECT people.names, tests.score
FROM tests, really_long_people_table_name=people
mSQL полностью поддерживает псевдонимы для таблиц, но не поддерживает 
псевдонимы для колонок.
Группировка и упорядочение
По умолчанию порядок, в котором появляются результаты выборки, не определен. К 
счастью, SQL предоставляет некоторые средства наведения порядка в этой 
случайной последовательности. Первое средство -упорядочение - есть и в MySQL, и 
в mSQL. Вы можете потребовать от базы данных, чтобы выводимые результаты были 
упорядочены по некоторой колонке. Например, если вы укажете, что запрос должен 
упорядочить результаты по полю last_name , то результаты будут выведены в 
алфавитном порядке по значению поля last_name . Упорядочение осуществляется с 
помощью предложения ORDER BY:
SELECT last_name, first_name, age
FROM people
ORDER BY last_name, first_name
В данном случае упорядочение производится по двум колонкам. Можно проводить 
упорядочение по любому числу колонок, но все они должны быть указаны в 
предложении SELECT. Если бы в предыдущем примере мы не выбрали поле last_name , 
то не смогли бы упорядочить по нему.
Группировка — это средство ANSI SQL, реализованное в MySQL, но не в mSQL. 
Поскольку в mSQL нет агрегатных функций, то группировка просто не имеет смысла. 
Как и предполагает название, группировка позволяет объединять в одну строки с 
аналогичными значениями с целью их совместной обработки. Обычно это делается 
для применения к результатам агрегатных функций. О функциях мы поговорим 
несколько позднее.
Рассмотрим пример:
mysql> SELECT name, rank, salary FROM people\g

5 rows in set (0.01 sec)
После группировки по званию (rank) выдача изменяется:
mysql> SELECT rank FROM people GROUP BY rank\g

3 rows in set (0.01 sec)
После применения группировки можно, наконец, найти среднюю зарплату (salary) 
для каждого звания. О функциях, используемых в этом примере, мы поговорим 
позднее.
mysql> SELECT rank, AVG(salary) FROM people GROUP BY rank\g

3 rows in set (0.04 sec)
Мощь упорядочения и группировки в сочетании с использованием функций SQL 
позволяет производить большой объем обработки данных на сервере до их 
извлечения. Но этой мощью нужно пользоваться с большой осторожностью. Хотя 
может показаться, что перенос максимального объема обработки на сервер базы 
данных дает выигрыш в производительности, на самом деле это не так. Ваше 
приложение-клиент обслуживает потребности отдельного клиента, в то время как 
сервер совместно используется многими клиентами. Из-за большого объема работы, 
который должен производить сервер, почти всегда более эффективно возложить на 
сервер минимально возможную нагрузку. MySQL и mSQL, возможно, наиболее быстрые 
из имеющихся баз данных, но не нужно использовать эту скорость для той работы, 
к которой лучше приспособлено клиентское приложение.
Если вам известно, что много клиентов будет запрашивать одни и те же итоговые 
данные (например, данные по некоторому званию в нашем предыдущем примере), 
создайте новую таблицу с этими данными и обновляйте ее при изменении данных в 
исходной таблице. Эта операция аналогична буферизации и является 
распространенным приемом в программировании баз данных.
Расширения языка
Как MySQL, так и mSQL обладают некоторыми витиеватыми расширениями, аналогов 
которым вы не найдете в других базах данных. Большинство расширений, имеющихся 
в MySQL, в целом согласуется со стандартом ANSI SQL. Расширения mSQL связаны 
просто с особыми переменными, к которым можно обращаться при работе с базой 
данных mSQL.
Возможности MySQL
MySQL превосходит mSQL в поддержке SQL, предоставляя возможность работы с 
функциями и в некоторой мере — с внешними объединениями. Функции в SQL 
аналогичны функциям в других языках программирования, таких как С и Perl. 
Функция может принимать аргументы и возвращает некоторое значение. Например, 
функция SQRT(16) возвращает 4. В MySQL в команде SELECT функции могут 
использоваться в двух местах:
Как извлекаемая величина
В этом случае функция включается в список извлекаемых колонок. Возвращаемое 
функцией значение, вычисляемое для каждой выбранной строки, включается в 
возвращаемое результирующее множество, как если бы это была колонка базы данных.
 Вот пример:
# Выбрать название каждого события (event), а также его дату
# в удобном для чтения формате из всех событий, более свежих,
# чем указанная дата. Функция FROM_UnixTIME()
# преобразует стандартное значение времени Unix
# в читаемый вид.
SELECT name, FROM_UnixTIME(date)
FROM events
WHERE time > 90534323
# Выбрать заглавие статьи, полный текст ее,
# и длину (в байтах) полного текста для всех 
# статей, автор которых Stacie Sheldon.
# Функция LENGTHO возвращает длину заданной
# строки в символах.
SELECT title, text, LENGTH(text)
FROM papers
WHERE author = 'Stacie Sheldon'
Как часть предложения WHERE
В этом виде функция заменяет место константы при вычислении в предложении WHERE.
 Значение функции используется при сравнении в каждой строке таблицы. Приведем 
пример.
# Случайным образом выбрать название объекта из общего числа 35.
# Функция RAND() генерирует случайное число
# между 0 и 1 (умножается на 34, чтобы сделать его между 0
# и 34, и увеличивается на 1 , чтобы сделать его между 1 и
# 35). Функция ROUND() возвращает данное число округленным
# до ближайшего целого, что приводит к целому числу
# между 1 и 35, которое должно соответствовать одному
# из чисел ID в таблице.
SELECT name
FROM entries
WHERE id = ROUND( (RAND()*34) + 1 )
# Можно использовать функции одновременно в списке значений
# и предложении WHERE. В этом примере выбираются имя и дата
# всех событий, происшедших более суток назад. Функция UNIX_TIMESTAMP()
# без аргументов возвращает текущее время
# в формате Unix.
SELECT name, FROM_UnixTIME(date)
FROM events
WHERE time > (Unix_TIMESTAMP() - (60 * 60 * 24) )
# Функция может использовать значение поля таблицы.
# В этом примере возвращаются имена всех,
# кто использовал свое имя в качестве пароля. Функция ENCRYPTO
# возвращает зашифрованную в стиле пароля Unix
# заданную строку, используя 2-символьный ключ.
# Функция LEFT() возвращает п самых левых символов
# переданной строки.
SELECT name
FROM people
WHERE password = ENCRYPT(name, LEFT(name, 2))
Наконец, MySQL поддерживает более сильный тип объединения, чем простое 
внутреннее объединение, которое мы до сих пор использовали. Именно, MySQL 
поддерживает так называемое левое внешнее объединение (известное также просто 
как внешнее объединение). Объединение этого типа похоже на внутреннее 
объединение, за исключением того, что в него включаются данные из левой колонки,
 которым нет соответствия в правой колонке. Если вы обратитесь к нашим таблицам 
с авторами и книгами, то вспомните, что в наше объединение не вошли авторы, у 
которых в базе данных не было книг. Часто вы можете пожелать вывести записи из 
одной таблицы, для которых нет соответствия в другой таблице, с которой 
производится объединение. Это можно сделать с помощью внешнего объединения:
SELECT book.title, author.name
FROM author
LEFT JOIN book ON book.author = author.id
Обратите внимание, что во внешнем объединении вместо WHERE используется 
ключевое слово ON. Результат нашего запроса будет выглядеть так:

MySQL делает следующий шаг, позволяя использовать естественное внешнее 
объединение (natural outer join). Естественное внешнее объединение соединяет 
строки двух таблиц, в которых две колонки имеют одинаковые имена и тип, и 
значения в этих колонках совпадают:
SELECT my_prod.name
FROM my_prod
NATURAL LEFT JOIN their_prod
Особенности mSQL
В mSQL есть пять «системных переменных», которые можно включить в любой запрос. 
Об одной из этих переменных, _seq, мы уже говорили. Остальные переменные 
следующие:
_rowid
Уникальный идентификатор возвращенной строки данных. Для повышения 
производительности можно использовать эту переменную в командах UPDATE или 
DELETE. Однако такой подход нельзя рекомендовать определенно, поскольку разные 
клиенты могут помешать друг другу. Например, два клиента могут выбрать одну и 
ту же строку. Первый клиент удаляет ее, а затем третий клиент добавляет новую 
строку. Новая строка может получить то же значение _rowid, что и удаленная 
строка. Если теперь второй клиент попытается отредактировать или удалить строку,
 используя данное значение _rowid, то результат будет совсем не тот, на который 
он рассчитывал.
_timestamp
Время последней модификации строки. В текущей версии mSQL имеет стандартный 
формат времени Unix. В будущих версиях формат может измениться, поэтому 
использовать эту переменную следует только для сравнения временных меток разных 
строк.
_sysdate
Возвращает значение текущей даты на сервере mSQL. Может использоваться для 
синхронизации времени в базе данных, даже если у клиентов на машинах стоит 
разное время. Имеет стандартный формат Unix.
_user
Содержит имя клиента текущего соединения. Как и _-sysdate, не зависит от 
таблицы, из которой выбирается.
Глава №7.
Другие СУБД среднего масштаба
Когда mSQL впервые вышла на сцену, это была единственная СУБД среднего масштаба 
с поддержкой SQL. Но она недолго оставалась в одиночестве. Конечно, вы уже 
знаете о другой такой базе данных: MySQL. За годы, прошедшие после появления 
mSQL, появилось и несколько СУБД среднего класса. Мы сосредоточились в этой 
книге на MySQL и mSQL из-за их очень большого сходства и громадной популярности.
 Было бы, однако, несправедливо не упомянуть о других базах данных.
Базы данных используются в столь многочисленных задачах, что трудно в одном 
пакете соединить все функции для всех возможных применений. Тем не менее 
крупные поставщики баз данных пытаются достичь этой цели. Они расплачиваются за 
это производительностью, а вы расплачиваетесь своими деньгами. С другой стороны,
 базы данных низшего класса настолько узко специализированы, что возможности их 
использования на малых предприятиях, в некоммерческих организациях и других 
местах с нетривиальными потребностями весьма ограниченны. Базы данных среднего 
класса заполняют важный пробел между двумя этими крайностями. До сего времени 
мы рассматривали лишь два очень схожих подхода к удовлетворению потребности в 
базе данных среднего класса. Определенно, они не являются единственными 
решениями. Если, скажем, ваша компания невелика, это не значит, что вам не 
может потребоваться поддержка транзакций. Некоторым пользователям среднего 
звена могут потребоваться также триггеры, вложенные запросы, хранимые процедуры,
 поддержка объектно-ориентированного программирования и многое другое - но не 
все эти возможности одновременно. Таким образом, различные базы данных среднего 
класса могут иметь необходимые возможности, отсутствующие в MySQL или mSQL.
Что значит «бесплатный»?
Иногда можно слышать, как MySQL и mSQL называют «бесплатными» (free) продуктами.
 Когда сравнивают MySQL и mSQL, иногда даже говорят, что MySQL «более 
бесплатна», чем mSQL. Здравый смысл противится выражению «более бесплатный». 
Однако в мире программного обеспечения действительно изобретены «степени 
бесплатности».
До сих пор мы сознательно избегали обсуждения «бесплатности» MySQL и mSQL, 
поскольку термин «бесплатный» неоднозначен в мире программного обеспечения. На 
самом деле, лицензия как на один, так и на другой продукт может оказаться для 
вас не бесплатной, в зависимости от того, кем вы являетесь. По правилам, 
действовавшим в момент написания книги, университет не был обязан платить за 
лицензию ни на тот, ни на другой продукт. А коммерческий пользователь mSQL- 
обязан. Когда говорят, что MySQL «более бесплатна», чем mSQL, имеют в виду, что 
MySQL бесплатна для большего числа пользователей, чем mSQL.
Другая сторона понятия «бесплатный» для программ не имеет отношения к цене, а 
связана с возможностью изучать и модифицировать исходный код. В этом смысле тот 
и другой продукт совершенно бесплатны. Вы можете зайти на их веб-страницы и 
загрузить исходный код. Даже если вы принадлежите к пользователям MySQL или 
mSQL, которые обязаны платить за их использование, тратиться дополнительно на 
исходный код не нужно.
В мире программирования возник новый термин, предназначенный для избавления от 
неоднозначности понятия «бесплатный». Он называется Open Source- Открытый код. 
Фактически, термин «Open Source» стал торговой маркой, обозначающей программный 
продукт, исходный код которого открыт вне зависимости от взимаемой за его 
использование платы. Linux, Netscape, FreeBSD, Perl, Apache, все продукты GNU и 
многие продукты, упоминаемые в этой книге, такие как MySQL, mSQL, mm.mysql.jdbc 
и mSQL-JDBC (мы перечислили лишь немногие), - все они являются Open 
Source-продуктами.
Другие базы данных, о которых мы говорим в этой главе, также относятся к Open 
Source. Open source имеет очень большое значение в мире пользователей среднего 
класса, поскольку «большие парни» склонны рассматривать этот рынок как не 
заслуживающий их внимания из-за ограниченности, а разработчики малого класса 
считают эти продукты слишком сложными для себя.
Чего недостает MySQL и mSQL
Слово «недостает» выбрано за неимением лучшего. Как уже отмечалось, MySQL и 
mSQL сознательно предпочли отказаться от возможностей, которые могли снизить их 
производительность. Иными словами, в MySQL и mSQL ставка сделана на 
производительность. Однако некоторые пользователи среднего класса готовы 
отчасти пожертвовать производительностью ради определенных функций. Для 
понимания того, что предлагают другие базы данных среднего масштаба, полезно 
выяснить, что же опущено в MySQL и mSQL.
Разработчики MySQL собираются все-таки включить в свой продукт некоторые из 
этих функций с возможностью по желанию их отключать. Сейчас, когда книга 
печатается, мы зна- . ем, что планируется реализовать механизм хранимых 
процедур и вложенных запросов, а возможно, и транзакций.
Транзакции
Транзакции позволяют сгруппировать вместе несколько команд SQL в качестве 
единицы работы. Группируя вместе команды, можно быть уверенным, что никто не 
столкнется с частично измененной базой данных. Кроме того, при невозможности 
выполнить одну из команд вся единица работы не будет выполнена. Транзакции 
можно зрительно представить себе как перекресток оживленных дорог. В 
однопоточной системе с очередью, такой как mSQL, это как остановка перед 
перекрестком со всех четырех сторон. Все машины проезжают в очередь по одной. 
Если проезжает колонна из двух машин, существует опасность, что она будет 
разорвана перед знаком остановки.
В многопоточной системе с блокировкой, такой как MySQL, это больше напоминает 
перекресток с регулировщиком вместо знаков остановки. Движение происходит в 
любом порядке и с любой скоростью, а регулировщик следит, чтобы не было 
столкновений. Если к перекрестку подходят одновременно две машины с 
пересекающихся направлений, регулировщик приказывает одной из них остановиться 
и подождать, пока другая преодолеет перекресток.
Транзакции напоминают перекресток со светофором. Подходящий транспорт 
останавливается перед красным сигналом на то время, пока весь транспорт, 
следующий в перпендикулярном направлении, не пересечет перекресток.
Практический пример использования транзакций - банковское приложение, в котором 
перевод средств со сберегательного на чековый счет выполняется в результате 
изменения остатка на сберегательном счете, а затем изменения остатка на чековом 
счете. Это можно осуществить с помощью двух команд SQL:
# Снять $100 из $110 на сберегательном счете 
UPDATE account
SET balance = 10.00
WHERE id = 1234
# Добавить $100 к $55 на чековом счете 
UPDATE account
SET balance = 155.00 
WHERE id = 5678
В промежутке между двумя этими изменениями другой клиент мог провести операцию, 
проверяющую состояние чекового и сберегательного счетов, чтобы узнать, 
достаточна ли сумма для оплаты чека. Если бы подобное произошло, чек был бы 
возвращен банком. Еще хуже, если сервер «упадет» в промежутке между двумя 
изменениями. Клиент просто потеряет $100.
Объединяя эти две команды в транзакцию, вы говорите, что либо обе должны быть 
успешно выполнены, либо ни одна из них. Если первая команда пройдет, а вторая 
не сможет выполниться, то можно дать команду, называемую «откат»(«rollback»), 
которая вернет базу данных в состояние, предшествовавшее началу транзакции. 
Точно так же никому не разрешается трогать файлы, которые вы модифицируете, 
пока работа не будет завершена. MySQL частично позволяет эмулировать транзакции,
 используя команду LOCK TABLES. Блокировки помогают избежать нарушения 
целостности данных, но не дают возможности осуществления операции отката. В 
mSQL поддержка транзакций отсутствует.
Триггеры
Триггеры тесно связаны с транзакциями. Продолжая аналогию с дорожным движением, 
представим себе полицейского инспектора, сверху наблюдающего за перекрестком. 
Если одна из машин совершает какое-либо нарушение, инспектор выезжает на дорогу 
и преследует нарушителя.
Триггер — это одна или несколько команд SQL, которые хранятся в базе и 
выполняются, когда происходит какое-либо определенное событие. Триггеры 
являются методом автоматизации задач контроля. Если выполняется некоторое 
условие, триггер может воздействовать на данные или просто сообщить о том, что 
имело место срабатывание триггера.
Хранимые процедуры
В простейшем случае хранимые процедуры - это одна или несколько команд SQL, 
хранимых в базе данных под каким-либо простым именем и в совокупности 
выполняющих некую функцию. В примере с переводом денежных средств можно было бы 
просто сохранить эти две команды в одной хранимой процедуре с именем «transfer» 
(перевод). Ваше приложение передает хранимой процедуре два номера счета и сумму,
 и она выполняет две команды SQL в одной транзакции.
На более высоком уровне сложности хранимые процедуры могут расширять базовый 
синтаксис SQL, так что он становится похожим на традиционные языки 
программирования. Двумя примерами таких расширений являются Oracle PL/SQL и 
Sybase/ Microsoft Tran-sactSQL. Часто можно слышать, что использование хранимых 
процедур «помещает бизнес-логику в базу данных».
Вложенные запросы
Обычная команда SQL SELECT осуществляет полный доступ ко всем данным, хранимым 
в таблице, - если вы знаете, что ищете. Когда вы не стремитесь извлечь 
содержимое таблицы целиком, SELECT в своем основном виде требует ввести хотя бы 
часть данных, которые вы хотите извлечь. Например, SELECT name FROM friends 
WHERE name LIKE 'B%' требует знания хотя бы одной буквы имени, которое вы ищете.
 Что делать в случае, если вы хотите узнать, чей заработок был выше среднего? 
Запрос должен выглядеть примерно так:
SELECT name FROM people WHERE salary > ???
Больше чего? Вы понятия не имеете, каков средний заработок, пока не сделаете 
выборку по заработкам! Необходимо взять значение SELECT AVG(salary) FROM people 
и вставить его в предыдущий запрос. Вложенный запрос позволяет это сделать:
SELECT name 
FROM people 
WHERE salary > (SELECT AVG(salary) FROM people)
Объекты
Реляционные базы данных - не конечный пункт эволюции. Имеется много 
объектно-реляционных и объектно-ориентированных баз данных. На рынке систем 
большого масштаба идея чисто реляционных баз данных постепенно отступает. Новый 
стандарт SQL3 включит в себя многие изменения, касающиеся поддержки объектов.
В РСУБД все данные хранятся в виде таблиц, представляющих собой просто списки 
записей, в свою очередь, являющихся собранием битов, представляющих текст, 
числа и другие типы данных. В объектно-ориентированной системе управления 
базами данных (ООСУБД) базовой единицей хранения данных является объект. Объект 
может содержать не только данные тех же типов, что встречаются в реляционных 
базах данных, но также и другие объекты или многомерные данные, скажем, массивы,
 или даже выполняемые функции, в мире объектно-ориентированного 
программирования обычно называемые методами.
PostgreSQL
Существующая в настоящее время реализация объектно-реляционной СУБД Postgres 
известна как PostgreSQL (или Postgres 6). Хотя Post-gres поддерживает SQL в 
течение всего трех лет, самой системе уже более десяти лет. В начале 1980-х д-р 
Майкл Стоунбрейкер (Michael Sto-nebreaker) из Калифорнийского Университета в 
Беркли разработал систему баз данных, которая предвосхитила многие концепции, 
реализованные в современных системах управления базами данных. Эта СУБД 
получила название Ingres (позднее University Ingres). Ingres была 
некоммерческим проектом, финансируемым университетом; проектом, быстро обретшим 
последователей среди специалистов по компьютерам во всем мире.
Одна из фирм обратила внимание на коммерческий потенциал этого академического 
продукта и, зарегистрировав торговую марку Ingres, сделала коммерческий продукт.
 Исходная некоммерческая версия Ingres была переименована в University Ingres, 
и ее развитие продолжилось независимо от коммерческой версии.
Через некоторое время д-р Стоунбреикер пошел в своих исследованиях дальше того, 
что предполагалось в начальных целях проекта Ingres. Он решил, что настало 
время разработать совершенно новую систему баз данных, развивавшую идеи, 
заложенные в Ingres, и отправился осваивать новую территорию. Эта система баз 
данных стала известна как Postgres, то есть после-Ingres.
Postgres, как и Ingres, была открытым для общественности проектом, который 
финансировался университетом. И так же, как в случае Ingres, коммерческий 
сектор обратил внимание и на Postgres, в результате чего появился коммерческий 
проект Illustra*. Бесплатная Postgres продолжила свое существование и сейчас 
соперничает в популярности с MySQL и mSQL среди серверов баз данных среднего 
масштаба.
В 1995 г. произошли два события, повлиявшие на судьбу Postgres. Во-первых, два 
студента д-ра Стоунбрейкера - Эндрю Ю (Andrew Yu) и Джолли Чен (Jolly Chen) - 
разработали SQL-интерфейс для Postgres.
Таким образом, через несколько лет после того, как Дэвид Хьюз впервые 
разработал MiniSQL для использования SQL в работе с Postgres, у последней 
появился настоящий SQL-интерфейс. Поддержка SQL вызвала рост популярности. Как 
и в случае с mSQL и MySQL, рост популярности привел к росту потребности в новых 
функциях. В результате появилась объектно-ориентированная СУБД среднего 
масштаба с поддержкой транзакций, триггеров и вложенных запросов. Подробнее 
узнать о PostgreSQL можно на http://www.postgresql.org.
GNU SQL
Проект GNU для многих программистов является символом свободы. Официальная 
лицензия на продукты GNU гарантирует свободный доступ и полную свободу 
модификации исходного кода. Почти для всякой утилиты среды Unix можно найти 
версию GNU - включая редактор (Emacs), командный процессор (bash) и ядро 
операционной системы (Hurd). До недавнего времени зияющим пробелом было 
отсутствие СУБД.
Институт системного программирования Российской Академии наук работает над тем, 
чтобы изменить это положение. Пару лет назад он выпустил первую открытую 
бета-версию GNU SQL - полностью функциональную РСУБД с поддержкой SQL и 
лицензией GNU Public License (GPL). Ко времени печати этой книги текущая версия 
GNU SQL имела номер 0.7beta.
Когда задумывалась GNU SQL, спецификация SQL 2 была еще не окончательной, 
поэтому первые версии GNU SQL обеспечивали поддержку только функций SQL89, а 
возможности SQL2 добавлялись постепенно.
В настоящее время GNU SQL поддерживает многие развитые возможности - транзакции,
 вложенные запросы и курсоры. Поскольку это бета-версия, мы не рекомендовали бы 
ее для промышленного использования. По мере своего становления она, конечно, 
будет достойна внимания. Подробнее узнать о GNU SQL можно на http://www.ispras.
ru/-kml/gss/index.html 
Beagle
Beagle является бесплатным ядром баз данных SQL, разработанным и реализованным 
Робертом Клейном (Robert Klein). Как и GNU SQL, Beagle задуман как полностью 
SQL-совместимый сервер со всеми необходимыми функциями, включая 
объектно-реляционные расширения, впервые появившиеся в PostgreSQL. Как и GNU 
SQL, Beagle во многом не завершен. Ко времени печати этой книги он достиг того 
уровня развития, когда он надежен и может использоваться для тестирования и 
разработки. Для промышленного пользования этот продукт еще не готов.
Одной из наиболее интересных особенностей Beagle является то, что автор с 
самого начала проекта вел журнал разработки. Изучая этот журнал, вы можете 
проследить развитие SQL-сервера от простого тестового приложения, использующего 
TCP и архитектуру клиент/сервер, до почти полностью функционального SQL-сервера,
 каким он является сегодня. Домашняя страница Beagle расположена на http:// www.
beaglesql.org.
Сравнение характеристик
Как и многие приложения, MySQL обладает набором тестов для проверки того, что 
заново откомпилированная система действительно поддерживает все возможности, 
которыми предположительно должна обладать. Для MySQL этот набор называется 
«crash-me», поскольку одной из его задач является попытка «завалить» сервер баз 
данных.
В какой-то момент обратили внимание на то, что «crash-me» является переносимой 
программой. Она может работать не только в различных операционных системах, но 
и использоваться для тестирования разных СУБД. С тех пор «crash-me» 
превратилась из простого набора тестов в программу, позволяющую производить 
сравнение характеристик. Тесты включают в себя стандартный SQL, а также 
расширения, предлагаемые многими серверами. Кроме того, программа проверяет 
надежность сервера при интенсивной нагрузке. Полный прогон тестов дает 
исчерпывающую характеристику возможностей сервера баз данных.
Можно использовать «crash-me» для сравнения двух или более серверов баз данных 
в активном режиме. Домашняя страница «crash-me» находится на http://www.mysql.
com/crash-me-choose.htmy.
Часть II.
Программирование баз данных
Мощь базы данных реализуется через инструменты, предназначенные для работы с 
ней. В этой части мы поговорим о том, как создавать такие инструменты, 
используя некоторые популярные сегодня языки программирования. На примере 
создания веб-приложений для бизнеса мы обсудим API и инструменты, необходимые 
для максимального использования потенциала MySQL и mSQL. Эта часть начинается с 
нескольких обзорных глав по архитектуре приложений для работы с базами данных и 
СGI-программированию. Однако основное содержание этой части посвящено 
программированию на различных языках для MySQL и mSQL.
Глава №8.
Архитектуры приложений для работы с базами данных
Прежде чем разбираться в деталях разработки приложений для работы с базами 
данных на различных языках, следует потратить некоторое время и шире взглянуть 
на проектирование этих приложений. Эта глава концептуальная: мы хотим 
рассмотреть архитектуру клиент/ сервер, лежащую в основе программирования баз 
данных. Эти вопросы важны для программирования MySQL и mSQL, но не являются 
специфичными только для этих СУБД. Напротив, они применимы в любой среде 
программирования баз данных. Если не учитывать принципов архитектуры, то может 
оказаться, что ваши приложения не могут ни удовлетворить ваши потребности, ни 
приспособиться к изменяющимся обстоятельствам. В нашем обзоре программирования 
баз данных мы коснемся таких сложных тем, как понятие об обычной двухзвенной 
архитектуре, соответствие между объектами и реляцион-ностью и более новой 
трехзвенной архитектуре клиент/сервер.
Архитектура клиент/сервер
В упрощенном виде архитектура клиент/сервер предполагает разделение 
происходящей в приложении обработки на две или более логически различные части. 
До сих пор в этой книге мы обсуждали базы данных так, будто они существуют в 
некоем безвоздушном пространстве. Однако они выполняют свое предназначение 
только тогда, когда используются какими-либо приложениями. Упрощая, можно 
сказать, Что база данных составляет одну часть архитектуры клиент/сервер. База 
данных является «сервером», а всякое использующее ее приложение является 
«клиентом». Часто клиент и сервер расположены на разных машинах; в большинстве 
случаев приложение клиента является дружественным интерфейсом к базе данных. На 
рис. 8-1 графически представлена простая система клиент/сервер.
Возможно, вы уже встречали в Интернет такую структуру. По сути, мы будем 
обращаться к определенной задаче приложений клиент/сервер для Интернет на 
протяжении всей книги. К примеру, WWW является гигантским приложением типа 
клиент/сервер, в котором Web-броузер является клиентом, а Web-сервер- сервером. 
В этом сценарии сервер является не сервером реляционных баз данных, а 
специализированным файл-сервером. Важнейшим свойством сервера является то, что 
он предоставляет данные клиенту в определенном формате.

Рис. 8-1. Архитектура клиент/сервер
При создании приложения для работы с базой данных прежде всего необходимо иметь 
возможность связать клиента с базой данных. Поставщики баз данных предпочитают 
скрывать от разработчиков основополагающие механизмы связи посредством API, 
ориентированных на конкретный язык. Когда вы создаете приложение для работы с 
базой данных, то используете специальные библиотеки, которые транслируют ваши 
запросы в пакеты TCP/IP, передающиеся по сети к серверу базы данных.
Внешний вид этих API для доступа к базам данных различен и зависит от языка 
программирования, а во многих случаях - и от самой базы данных. Поскольку API 
для MySQL намеренно разрабатывались так, чтобы иметь сходство с mSQL, у всех 
API, которые вы найдете в этой книге, различия минимальны.
Обработка данных
В части I «Введение в MySQL и mSQL» мы дали понятия управления транзакциями и 
результирующего набора. Приложение для работы с базой данных — всего лишь 
инструмент для управления транзакциями и обработки результирующих наборов. 
Например, если ваше приложение является адресной книгой, то обработка 
результирующих наборов заключается в том, чтобы извлечь из таблицы все строки и 
показать их пользователю. Управление транзакциями просто сводится к тому, чтобы 
изменения в таблицах address и person производились как единое целое.
Мы уже упоминали, что в MySQL и mSQL нет поддержки транзакций. Всякое изменение 
в базе данных совершается автоматически, когда вы его запрашиваете. Это 
ограничение заставляет принимать специальные меры для того, чтобы целостность 
данных не нарушалась в результате отказа, происходящего в промежутке между 
двумя связанными между собой обращениями к базе данных.
Два других важных момента в работе приложения - это подключение и отключение. 
Вполне понятно, что перед тем, как выполнить запрос, необходимо подключиться к 
базе данных. Однако довольно часто забывают о второй стороне медали- 
необходимости «убрать за собой». Следует всегда освобождать все захваченные 
ресурсы базы данных, когда они вам больше не нужны. В долго живущих приложениях,
 таких как демон Интернет, неаккуратно написанная система может понемногу 
отнимать ресурсы базы данных, и, в конце концов, заблокирует систему.
«Уборка за собой» включает в себя правильную обработку ошибок. Хорошие языки 
программирования затрудняют пропуск обработчиков исключительных ситуаций (отказ 
сети, повторяющиеся ключи при добавлении, ошибки синтаксиса SQL и т. д.). Но 
независимо от того, какой язык вы избрали, вы обязаны знать, какие 
исключительные ситуации могут возникать при данном вызове API, и в каждой 
исключительной ситуации действовать надлежащим образом. С-библиотеки для MySQL 
и mSQL основываются на представлении базы данных в виде наборов строк. Мы хотим 
этим сказать, что библиотеки С позволяют непосредственно обращаться с данными в 
том виде, в каком они в принципе существуют в базе данных. Глава 13 «С и C++», 
раскрывает практические детали программирования в этой модели с использованием 
С API для MySQL и mSQL.
Доступ к реляционной базе данных из объектно-ориентированной среды выявляет 
особый парадокс: реляционный мир занимается исключительно манипуляциями с 
данными, в то время как мир объектов занимается инкапсуляцией данных внутри 
некоторого набора схем поведения. В объектно-ориентированном приложении база 
данных служит средством сохранения объектов для экземпляров приложения. 
Объектно-ориентированное программирование рассматривает данные запроса не как 
набор строк, а как собрание объектов.
Объектное/реляционное моделирование
Основная проблема, которая встает перед разработчиком объектно-ориентированного 
приложения при использовании реляционной базы данных, это - как отобразить 
реляционные данные в объекты. Первой мыслью может быть попытка отобразить 
атрибуты объекта в поля таблицы. К несчастью, такой подход по ряду причин не 
очень удачен.
* Объекты не хранят только простые данные в своих атрибутах. Там могут 
храниться также коллекции и связи с другими объектами.
* В большинстве реляционных баз данных, включая MySQL и mSQL, нет средств, 
позволяющих моделировать наследование.
Практические правила для объектно-реляционного моделирования
* У каждого сохраняемого класса в базе данных есть своя таблица.
* Поля объектов с простыми типами данных (целые, символы, строки и т. д.) 
сопоставлены колонкам в соответствующей таблице базы данных.
* Каждая строка таблицы базы данных cоответствует экземпляру соответствующего 
хранимого класса.
* Каждая связь между объектами типа «многие-ко-многим» требует таблицы-связки, 
так же как это требуется для объектов базы данных типа «многие-ко-многим».
* Наследование моделируется с помощью отношения «один-к-одному» между таблицами,
 соответствующими классу и подклассу. Вспомните адресную книгу, о которой мы 
говорили ранее. Допустим, она имеет таблицы address и person, как на рис. 8-2.

Рис. 8-2. Модель данных простого приложения адресной книги
Есть весьма неочевидная проблема, с которой сталкиваются программисты. Основная 
задача объектно-ориентированного подхода к реляционным данным - это, получив 
эти данные, немедленно создать экземпляр объекта. Приложение должно работать с 
данными только через объекты. Большинство традиционных методов программирования,
 включая разработку на С, PowerBuilder и VisualBasic, требует, чтобы 
разработчик извлек из базы данные, а затем их обработал. Главное отличие 
состоит в том, что в объектно-ориентированном программировании баз данных вы 
имеете дело с объектами, а не данными.
Рис. 8-3 показывает объектную модель, соответствующую модели данных на рис. 8-2.
 Каждая строка базы данных преобразуется в программный объект. Таким образом, 
ваше приложение принимает результирующий набор и для каждой возвращаемой строки 
создает новый экземпляр Address или Person. Труднее всего справиться с 
проблемой, о которой уже говорилось: как в приложении установить связь между 
человеком и его адресом? Объект Person, конечно, имеет ссылку на объект Address,
 относящийся к этому человеку, но сохранить объект Address внутри таблицы 
person реляционной базы нельзя. Модель данных предполагает хранение связей 
между объектами с помощью внешних ключей, для чего в таблицу person заносится 
address_id.

Рис. 8-3. Объектная модель, поддерживающая простое приложение адресной книги
Самое незначительное усложнение объектной модели может вызвать бездну проблем 
при установлении соответствия наших объектов и модели данных. Допустим, что 
Person является потомком Entity и класс Company тоже является потомком Entity. 
Как отделить Entity от Person или Company? Приведенное выше правило фактически 
является скорее рекомендацией. В некоторых случаях базовый класс является чисто 
абстрактным и, следовательно, не имеет в базе связанных с ним данных. В таком 
случае для этого класса в базе данных не будет объекта.
Трехзвенная архитектура
До сих пор мы обсуждали самую простую архитектуру для работы с WWW и простыми 
бизнес-приложениями - клиент/сервер. Однако эту архитектуру не так-то просто 
нарастить по мере роста и изменения ваших приложений. В ней также трудно 
использовать преимущества объектно-ориентированного программирования. Первая 
проблема недавно нашла отражение в дискуссиях относительно «тонких клиентов». 
Потребность в тонких клиентах происходит из беспокоящей тенденции в передаче 
клиенту все больших объемов обработки. Эта проблема проявилась в PowerBuilder и 
VisualBasic - инструментах, которые прямо вытаскивают данные из базы в GUI, а 
затем все операции над этими данными проводят в GUI.
Такая тесная привязка интерфейса пользователя к ядру базы данных приводит к 
появлению программ, которые трудно модифицировать и невозможно масштабировать 
при увеличении числа пользователей и объема данных. Если у вас есть опыт 
разработки интерфейсов пользователя, то вы сталкивались с проблемой переработки 
интерфейса в зависимости от каприза пользователя. Чтобы изолировать последствия 
такой переработки, проще всего оставить для GUI только одну задачу- действовать 
в качестве интерфейса пользователя. Такой интерфейс пользователя действительно 
является тонким клиентом.
Влияние на масштабируемость сказывается и с другой стороны. Когда требуется 
переработать приложение, чтобы оно могло справляться с возросшим числом 
пользователей и объемом данных, модификация может быть осуществлена в 
результате изменений, вносимых в базу данных, в том числе таких, которые 
состоят в распределении базы данных по нескольким серверам. Навечно привязав 
свой интерфейс к базе данных, вам приходится делать изменения в этом GUI для 
решения проблем масштабирования - проблем, связанных исключительно с сервером.
Тонкие клиенты - не единственное сегодняшнее поветрие. Другая тенденция - 
повторное использование кода. Общий для разных приложений код тяготеет к 
обработке данных, обычно называемой деловой логикой. Если вся ваша деловая 
логика располагается в интерфейсе пользователя, то добиться повторного 
использования кода будет, по меньшей мере, трудно. Решением этих проблем 
является разбиение приложения на три, а не на две части. Такая архитектура 
называется трехзвенной.
Когда мы говорим об интерфейсе пользователя у клиента, то имеем в виду 
логическое различие. Разновидностью тонкого клиента, иногда называемой 
«сверхтонким клиентом», является то, что обычно всеми воспринимается как 
Web-страница. Web-страница может динамически создаваться на Web-сервере. В этом 
случае большая часть работы клиента происходит на сервере в виде динамической 
генерации HTML-страниц.
Сравните двухзвенную архитектуру на рис. 8-1 с трехзвенной архитектурой, 
показанной на рис. 8-4. Мы добавили промежуточный слой между интерфейсом 
пользователя и базой данных. Этот новый слой, сервер приложений, заключает в 
себе логику работы приложения - деловую логику, которая является общей для 
некоторой области задач. Клиент становится ничем иным, как средством просмотра 
объектов среднего яруса, а база данных становится хранилищем этих объектов.
Самое главное, что вы выигрываете, - это разделение интерфейса пользователя и 
базы данных. Теперь вам не нужно встраивать знание базы данных в GUI. Напротив, 
все сведения о том, как работать с базой данных, могут размещаться в среднем 
ярусе.
Две главные задачи сервера приложений - это изоляция подключений к базе данных 
и обеспечение централизованного хранилища для деловой логики. Интерфейс 
пользователя имеет дело только с отображением и вводом данных, а ядро базы 
данных занимается только проблемами базы данных. При перемещении обработки 
данных в центральное место одну и ту же программу сервера приложений могут 
использовать различные интерфейсы пользователя, и устраняется необходимость 
писать правила обработки данных всякий раз, когда вы создаете новое приложение.

Рис. 8-4. Трехзвенная архитектура
Глава 9. Программирование с использованием CGI  - увы...отсутствует.
Глава №10.
Perl
Язык программирования Perl превратился из инструмента, используемого 
преимущественно администраторами Unix-систем, в наиболее распространенную 
платформу разработки для World Wide Web. Perl не предназначался изначально для 
Web, но простота его использования и мощные функции для работы с текстом 
сделали естественным его применение для CGI-программирования. Сходным образом, 
когда mSQL впервые появилась на сцене, исключительные компактность и скорость 
выполнения сделали ее очень привлекательной для разработчиков Web, которым 
требовалось обслуживать ежедневно тысячи операций. MySQL со своей высокой 
скоростью и расширенными возможностями стала еще более привлекательным 
средством для веб-разработчиков. Естественно поэтому, что был разработан 
интерфейс Perl к обеим базам - MySQL и mSQL, - объединив таким образом их 
достоинства.
В то время, когда пишется эта книга, существуют два интерфейса между Perl и 
MySQL с mSQL. Более ранний состоит из специализированных интерфейсов Myaql.pm и 
Msql.pm, которые работают только с MySQL и mSQL соответственно. Другой, более 
новый интерфейс является подключаемым модулем в комплекте DBI (DataBase 
Independent) - независимых от базы данных модулей. DBI является попыткой 
обеспечить общий Perl API для доступа к любым базам данных и предоставления 
более высокой переносимости. Интерфейс DBI стал наиболее надежным и стандартным,
 и разработчики MySQL рекомендуют пользоваться только DBI, поскольку дальнейшая 
разработка модулей Mysql.pm и Msql.pm прекращена. Однако многие унаследованные 
системы все еще используют их, поэтому мы расскажем здесь и о них.
DBI
Рекомендуемым методом доступа к базам данных MySQL и mSQL из Perl является 
интерфейс DBD/DBI. DBD/DBI означает DataBase Dependent/DataBase Independent 
(Зависимый от базы данных/Независимый от базы данных). Название связано с 
двухъярусной реализацией интерфейса. В нижнем ярусе находится зависимый от базы 
данных уровень. На нем существуют свои модули для каждого типа базы данных, 
доступного из Perl. Поверх этого уровня находится независимый от базы данных 
уровень. Это тот интерфейс, которым вы пользуетесь при доступе к базе данных. 
Выгода такой схемы в том, что программисту нужно знать только один API уровня 
независимости от базы данных. Когда появляется новая база данных, кому-нибудь 
нужно лишь написать для нее модуль DBD (зависимый), и она станет доступна всем 
программистам, использующим DBD/DBI.
Как и в любом модуле Perl, для получения доступа нужно указать DBI в директиве 
use:
#!/usr/bin/perl -w
use strict;
use CGI qw(:standard);
use DBI;
При запуске программ Perl для MySQL/mSQL следует всегда задавать аргумент 
командной строки -w. Благодаря этому DBI будет перенаправлять все специфические 
для MySQL и mSQL сообщения об ошибках на STDERR, и вы сможете увидеть ошибки, 
вызванные работой с базой данных, не прибегая к явной проверке их в программе.
Всякое взаимодействие между Perl, с одной стороны, и MySQL и mSQL - с другой, 
производится с помощью объекта, известного как описатель базы данных (handle). 
Описатель базы данных (database handle) - это объект, представленный в Perl как 
скалярная ссылка и реализующий все методы, используемые для связи с базой 
данных. Одновременно можно открыть любое число описателей базы данных, 
ограничение накладывают только ресурсы системы. Метод connect() использует для 
создания описателя формат соединения DBI:servertype:database:hostname:port (имя 
узла и порта необязательны), дополнительными аргументами служат имя 
пользователя и пароль:
my $dbh = DBI->connect( 'DBI:mysql:mydata ', undef, Lindef);
my $dbh = DBI->connect( 'DBI:mSQL:mydata:myserver', undef, undef);
my $dbh = DBI->connect( 'DBI:mysql:mydata', 'me', 'mypass")',
Атрибут servertype является именем специфического для базы данных DBD-модуля, в 
нашем случае «mysql» или «mSQL» (обратите внимание на точное использование 
регистра). В первом варианте создается соединение с сервером MySQL на локальной 
машине через сокет Unix. Это наиболее эффективный способ связи с базой данных, 
который должен использоваться при соединении на локальном сервере. Если указано 
имя узла, оно используется для соединения с сервером на этом узле через 
стандартный порт, если только не задан и номер порта. Если при соединении с 
сервером MySQL вы не указываете имя пользователя и пароль, то пользователь, 
выполняющий программу, должен обладать достаточными привилегиями в базе данных 
MySQL. Для баз данных mSQL имя пользователя и пароль не должны указываться.
В Perl 5 используются два соглашения по вызову модулей. В 
объектно-ориентированном синтаксисе для ссылки на метод определенного класса 
используется символ стрелки «->» (как в DBI->connect). Другой метод - 
использование непрямого синтаксиса, в котором за именем метода следует имя 
класса, а затем - аргументы. В последнем примере метод connect следовало бы 
записать как connect DBI 'DBI:mysql:mydata', "me', ' mypass . В ранних версиях 
Msql.pm использовался исключительно непрямой синтаксис, и требовалось 
придерживаться метода использования заглавных букв, обусловленного mSQL С API. 
Поэтому значительная часть старого кода MsqlPerl содержит строки типа SelectDB 
$dbh ' test' там, где можно было бы написать проще: $dbh->selectdb(' test') . 
Если вы еще не догадались, то сообщаем, что мы неравнодушны к 
объектно-ориентированному синтаксису, хотя бы потому, что использование стрелки 
делает ясной связь между классом и методом.
Как только вы соединились с сервером MySQL или mSQL, описатель базы данных - во 
всех примерах этого раздела $dbh - становится шлюзом к базе данных. Например, 
так готовится запрос SQL:
$dbh->prepare($query);
При работе с mSQL для одного описателя базы данных можно одновременно выбрать 
только одну базу данных, это ограничение накладывается сервером mSQL. Однако в 
любой момент можно сменить текущую базу данных, повторно вызвав connect . При 
работе с MySQL можно включать в запрос другие базы данных, явно указывая их 
имена. Кроме того, и в MySQL, и в mSQL при необходимости одновременного доступа 
к нескольким базам данных можно создать несколько описателей базы данных и 
использовать их совместно.
В главе 21 «Справочник по Perl», описаны все методы и переменные, содержащиеся 
как в DBI, так и в Mysql.pm и Msql.pm.
Для иллюстрации использования DBI рассмотрим следующие простые программы. В 
примере 10-1 datashow.cgi принимает в качестве параметра имя узла; при 
отсутствии параметра принимается имя «local-host». Затем программа выводит 
список всех баз данных, имеющихся на этом узле.
Пример 10-1. Программа CGI datashow.cgi показывает все базы данных, имеющиеся 
на сервере MySQL или mSQL
#!/usr/bin/perl -w
use strict;
use CGI qw( standard);
use CGI::Carp;
# Использовать модуль DBI use DBI; CGI::use_named_parameters(1);
my ($server, $sock, $host);
my $output = new CGI;
$server = param('server') or Sserver = '';
# Подготовить DBD-драйвер для MySQL
my $driver = DBI->install_driver('mysql');
my @databases = $driver->func($server, '_ListDBs');
# Если параметр @databases неопределен, предполагаем,
# что на этом узле не запущен
# сервер MySQL. Однако это может быть вызвано
# другими причинами. Полный текст сообщения об ошибке
# можно получить, проверив $DBI::errmsg. 
if (not @databases) {
print header, start_html('title'=>"Данные no Sserver", 'BGCOLOR'=>'white'); 
print<$server
Ha Sserver , по-видимому, не запущен сервер mSQL.  END_OF_HTML
exit(0); }
print header, start_html('title'=>" Данные по $host",
'BGCOLOR'=>'white'); print <$host

Соединение с $host на сокете $sock.

Базы данных: