
web - tec / PHP 5 для начинающи
.pdf
Введение в базы данных и SQL 413
Добавим в таблицу user новое поле типа ENUM с именем sex. Данное поле можно будет использовать для записи пола пользователя:
mysql> ALTER TABLE user ADD sex ENUM('M', 'F') DEFAULT 'M'; Query OK, 0 rows affected (0.24 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC user; |
|
|
|
|
|
|
+---------------- |
+--------------------- |
+------- |
+----- |
+--------- |
+----------- |
+ |
| Field |
| Type |
| Null |
| Key | Default |
| Extra |
| |
|
+---------------- |
+--------------------- |
+------- |
+----- |
+--------- |
+----------- |
+ |
| ... |
| |
| |
| |
| |
| |
| |
| sex |
| enum('M','F') |
| YES |
| |
| M |
| |
| |
+---------------- |
+--------------------- |
+------- |
+----- |
+--------- |
+----------- |
+ |
10 rows in set (0.00 sec)
Новое поле добавляется в таблицу как последнее поле. Чтобы вставить новое поле между другими полями, используется ключевое слово AFTER. Теперь удалим только что созданное поле:
mysql> ALTER TABLE user DROP sex; Query OK, 0 rows affected (0.08 sec) Records: 0 Duplicates: 0 Warnings: 0
Чтобы вставить новое поле sex сразу после поля username, можно ввести сле+ дующую команду:
mysql> ALTER TABLE user ADD sex ENUM('M', 'F') DEFAULT 'M' AFTER username; |
|
|||||
Query OK, 0 rows affected (0.09 sec) |
|
|
|
|
|
|
Records: 0 Duplicates: 0 Warnings: 0 |
|
|
|
|
|
|
mysql> desc user; |
|
|
|
|
|
|
+--------------- |
+---------------------- |
+------ |
+----- |
+------------ |
+----------- |
+ |
| Field |
| Type |
| Null |
| Key | Default |
| Extra |
| |
|
+--------------- |
+---------------------- |
+------ |
+----- |
+------------ |
+----------- |
+ |
| ... |
| |
| |
| |
| |
| |
| |
| sex |
| enum('M','F') |
| YES |
| |
| M |
| |
| |
+--------------- |
+---------------------- |
+------ |
+----- |
+------------ |
+----------- |
+ |
10 rows in set (0.00 sec)
Чтобы поместить новое поле в начало списка полей, вместо ключевого слова AFTER необходимо использовать ключевое слово FIRST, так как предшествующих по+ лей в этом случае нет.
Если сайт адресован женщинам, вероятно, значение по умолчанию для поля sex следует изменить с M на F:
mysql> ALTER TABLE user ALTER sex SET DEFAULT 'F'; Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
Для полного изменения определения поля используется ключевое слово MODIFY:
mysql> ALTER TABLE user MODIFY userprofile VARCHAR(250) NOT NULL -> DEFAULT 'No Comment';
Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0
Чтобы изменить имя и определение поля, можно использовать ключевое слово
CHANGE:
mysql> ALTER TABLE user CHANGE userposition playerposition VARCHAR(50) NOT NULL;
Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0




Введение в базы данных и SQL 417
Резюме
Вданной главе рассматривались модели хранения информации, базы данных
инаиболее жизнеспособные варианты хранения больших массивов данных, а также был дан краткий обзор преимуществ систем управления реляционными базами данных (СУРБД). Кроме того, в главе обсуждались такие проблемы, как производительность, работоспособность и безопасность. В главе объясняется, почему свободно доступная СУРБД MySQL является серьезным кандидатом для применения в большинстве при+ ложений, использующих базы данных.
Еще раз кратко опишем преимущества реляционных баз данных с клиент/сервер+ ной архитектурой (которую поддерживают не все СУРБД):
производительность: нормализация баз данных значительно увеличивает про+ изводительность;
многопользовательская среда: единственным ограничением, налагаемым на коли+ чество одновременно подключающихся пользователей, является тип приобретен+ ной лицензии и/или производительность имеющегося аппаратного обеспечения;
доступность: сетевая СУРБД может обрабатывать запросы ‘‘в реальном времени’’, в любое время делая доступными актуальные данные; иначе говоря, при необхо+ димости к такой базе данных можно получить доступ отовсюду и в любой момент;
безопасность: жизненно важным является управление доступом к данным по+ средством хорошо организованной схемы обеспечения безопасности; напри+ мер, система MySQL не предоставляет непосредственный доступ к каким+либо сохраненным в ней данным, обеспечивая таким образом безопасность инфор+ мации на более высоком по сравнению с операционной системой уровне; поль+ зователь, не имеющий необходимых привилегий, не может выполнять несанк+ ционированные операции с данными;
надежность: когда речь идет о программном обеспечении, степень надежности, как правило, измеряется частотой таких отказов продукта в течение срока службы, которые требуют перезапуска; например, MySQL порождает дочерние процессы для обработки одновременных запросов; когда дочерний процесс ра+ ботает неверно и в конечном итоге останавливается, он редко тянет за собой весь сервер баз данных, таким образом, сводя к минимуму свое влияние на це+ лостность данных в базе.
Подведем итог: планируя разработку целевых многопользовательских Web+прило+ жений, в качестве сервера для хранения данных стоит рассматривать сетевую СУРБД.
В этой главе также рассматривалась установка MySQL+сервера и основы SQL ++++++
языка структурированных запросов, на котором основана система MySQL. В главе описывались некоторые основные SQL+запросы ++++++ SELECT, INSERT, REPLACE, DELETE и UPDATE, а также права доступа в MySQL.
Любой сценарий, в котором для подключения к MySQL+серверу используются PHP+ функции, позволяет выбрать определенную информацию в базах данных сервера. В главе описывалось несколько способов для обработки ошибок, возникающих в MySQL+сервере; рассматривалось создание и модификация таблиц с помощью SQL+ операторов, а также заполнение таблиц в базе данных информацией, которую можно будет использовать в последующих главах.

10
Получение данных от MySQL с помощью PHP
До сих пор основное внимание в книге уделялось проверке соединения с MySQL либо через клиентскую программу, либо посредством MySQL+функций PHP, а также созданию таблиц и заполнению их данными. Одним из первых SQL+операторов, ко+ торые описывались в главе 9, был базовый оператор SELECT. Чтобы точно опреде+ лить, какие данные должна возвращать база, можно использовать множество других операторов. В этой главе описываются способы получения доступа к данным, храня+ щимся в MySQL+базе данных, из PHP+сценариев.
Вначале следует рассмотреть PHP+функции, предназначенные для получения данных,
азатем изучить методику формирования SQL+операторов SELECT, позволяющих получить доступ к необходимым данным, упорядоченным так, как нужно для работы приложения.
Затем будет рассмотрена возможность ограничения количества возвращаемых ре+ зультатов, а также их упорядочение и группировка. Кроме того, в учебных примерах данной главы создается сценарий для просмотра пользовательских записей, позво+ ляющий просматривать таблицы созданной в предыдущей главе базы данных.
Получение данных с помощью PHP
При использовании SELECT+операторов с функцией mysql_query() результи+ рующее множество (которое также можно отобразить в командной строке mysql) пе+ редается в память, и возвращается идентификатор результата. Обычно этот иденти+ фикатор сохраняется в переменной, например, $result, и используется для указания результирующего множества в последующих вызовах функций.
Ранее уже было показано, как функция mysql_fetch_row() возвращает одну строку из результирующего множества. В простом примере из предыдущей главы ис+ пользуется цикл while для поочередного вывода каждой строки результирующего

Получение данных от MySQL с помощью PHP 419
множества, созданного оператором SHOW DATABASES. Ниже приводится усовершен+ ствованная версия сценария show_db.php, которая распечатывает информацию из таблицы user базы данных sample_db:
<?php include "./common_db.inc";
$link_id = db_connect('sample_db');
$result = mysql_query("SELECT * FROM user", $link_id);
while($query_data = mysql_fetch_row($result)) {
echo "'",$query_data[1],"' - ",$query_data[4],"<br>";
}
?>
Сценарий возвращает следующий вывод:
'Nicrot' - Mid
'Spargy' - Mid
'Pads' - Winger
'Dodge' - Link
'Mac' - Winger 'Greeny' - Utility back
Сначала сценарий подключается к серверу с помощью функции db_connect (которая определена в подключаемом файле common_db.inc), указывая необходимую базу данных sample_db. Затем выполняется SQL+оператор “SELECT * FROM user”, результи+ рующее множество которого представляет собой все содержимое таблицы user.
В переменной $result хранится возвращаемый идентификатор результата, с по+ мощью которого в вызове функции mysql_fetch_row() указывается результирую+ щее множество. Данная функция в свою очередь выбирает первую строку результата, из которой затем выводятся второе и четвертое поля (userid и userposition, со+ ответственно). После этого внутренний указатель перемещается к следующей строке результата, а цикл while продолжается до тех пор, пока не будут выбраны все содер+ жащиеся в таблице строки.
Достичь того же результата можно более эффективным способом:
$result = mysql_query("SELECT userid, userposition FROM user", $link_id);
while($query_data = mysql_fetch_row($result)) {
echo "'",$query_data[0],"' - ",$query_data[1],"<br>";
}
Извлекая из таблицы только те поля, которые нужны, можно сэкономить время
ипамять.
ВPHP имеется еще две функции, которые можно использовать для выборки дан+ ных: mysql_fetch_array и mysql_fetch_object(). Обе они работают в основном аналогично функции mysql_fetch_row(), единственное отличие заключается в ти+ пе возвращаемых данных. Лучше всего это можно проиллюстрировать на примере кода для выборки значений из результирующего множества.
Функция mysql_fetch_array()() возвращает из результирующего множества один ассоциативный массив, сохраняя каждое значение в элементе, имя которого со+ ответствует имени поля:
while($query_data = mysql_fetch_array($result)) { echo "'",$query_data["userid"],"' - ", $query_data["userposition"],"<br>";
}

420 Глава 10
Функция mysql_fetch_object() возвращает один объект из результирующего множества, сохраняя каждое значение как свойство данного объекта. Свойства име+ нуются согласно именам полей:
while($query_data = mysql_fetch_object($result)) { echo "'",$query_data->userid,"' - ", $query_data->userposition,"<br>";
}
Две эти функции особенно полезны в ситуациях, когда необходимо изменить структуру таблиц базы данных. Если не изменять имена полей, то можно не беспоко+ иться о порядке, в котором они появляются в таблице, потому что можно извлечь значение поля, указав его имя, а не индекс. Хотя обе функции работают медленнее, чем mysql_fetch_row(), они обладают одним дополнительным преимуществом ++++++
эти функции делают сценарии более читабельными (например, впоследствии в коде большого приложения можно перепутать поля, если указывать только их индексы).
Существует еще одна функция, заслуживающая внимания: mysql_result(), кото+ рая возвращает значение определенного поля в определенной записи. В качестве ар+ гументов данная функция принимает, как обычно, идентификатор результата, а также номер строки и имя поля. Можно переписать приведенный выше пример так:
$result = mysql_query("SELECT * FROM user", $link_id);
for($i =0; $i < mysql_num_rows($result); $i++){
echo "'", mysql_result($result, $i, "userid"),"' - ", mysql_result($result, $i, "userposition"),"<br>";
}
Можно также выводить значения в обратном порядке:
$result = mysql_query("SELECT * FROM user", $link_id);
for($i = mysql_num_rows($result)-1; $i >=0; $i--){
echo "'", mysql_result($result, $i, "userid"),"' - ", mysql_result($result, $i, "userposition"),"<br>";
}
В этом случае результирующее множество будет таким:
'Greeny' - Utility back 'Mac' - Winger
'Dodge' - Link
'Pads' - Winger
'Spargy' - Mid
'Nicrot' - Mid
Имя поля также можно указать в виде целого числа, представляющего смещение поля:
echo "'", mysql_result($result, $i, 1),"' - ", mysql_result($result, $i, 3),"<br>";
Другой способ перемещения к заданной строке данных заключается в использова+ нии функции mysql_data_seek(). Она работает аналогично функции fseek(), ко+ торая использовалась в примерах главы 7 для навигации в файловом потоке. Эта функция в качестве аргументов принимает дескриптор результата и целое число, представляющее позицию в результирующем множестве, к которой необходимо пе+ рейти. Как можно предположить, данная функция возвращает True в случае успешно+ го перемещения и False при переходе за границу массива. Сохраните следующий код в файле show_seek.php и откройте его в браузере:

Получение данных от MySQL с помощью PHP 421
<?php
include "./common_db.inc";
$link_id = db_connect('sample_db');
$result = mysql_query("SELECT * FROM user", $link_id);
for($i = mysql_num_rows($result)-1; $i >=0; $i--){
mysql_data_seek($result, $i);
$query_data = mysql_fetch_array($result); echo "'", $query_data["userid"], "' - ", $query_data["username"], "<P>";
}
?>
В этом разделе были рассмотрены различные способы доступа к результирующему множеству из PHP+сценариев. Эти методики помогают найти решение в различных ситуациях и вывести необходимые данные, представленные в том порядке, который требуется. Однако это еще далеко не все.
Известно, что повысить эффективность сценариев можно путем сохранения не+ больших размеров результирующего множества. В приведенных примерах для этого указывались необходимые поля в исходном SELECT+операторе, например:
$result = mysql_query("SELECT userid, username FROM user", $link_id);
Однако при отображении результатов этого запроса в другом порядке могут воз+ никнуть некоторые проблемы. Допустим, что данные нужно выводить в обратном или в алфавитном порядке. Хлопот можно избежать, если упорядочить данные, посту+ пающие в результирующее множество. На самом деле существует множество вариан+ тов обработки данных, эффективность которых, как по времени выполнения, так и по сложности, почти наверняка будет выше, если использовать хорошо продуман+ ные SQL+запросы, а не специальные PHP+функции. По этой причине следует вернуть+ ся к mysql+клиенту и рассмотреть возможности, предоставляемые командой SELECT.
SQL-операторы для выборки данных
Рассмотрим команду SELECT подробнее. Обратите внимание, что все описывае+ мые здесь команды полностью применимы к предыдущим примерам с использовани+ ем PHP ++++++ таблица, отображаемая в командной строке, представляет собой просто эк+ ранное представление результирующего множества, с которым в конечном итоге должен работать PHP+сценарий.
Серверные функции
Вернемся к основам и попытаемся вводить SELECT+запросы, которые вообще не требуют наличия таблицы базы данных. MySQL обладает множеством весьма полез+ ных встроенных серверных функций. Например, чтобы узнать текущее время, можно ввести следующую команду:
mysql> SELECT now(); |
|
||
+---------------------------- |
|
|
+ |
| now() |
|
| |
|
+---------------------------- |
|
|
+ |
| 2004-08-03 |
16:56:03 |
| |
|
+---------------------------- |
|
|
+ |
1 |
row in set |
(0.00 sec) |
|
