PHP и MySQLPHP и MySQL. Совместная работаЧто такое MySQL. Взаимодействие с PHPИтак, для начала ответим на вопрос: что такое MySQL? MySQL – это одна из самых популярных и самых распространенных СУБД (система управления базами данных) в интернете. Она не предназначена для работы с большими объемами информации, но ее применение идеально для интернет сайтов, как небольших, так и достаточно крупных. MySQL отличатся хорошей скоростью работы, надежностью, гибкостью. Работа с ней, как правило, не вызывает больших трудностей. Поддержка сервера MySQL автоматически включается в поставку PHP. Немаловажным фактором является ее бесплатность. MySQL распространяется на условиях общей лицензии GNU (GPL, GNU Public License). Ранее для долговременного хранения информации мы работали с файлами: помещали в них некоторое количество строчек, а затем извлекали их для последующей работы. Задача длительного хранения информации очень часто встречается в программировании Web-приложений: подсчёт посетителей в счётчике, хранение сообщений в форуме, удалённое управление содержанием информации на сайте и т.д. Между тем, профессиональные приёмы работы с файлами очень трудоёмки: необходимо заботится о помещении в них информации, о её сортировке, извлечении, при этом не нужно забывать, что все эти действия будут происходить на сервере хост-провайдера, где с очень большой вероятностью стоит один из вариантов Unix - следовательно, нужно так же заботится о правах доступа к файлам и их размещении. При этом объём кода значительно возрастает, и совершить ошибку в программе очень просто. Все эти проблемы решает использование базы данных. Базы данных сами заботятся о безопасности информации и её сортировке и позволяют извлекать и размещать информацию при помощи одной строчки. Код с использованием базы данных получается более компактным, и отлаживать его гораздо легче. Кроме того, не нужно забывать и о скорости - выборка информации из базы данных происходит значительно быстрее, чем из файлов. ПримечаниеПриложение на РНР, использующее для хранения информации базу данных (в частности MySql) всегда работает быстрее приложения, построенного на файлах. Дело в том, что базы данных написаны на языке C++, и написать на PHP программу, которая работала бы с жёстким диском эффективнее базы данных - задача неразрешимая по определению, поскольку программы на PHP в принципе работают медленнее, чем программы на C++, так как РНР - интерпретатор, а С++ - компилятор. Таким образом, основное достоинство базы данных заключается в том, что она берёт на себя всю работу с жёстким диском и делает это очень эффективно. Реляционные базы данныхЗадача длительного хранения и обработки информации появилась практически сразу с появлением первых компьютеров. Для решения этой задачи в конце 60-х годов были разработаны специализированные программы, получившие название систем управления базами данных (СУБД). СУБД проделали длительный путь эволюции от системы управления файлами, через иерархические и сетевые базы данных. В конце 80-х годов доминирующей стала система управления реляционными базами данных (СУРБД). С этого времени такие СУБД стали стандартом де-факто, и для того, чтобы унифицировать работу с ними, был разработан структурированный язык запросов (SQL), который представляет собой язык управления именно реляционными базами данных. ЗамечаниеВзаимодействие с базой данных происходит при помощи Системы Управления Базой Данных (СУБД), которая расшифровывает запросы и производит операции с информацией в базе данных. Поэтому более правильно было бы говорить о запросе к СУБД и о взаимодействии с СУБД из Web-приложения. Но так как это несколько усложняет восприятие, далее везде мы будем говорить "база данных", подразумевая при этом СУБД. Существуют следующие разновидности баз данных:
Иерархическая база данных основана на древовидной структуре хранения информации. В этом смысле иерархические базы данных очень напоминают файловую систему компьютера. В реляционных базах данных данные собраны в таблицы, которые в свою очередь состоят из столбцов и строк, на пересечении которых расположены ячейки. Запросы к таким базам данных возвращает таблицу, которая повторно может участвовать в следующем запросе. Данные в одних таблицах, как правило, связаны с данными других таблиц, откуда и произошло название "реляционные". В объектно-ориентированных базах данных данные хранятся в виде объектов. С объектно-ориентированными базами данных удобно работать, применяя объектно-ориентированное программирование. Однако, на сегодняшний день такие базы дан-ных еще не достигли популярности реляционных, поскольку пока значительно уступают им в производительности. Гибридные СУБД совмещают в себе возможности реляционных и объектно-ориентированных баз данных. В Web-приложениях, как правило, используются реляционные базы данных. Мы будем рассматривать пример базы данных, на которой основано большинство форумов, в том числе и тот, который мы далее будем разрабатывать. В этой базе хранится информация об авторах форума (authors), о названиях форумов (forums), о темах форума (themes) и, собственно, сами сообщения (posts). Таким образом, наша база данных будет включать следующие таблицы: Таблица 1 Таблицы базы данных Forum.
Модель реляционной базы данных представляет данные в виде таблиц, разбитых на строки и столбцы, на пересечении которых находятся данные. Пример такой таблицы показан в Табл.2: Таблица 2 Структура реляционной базы данных.
В табл.2 приведён пример таблицы forums базы данных большого форума, в котором имеется несколько разделов, посвящённых различным этапам построения Web-приложения. Каждая строка этой таблицы представляет собой один раздел форума. Четыре строки таблицы представляют собой весь форум. Каждый столбец таблицы forums представляет один элемент данных для каждого из форумов. Столбец id_forum содержит уникальный идентификатор форума, столбец name содержит название форума и столбец description содержит краткое описание проблемы, обсуждаемой на форуме. Кратко особенности реляционной базы данных можно описать следующим образом:
Запросы к базе данных возвращают результат в виде таблиц, которые тоже могут выступать как объект запросов. ИндексыИндекс - это отсортированный список значений полей, предназначенный для ускорения поиска в базе данных. Интересны, как правило, не сами индексы, а уникальные индексы. Уникальный индекс представляет собой список значений, в котором каждое значение уникально. К примеру, в таблице базы данных, содержащей паспортные данные уникальный индекс можно создать для поля "номер паспорта", поскольку каждый такой номер является единственным в своём роде. А вот дата рождения уже не уникальна, поэтому индекс по полю "Дата рождения" не может быть уникальным. Возвращаясь к нашей базе данных Forum, нужно заметить, что дата добавления сообщения в форум также не является уникальной, так как несколько участников форума могут добавить свои сообщения одновременно. Первичные ключиПервичный ключ (primary key) представляет собой один из примеров уникальных индексов и применяется для уникальной идентификации записей таблицы. Никакие из двух записей таблицы не могут иметь одинаковых значений первичного ключа. Первичный ключ обычно сокращенно обозначают как PK (primary key). Как мы уже говорили, в реляционных базах данных практически всегда разные таблицы логически связаны друг с другом. Первичные ключи как раз используются для однозначной организации такой связи. К примеру, в базе данных Forum таблицы themes и posts связаны между собой следующим образом: ![]() Первичным ключом таблицы themes является id_theme, а таблицы posts - id_post. Обратите внимание, что поле id_theme присутствует и в таблице posts. Каждое значение этого поля в таблице posts является внешним ключом (в данном случае это внешний ключ для первичного ключа таблицы themes). Внешний ключ сокращенно обозначают как FK (foreign key).Как видно из рис.1, внешний ключ ссылается на первичный ключ таблицы themes, устанавливая однозначную логическую связь между записями таблиц themes и posts. Иначе говоря, если внешний ключ для записи (сообщения) с PK=1 в таблице posts имеет значение внешнего ключа равное 1, то это значит, что это сообщение относится к теме с PK=1 таблицы themes. Способы задания первичного ключаПо способу задания первичных ключей различают логические (естественные) ключи и суррогатные (искусственные). Для логического задания первичного ключа нужно выбрать в базе данных то, что естественным образом определяет запись. Примером такого ключа является номер паспорта в базе данных о паспортных данных жителей. Если подходящих примеров для естественного задания первичного ключа не находится, пользуются суррогатным ключом. Суррогатный ключ представляет собой до-полнительное поле в базе данных, предназначенное для обеспечения записей первичным ключом. СоветДаже если в базе данных содержится естественный первичный ключ, лучше использовать суррогатные ключи, поскольку их применение позволяет абстрагировать первичный ключ от реальных данных. В этом случае облегчается работа с таблицами, поскольку суррогатные ключи не связаны ни с какими фактическими данными этой таблицы. Первичному ключу можно присвоить атрибут auto_increment, позволяющий автоматически генерировать уникальный ключ, если его тип является целочисленным. При вставке записи в базу данных значение ключа выставляется равным нулю, MySQL автоматически вычисляет максимальный номер первичного ключа, увеличивает его на единицу и присваивает это значение первичному ключу новой записи. Нормализация базы данныхСхемой базы данных называется структура связей между полями и таблицами. Нормализацией схемы базы данных называется процедура, производимая над базой данных с целью удаления в ней избыточности. Нормализация несет с собой немало преимуществ. Очевидно, что в нормализованной базе данных уменьшается вероятность возникновения ошибок, она занимает меньше места на жестком диске и т.д. Для того, чтобы лучше уяснить приведенное определение нормализации, рассмотрим следующий пример. Ниже показана таблица, в которой указаны фамилии сотрудников и их профессии: Таблица 3. Пример избыточности в таблицах базы данных
Эта таблица избыточна - для каждого из сотрудников повторяются одинаковые названия профессий. Т.е. схема такой базы данных не нормализована. Для небольшой базы данных это не критично, но в больших по объёму базах данных это скажется на размере базы и, в конечном счёте, на скорости доступа. Для нормализации необходимо разбить эту таблицу на две - для профессий (см. табл. 4) и для фамилий сотрудников (см. табл. 5). Таблица 4. Таблица профессий
Таблица 5. Таблица сотрудников
Теперь каждый тип профессии обозначен уникальным числом, и строка в базе данных присутствует только в единственном экземпляре: в таблице профессий. Размер поля "профессия" уменьшился, так как строка занимает больше памяти, чем число. ЗамечаниеВ теории баз данных говорится о том, что схема базы данных должна быть полностью нормализована. При работе с полностью нормализованными базами данных необходимо применять весьма сложные SQL-запросы, что приводит к обратному эффекту - замедлению работы базы данных. Поэтому иногда для упрощения запросов даже прибегают к обратной процедуре - денормализации. Работа с сервером MySQLВ этом разделе мы поговорим о том, как работать с клиентской программой mysql, с помощью которой можно подсоединяться к MySQL-серверу, выполнять SQL-запросы и просматривать результаты этих запросов. Текст этого раздела рассчитан на то, что на вашем компьютере уже установлена утилита mysql и существует связь с сервером MySQL. При подключении к серверу MySQL с помощью программы mysql нужно ввести имя пользователя, и, как правило, пароль. Если сервер и клиент находятся на разных машинах, необходимо также указать имя хоста, на котором запущен сервер MySQL: shell> mysql -h host -u user -p После этого на экране появится запрос Enter password:, и вам нужно будет ввести свой пароль. Если соединение прошло нормально, то на экране появляется следующая информация и метка командной строки mysql>: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 459 to server version: Type 'help' for help. mysql> Появление метки Отсоединиться от сервера можно в любой момент, набрав команду mysql> QUIT Bye Кроме этого, разорвать соединение с сервером можно также, одновременно нажав клавиши ЗамечаниеКак правило, на только, что установленном MySQL на локальной машине доступ осуществляется без ввода пароля и хоста, вводом команды mysql в командной строке. После того, как вы подсоединитесь к серверу, для того, чтобы освоиться с синтаксисом команд, можно выполнить несколько простых запросов. Поскольку пока еще никакой базы данных не выбрано, приводимые ниже запросы носят общий характер. Ниже приведена простая команда, запрашивающая у сервера информацию об его версии и текущей дате: mysql> SELECT VERSION(), CURRENT_DATE; Ответом MySQL на этот запрос будет следующая таблица: +--------------+--------------------+ | version() | current_date | +--------------+--------------------+ 1 row in set (0.02 sec) На примере выполнения этого запроса можно увидеть следующие основные особенности работы с MySQL:
Заметим, что команды MySQL не чувствительны к регистру, поэтому приведенные ниже запросы абсолютно идентичны: mysql> select version(), current_date; mysql> SELECT VERSION(), CURRENT_DATE; mysql> Select Version(), Сurrent_DATE; MySQL позволяет на одной строчке разместить несколько команд, но каждая из них должна заканчиваться точкой с запятой. К примеру: mysql> SELECT VERSION(); SELECT NOW(); На такой запрос мы получим следующий результат: +---------------+ | version() | +---------------+ | 4.0.13-nt | +---------------+ 1 row in set (0.00 sec) +----------------------+ | NOW() | +----------------------+ | 2004-01-25 16:57:00 | +----------------------+ 1 row in set (0.03 sec) Однако помещать все команды на одной строке совершенно необязательно: mysql> SELECT USER(), -> CURRENT_DATE; И вот результат: +-------------------------+---------------------+ | user() | current_date | +-------------------------+---------------------+ | ODBC@localhost | 2004-01-25 | +-------------------------+---------------------+ 1 row in set (0.00 sec) Заметьте, что после того, как мы перешли на новую строку, метка командной строки изменилась с mysql> select user() -> В завершение этого раздела, продемонстрируем, как можно использовать MySQL в качестве простого калькулятора, введя, к примеру, такой запрос: mysql> select cos(pi()/10), (2*5)-5; Язык SQLСтруктурированный язык запросов SQL позволяет производить различные операции с базами данных: создавать таблицы, помещать, обновлять и удалять из них данные, производить запросы из таблиц и т.д. Далее мы последовательно рассмотрим все эти операторы. ЗамечаниеНе смотря на то, что последний стандарт SQL принят в 1992 году, на сегодняшний день нет ни одной базы данных, где бы он полностью выполнялся. Более того, в различных базах данных часть операций осуществляется по-разному. Мы будем придерживаться диалекта SQL характерного для СУБД MySQL поэтому не все запросы могут выполняться для других баз данных. Команды SQL
В этом разделе мы изучим основные команды языка SQL. Для этого на компьютере с установленным MySQL необходимо запустить клиента mysql, в окне которого можно вводить команды SQL. Примечание Команды SQL не чувствительны к регистру, но традиционно они набираются прописными буквами. Типы полей базы данныхСписок наиболее часто встречающихся типов приведен в таблицах 13.6 - 13.8. Для многих типов данных задается максимальная ширина отображения, указываемая в скобках, которую мы далее будем обозначать символом max. К примеру, запись INT(2) означает, что значение данного поля не может превышать 100. К числовым типам относятся целые числа и числа с плавающей точкой. Для чисел с плавающей точкой, кроме максимальной ширины отображения можно также указывать число значащих цифр после запятой, далее обозначаемое символом P. Таблица 13.6. Числовые типы
Типы даты и времени приведены в таблице 13.7. Таблица 13.7. Типы даты и времени
Основные строковые типы приведены в таблице 13.8. Таблица 13.8. Строковые типы
CREATE DATABASEЭта команда создает новую базу данных: CREATE DATABASE db_name; Здесь mysql> CREATE DATABASE forum; Примечание Каждый запрос MySQL завершается точкой с запятой. При успешном выполнении команды MySQL выдаст строку, в которой сообщается, что этот запрос выполнен успешно и показано время, затраченное на выполнение запроса: Query OK, 1 row affected (0.02 sec) Далее в тексте строку MySQL с результатом выполнения команды мы будем приводить непосредственно в соответствующем листинге. Для того, чтобы убедится, что база данных forum успешно создана, можно выполнить команду mysql> SHOW DATABASES; Как видим, среди различных баз данных на компьютере автора присутствует и только что созданная база данных ![]() Замечание Команда Замечание Изначально, в МуSQL присутствует только две базы данных: USEДля того чтобы начать работу с таблицами, необходимо сообщить MySQL с какой базой данных вы намерены работать. Это осуществляется при помощи команды USE db_name; Здесь mysql> CREATE DATABASE forum; Database changed; CREATE TABLEКоманда CREATE TABLE table_name [(create_definition, ...)] Здесь Создадим первую таблицу базы данных mysql> CREATE TABLE authors ( id_author int(6) NOT NULL auto_increment, name text, passw text, email text, url text, iсq text, about text, photo text, time datetime default NULL, last_time datetime default NULL, themes int(10) default NULL, statususer int(2) default NULL, PRIMARY KEY (id_author) ) TYPE=MyISAM; Выполнив SQL-команду ![]() Давайте теперь аналогичным образом создадим другие таблицы. Следующей по порядку идет таблица forums, в которой содержатся данные о разделах форума. Примечание Для удобства на форуме может быть создано несколько различных разделов. К примеру, на форуме по языкам программирования для того, чтобы не смешивать темы, относящиеся к различным языкам, имеет смысл создать следующие разделы: С++, PHP, Java и т. д. В таблице Вот SQL-запрос, создающий таблицу mysql> CREATE TABLE forums ( id_forum int(6) NOT NULL auto_increment, name text, rule text, logo text, pos int(6) default NULL, hide int(1) default NULL, PRIMARY KEY (id_forum) ) TYPE=MyISAM; Структура форума может быть следующей: имеются список разделов, переход по которым приводит посетителя к списку тем раздела. При переходе по теме посетитель приходит к обсуждению этой темы, состоящих из сообщений других посетителей. Теперь создадим таблицу mysql> CREATE TABLE themes ( id_theme int(11) NOT NULL auto_increment, name text, author text, id_author int(6) default NULL, hide int(1) default NULL, time datetime default NULL, id_forum int(2) default NULL, PRIMARY KEY (id_theme) ) TYPE=MyISAM; В таблице В таблице Создадим последнюю таблицу mysql> CREATE TABLE posts ( id_post int(11) NOT NULL auto_increment, name text, url text, file text, author text, id_author int(6) default NULL, hide int(1) default NULL, time datetime default NULL, parent_post int(11) default NULL, id_theme int(11) default NULL, PRIMARY KEY (id_post) ) TYPE=MyISAM; В таблице Убедимся, что все таблицы успешно созданы, выполнив команду ![]() DESCRIBEКоманда DESCRIBE tаble_name Здесь Замечание Команда Давайте посмотрим, к примеру, структуру таблицы mysql> DESCRIBE forums; После выполнения этой команды, интерпретатор mysql выведет следующую таблицу ![]() ALTER TABLEКоманда ALTER TABLE table_name alter_spec Параметр alter_spec имеет значения, представленные в таблице
Добавим в таблицу mysql> ALTER TABLE forums ADD test int(10) AFTER name; Выполнив команду ![]() Давайте переименуем созданный столбец mysql> ALTER TABLE forums CHANGE test new_test text; Как видно из рисунка, столбец успешно переименован: ![]() При изменении только типа столбца, а не его имени, указание имени все-равно необходимо, хотя в этом случае оно будет фактически повторяться. mysql> ALTER TABLE forums CHANGE new_test new_test int(5) not null; Результат выполнения этого запроса приведен на рисунке: ![]() Теперь удалим столбец mysql> ALTER TABLE forums DROP new_test; Как видно из рисунка, после удаления этого столбца таблица ![]() DROP TABLEКоманда DROP TABLE table_name [ ,table_name,...] К примеру, для удаления таблицы mysql> DROP TABLE forums; DROP DATABASEКоманда DROP DATABASE database_name Удалим, например, базу данных mysql> DROP DATABASE forum; INSERT INTO…VALUESКоманда INSERT INTO table_name VALUES (values,…) После оператора Давайте вставим в базу данных mysql> INSERT INTO authors VALUES (1, 'Maks', '123', ' maks@mail.ru ', ' www.softtime.ru ', '', 'программист', '', '', '', 0, 0); mysql> INSERT INTO authors VALUES (2, 'Igor', '123', 'igor@mail.ru', 'http://www.softtime.ru', '', 'Программист', '', '', '', 407, 0); mysql> INSERT INTO authors VALUES (3, 'Sergey', '212', 'sergey@mail.ru', 'http://www.softtime.ru', '', 'Дизайнер', '', '', '', 408, 0); DELETE
DELETE FROM table_name [WHERE definition] Команда Вот как можно удалить все записи из таблицы mysql> DELETE FROM authors; Важной частью запросов mysql> DELETE FROM authors WHERE id_author = 1; Условия отбора могут быть значительно сложнее, так в листинге 13.16 удаляются все авторы с паролем '123' и первичный ключ которых превышает 10: mysql> DELETE FROM authors WHERE passw = '123' AND id_author > 10; Оператор AND является логическим "и". В запросах можно так же применять логическое или "или". SELECTКоманда SELECT column,... [FROM table WHERE definition] [ORDER BY col_name [ASC | DESC], ...] [LIMIT [offset], rows] Здесь Давайте вставим в таблицу mysql> INSERT INTO forums VALUES (1, 'Форум1', '', '', 1, 0); mysql> INSERT INTO forums VALUES (2, 'Форум2', '', '', 2, 0); mysql> INSERT INTO forums VALUES (3, 'Форум3', '', '', 3, 0); mysql> INSERT INTO forums VALUES (4, 'Форум4', '', '', 4, 0); mysql> INSERT INTO forums VALUES (5, 'Форум5', '', '', 5, 0); Для того чтобы посмотреть всю таблицу mysql> SELECT * FROM forums; Выбираем все столбцы из таблицы forums без ограничений. Результат показан на рисунке: ![]() Можно выбрать не все столбцы таблицы, а лишь часть, для этого необходимо явно задать список выбираемых столбцов: mysql> SELECT id_forum, name FROM forums; В этом случае MySQL выведет лишь два столбца с первичным ключом ![]() Оператор mysql> SELECT * FROM forums LIMIT 3; В результате этого запроса будет выведено только первые 3 записи из 5 ![]() Оператор mysql> SELECT * FROM forums LIMIT 1,3; В этом случае будут возвращены строки 2, 3 и 4 ![]() Оператор mysql> SELECT * FROM forums WHERE id_forum > 2; Результат показан на слудующем рисунке: ![]() Порядок сортировки выводимых записей можно задавать при помощи оператора mysql> SELECT * FROM forums WHERE id_forum > 2 ORDER BY pos; В этом запросе выводятся все записи со значением поля ![]() UPDATE
UPDATE table SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE definition] [LIMIT rows] Команда В следующим листинге разделу форума с первичным ключом 2 устанавливается новое название (PHP) и устанавливается атрибут UPDATE forums SET name='PHP', hide=1 WHERE id_forum=2; SHOWС этой командой мы уже встречались ранее, когда выполняли запросы вида Вывести список всех столбцов выбранной таблицы можно при помощи следующего запроса: mysql> SHOW FIELDS FROM authors; Результат приведен на следующем рисунке: ![]() Можно также отобразить информацию обо всех индексах конкретной таблицы: mysql> SHOW INDEX FROM authors; Выполнив команду ![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||