MySQL - свободная система управления базами данных(СУБД). MySQL является собственностью компании Oracle Corporation, получившей её вместе с поглощённой Sun Microsystems, осуществляющей разработку и поддержку приложения. Распространяется под GNU General Public License или под собственной коммерческой лицензией. Помимо этого разработчики создают функциональность по заказу лицензионных пользователей, именно благодаря такому заказу почти в самых ранних версиях появился механизм репликации.
MySQL является решением для малых и средних приложений. Входит в состав серверов WAMP, AppServ, LAMP и в портативные сборки серверов Денвер, XAMPP. Обычно MySQL используется в качестве сервера, к которому обращаются локальные или удалённые клиенты, однако в дистрибутив входит библиотека внутреннего сервера, позволяющая включать MySQL в автономные программы.
База данных - это структурированная коллекция записей или данных, хранящихся в компьютерной системе и организованных так, что можно осуществлять быстрый поиск и извлечение нужной информации.
В названии MySQL составляющая SQL означает Structured Query Language — язык структурированных запросов. Если характеризовать его в общих чертах, то это язык, основанный на словах английского языка и используемый также в других системах управления базами данных, например Oracle и Microsoft SQL Server. Он разработан для предоставления возможности создания простых запросов к базе данных.
В базе данных MySQL имеются одна или несколько таблиц, каждая из которых состоит из записей или строк. Внутри строк находятся разные столбцы или поля, в которых и содержатся данные.
Реляционная база данных - база данных, основанная на реляционной модели данных.
Реляционная база данных представляет собой набор связанных данных, хранящихся в таблицах.
Понятие «реляционный» основано на англ. relation («отношение», «зависимость», «связь»).
12 правил Кодда, которым должна удовлетворять каждая система управления реляционными базами данных.
SQL
SQL (Structured Query Language - Структурированный Язык Запросов) - язык манипулирований для реляционных баз данных.
Всемирно принятый стандарт для реляционных систем
ANSI X3.135-1992 "Database Langiage SQL"
ISO/IEC 9075:1992 "Database Langiage SQL"
ANSI - American National Standard Institute(Американский Институт Стандартизации) - центральный институт стандартизации США . Стандарт, принятый данным институтом, является рекомендуемым для других стран и обязательным для применения на территории США. Изделия, не удовлетворяющие условиям стандарта не могут быть использованы на территории США
Язык SQL является непроцедурным языком системы управления реляционной базой данных, который может обрабатывать записи группами и обеспечивает автоматический поиск нужных данных.
Непроцедурный язык - язык у которого отсуствует возможность управления последовательностью действий.
SQL по существу изобретение IBM. Но другие компании подхватили SQL сразу же. После того как появился ряд конкурирующих программ SQL на рынке, ANSI определил стандарт к которому они должны быть приведены (определение таких стандартов и является функцией ANSI). Однако после этого, появились некоторые проблемы. Возникли они в результате стандартизации ANSI в виде некоторых ограничений. Так как не всегда ANSI определяет то, что является наиболее полезным, то программы пытаются соответствовать стандарту ANSI не позволяя ему ограничивать их слишком сильно. Это, в свою очередь, ведет к случайным несогласованности. Программы баз данных обычно дают ANSI SQL дополнительные особенности и часто ослабляют многие ограничения из большинства из них. Удачные идеи имеют тенденцию к внедрению и использованию в различных программах даже когда они не определены стандартом ANSI. ANSI - это вид минимального стандарта и вы можете делать больше чем он позволяет.
SQL является прежде всего информационно-логическим языком, предназначенным для описания, изменения и извлечения данных, хранимых в реляционных базах данных.
Изначально SQL был основным способом работы пользователя с базой данных и позволял выполнять следующий набор операций
создание в базе данных новой таблицы
добавление в таблицу новых записей
изменение записей
удаление записей
выборка записей из одной или нескольких таблиц (в соответствии с заданным условием)
изменение структур таблиц
Со временем SQL усложнился обогатившись новыми конструкциями, обеспечил возможность описания и управления новыми хранимыми объектами.
При всех своих изменениях SQL остаётся единственным механизмом связи между прикладным программным обеспечением и базой данных. В то же время современные СУБД, а также информационные системы, использующие СУБД, предоставляют пользователю развитые средства визуального построения запросов.
Синтаксис
Синтаксис SQL читается подобно естественным языкам. Утверждения начинаются с глагола, описывающего действие, далее следует субъект и предикат.
SELECT
id FROM student
WHERE name='Ivan';
глагол
субъект
предикат
Субъект - это мысль о каком-то предмете, понятие о предмете суждения (логическое подлежащее).
Предикат - мысль об известной части содержания предмета, которое рассматривается в суждении (логическое сказуемое).
Заметно, что оператор читается как нормальное предложение. SQL был задуман, как легкий и понятный язык для работы непрограммистов.
-- Пример выборки ФИО и возраста из таблицы покупателей
SELECT fio, age FROM customer;
Пример таблицы БД
id
fio
address
phone
age
12
Иванов И.И.
г.Городец
89564534568
18
15
Петров П.П.
г.Заволжье
89601236578
26
22
Сидоров С.С.
рп.Сокольское
89302135461
35
80
Ткачёв Т.Т.
д.Повалихино
89012534785
51
-- Результат выборки
+-------------+----+
| Иванов И.И. | 18 |
| Петров П.П. | 26 |
| Сидоров С.С.| 35 |
| Ткачёв Т.Т. | 51 |
+-------------+----+
-- Добавили предикат
SELECT fio, age FROM customer WHERE age < 30;
+-------------+----+
| Иванов И.И. | 18 |
| Петров П.П. | 26 |
+-------------+----+
В давние дни предполагалось, что SQL будут использовать непрограммисты для выполнения разовых запросов и генерации отчетов, несмотря на то, что сейчас им пользуются исключительно разработчики и администраторы баз данных.
Каждое "предложение" SQL - это либо запрос данных из базы, либо обращение к базе данных, которое приводит к изменению данных в базе.
Операторы
Текст на языке SQL представляет собой последовательность операторов. Операторы обычно разделяются символом точка-с-запятой, который отмечает конец запроса.
Операторы, в свою очередь, составляются из серии лексем. Лексемы могут быть константами, ключевыми словами, идентификаторами, выражениями или специальными символами. Лексемы разделяются пробельными символами (пробел, табуляция, символ новой строки).
Операторы SQL делятся на
Операторы определения данных
CREATE
создает объект БД (саму базу, таблицу, представление, пользователя и т. д.)
ЗАПРЕЩЕНО использовать в качестве имён столбцов и таблиц зарезервированные слова
К зарезервированным словам относятся слова, использующиеся в качестве названия функций и типов данных. Некоторые слова разрешены в качестве имён для столбов и таблиц, но запрещены в ANSI SQL, как правило это слова естественного языка, уже пользующиеся многими потребителями, т.е. запретить их полностью будет болезненно для многих систем, эти слова: ACTION, BIT, DATE, ENUM, NO, TEXT, TIME и TIMESTAMP.
Операции
Оператор
Описание
+
Операция сложения
-
Операция вычитания / отрицания
*
Операция умножения
/
Операция деления
%
Остаток от деления
=
Сравнение на равно
<
Меньше
<=
Меньше или равно
<>
Не равно
>
Больше
>=
Больше или равно
--
Комментарии на одной строке
#
Комментарии на одной строке
/* */
Многострочные комментарии
;
Завершение команды SQL
OR
Логическое ИЛИ
AND
Логическое И
NOT
Логическое НЕ
SELECT name FROM customer WHERE age>18 AND age<35;
-- Результат выборки
+-------------+----+
| Петров П.П. | 26 |
+-------------+----+
Типы данных
Данные хранятся в БД в виде таблиц, состоящих из столбцов и строк. В таблице с одним столбцом можно хранить одномерный список. Таблица с несколькими столбцами хранит информацию, для которой имеет значение сочетание строк и столбцов.
Каждый столбец представляет собой один атрибут строки. Каждая строка таблицы содержит одну запись. Один или несколько столбцов таблицы могут быть первичными, внешними или уникальными ключами. На таблицы и столбцы ссылаются, используя их имена.
MySQL - реляционная СУБД, которая поддерживает несколько типов данных, которые можно разделить на три категории: числовые данные, дата и время, и данные типа строка.
Тип данных
Использование
Диапазоны
TINYINT
Очень маленькое целое число
Диапазон числа со знаком от –128 до 127. Диапазон числа без знака (unsigned) от 0 до 255.
SMALLINT
Маленькое целое число
Диапазон числа со знаком от –32768 до 32767. Диапазон числа без знака (unsigned) от 0 до 65535.
MEDIUMINT
Среднее целое число
Диапазон числа со знаком от –8388608 до 8388607. Диапазон числа без знака (unsigned) от 0 до 16777215.
INT или INTEGER
Целое число
Диапазон числа со знаком от –2147483648 до 2147483647. Диапазон числа без знака (unsigned) от 0 до 4294967295.
BIGINT
Большое целое число
Диапазон числа со знаком от –9223372036854775808 до 9223372036854775807. Диапазон числа без знака (unsigned) от 0 до 18446744073709551615.
FLOAT
Малое (одинарной точности) число с плавающей запятой. Не может быть числом без знака
Диапазоны от –3.402823466E+38 до –1.175494351E-38, 0 и 1.175494351E-38 до 3.402823466E+38. Если количество знаков после запятой не установлено или <= 24 это число с плавающей запятой одинарной точности.
DOUBLE, DOUBLEPRECISION, REAL
Нормальное (двойной точности) число с плавающей запятой. Не может быть числом без знака
Диапазоны от -1.7976931348623157E+308 до -2.2250738585072014E-308, 0 и 2.2250738585072014E-308 до 1.7976931348623157E+308. Если количество знаков после запятой не установлени или 25 <= количество знаков <= 53 означает числоа с плавающей запятой двойной точности.
DECIMAL, NUMERIC
Распакованное число с плавающей запятой
Работает подобно типу данных CHAR: «распакованный» означает, что число хранится в виде строки, используя один символ для каждой цифры-значения. Символ десятичной запятой и символ отрицательного числа "-" не учитывается в длину. Если десятичное значение равно 0, значение не будет иметь десятичной запятой или дробной части. Максимальный размер для DECIMAL значение такое же, как и для DOUBLE, но фактический диапазон для данного столбца DECIMAL может быть ограничен в выборе длины и десятичные дроби.
DATE
Дата
Дата в диапазоне от «1000-01-01» до «9999-12-31». MySQL хранит поле типа DATE в виде «YYYY-MM-DD» (ГГГГ-ММ-ДД).
DATETIME
Дата и время
Допустимые диапазоны от «1000-01-01 00:00:00» до «9999-12-31 23:59:59». MySQL хранит поле типа DATETIME в виде «YYYY-MM-DD HH:MM:SS» (ГГГГ-ММ-ДД ЧЧ-ММ-СС).
TIMESTAMP
Дата и время
Диапазон от «1970-01-01 00:00:00» до, примерно, 2037 года. MySQL может хранить поле типа TIMESTAMP в видах «YYYYMMDDHHMMSS» (TIMESTAMP(14)), «YYMMDDHHMMSS» (TIMESTAMP(12)), «YYYYMMDD» (TIMESTAMP(8)) и др.
TIME
Время
Диапазон от «-838:59:59» до «838:59:59». MySQL хранит поле TIME в виде «HH:MM:SS», но позволяет присваивать значения столбцам TIME с использованием либо строки или числа.
YEAR
Год в 2- или 4- хцифровом виде (4 цифры по-умолчанию)
Если вы используете 4 цифра, то допустимые значения 1901-2155, и 0000. Если 2 цифры, то 1970-2069 (70-69). MySQL хранит значения поля YEAR в формате «YYYY».
CHAR
Строка фиксированной длины, которая справа дополняются пробелами до указанной длины, при хранении
Диапазон длины от 1 до 255 символов. Завершающие пробелы удаляются, когда значение извлекается. Значения CHAR сортируются и сравниваются без учета регистра в зависимости от кодировки по умолчанию, если не установлен флаг BINARY.
VARCHAR
Строка переменной длины. Примечание: конечные пробелы удаляются при сохранении (в отличие от спецификации ANSI SQL).
Диапазон длины от 1 до 255 символов. Значения VARCHAR сортируются и сравниваются без учета регистра, если не установлен флаг BINARY.
TINYBLOB, TINYTEXT
BLOB или ТЕХТ с максимальной длиной 255 (2^8 - 1) символов.
BLOB, TEXT
BLOB или ТЕХТ с максимальной длиной 65535 (2^16 - 1) символов.
MEDIUMBLOB, MEDIUMTEXT
BLOB или ТЕХТ с максимальной длиной 16777215 (2^24 - 1) символов.
LONGBLOB, LONGTEXT
BLOB или ТЕХТ с максимальной длиной 4294967295 (2^32 - 1) символов.
ENUM
Перечисление
Строка-объект, который может принимать только одно значение, выбирается из списка значений «значение 1», «значение 2» или NULL. ENUM максимум может иметь 65535 различных значений.
SET
Набор
Строка-объект, который может принимать ноль и более значений, каждоу из которых должно быть выбрано из списка значений «значение 1», «значение 2», … Поле SET может иметь максимум 64 варианта значений.
Константы
Константами, так же называемые литералами, явно записываются величины. Выделяется три типа констант: строки, числа и двоичные значения. Строка - это одна или несколько символов в одинарных кавычках. Например:
'606345 ул.Геологов'
'Newman'
'Привет мир!!'
Для языка SQL стандартом является использование одинарных кавычек. Привыкайте пользоваться стандартом, это избавит от затруднений в случае других диалектов SQL. Если одинарная кавычка является частью строки, надо вместо одной набрать две подряд:
'Kenny''s chicken'
Числа можно записывать как целые, с десятичной точкой и научной нотации. Примеры:
-1
3.142
6.0221415Е23
Двоичные константы записываются как пары шестнадцатиричных цифр (0-9A-F) в одинарных кавычках с лидирующим символом х. Примеры:
x'01'
x'0fff'
Пример
В МySQL существует два типа таблиц - MyISAM и InnoDB. Отличаются они следующим. MyISAM
не поддерживает транзакции и с этим связаны его основные недостатки и преимущества;
в большинстве случаев он быстрее, так как нет расходов на транзакции;
занимает меньше дискового пространства;
меньше расход памяти на обновления;
полнотекстовый индекс;
быстрый INSERT, SELECT.
InnoDB
поддержка транзакций;
построчная блокировка. UPDATE не блокирует всю таблицу;
отлично ведет себя при смешанной нагрузке (insert|select|update|delete).
Начиная с версии 5.5 InnoDB стал основным хранилищем по умолчанию
CREATE TABLE
CREATE TABLE оператор используется для создания новой таблицы в базе данных.
-- Создадим таблицу Customer
CREATE TABLE customer {
id int AUTO_INCREMENT,
fio varchar(50),
age int
}
Результат работы оператора CREATE TABLE
id
fio
age
INSERT INTO
INSERT INTO используется для вставки новых записей в таблицу.
INSERT INTO table_name (column1, column2, column3, ...) VALUES (value1, value2, value3, ...);
-- Без указания столбцов
INSERT INTO table_name VALUES (value1, value2, value3, ...);
INSERT INTO customer (fio, age) VALUES ('Иванов И.И.', 18);
INSERT INTO customer (fio, age) VALUES ('Петров П.П.', 26);
INSERT INTO customer (fio, age) VALUES ('Сидоров С.С', 35);
INSERT INTO customer (fio, age) VALUES ('Ткачёв Т.Т.', 51);
Результат работы оператора INSERT INTO
id
fio
age
1
Иванов И.И.
18
2
Петров П.П.
26
3
Сидоров С.С.
35
4
Ткачёв Т.Т.
51
SELECT
Оператор SELECT используются для выбора данных из базы данных.
SELECT column1, column2, ... FROM table_name;
SELECT fio FROM customer;
-- Результат выборки
+--------------+
| Иванов И.И. |
| Петров П.П. |
| Сидоров С.С. |
| Ткачёв Т.Т. |
+--------------+
Если вы хотите, чтобы выбрать все поля, доступные в таблице, используйте символ * вместо перечисления имён полей
SELECT * FROM customer;
UPDATE
Оператор UPDATE используется для изменения существующих записей в таблице.
UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;
Обратите внимание на пункт WHERE в операторе UPDATE. Предложение WHERE определяет, какая запись(или записи), должна быть обновлена. Если опустить предложение WHERE, все записи в таблице обновяться!
UPDATE customer SET fio = 'Пупкин Г.В.', age = 90 WHERE id = 3;
Результат выполнения оператора UPDATE
id
fio
age
1
Иванов И.И.
18
2
Петров П.П.
26
3
Пупкин Г.В.
90
4
Ткачёв Т.Т.
51
DELETE
Оператор DELETE используется для удаления существующих записей в таблице.
DELETE FROM table_name WHERE condition;
Предложение WHERE определяет , какая запись(или записи), должна быть удаленыа. Если опустить предложение WHERE, все записи в таблице будут удалены!
DELETE FROM customer WHERE age > 50;
Результат выполнения оператора DELETE
id
fio
age
1
Иванов И.И.
18
2
Петров П.П.
26
DROP TABLE
Оператор DROP TABLE используется для удаления существующей таблицы в базе данных.
DROP TABLE table_name;
Удаление таблицы приведёт к полной потере информации, хранящейся в таблице!
phpMyAdmin
phpMyAdmin - веб-приложение с открытым кодом, написанное на языке PHP и представляющее собой веб-интерфейс для администрирования СУБД MySQL. phpMyAdmin позволяет через браузер и не только осуществлять администрирование сервера MySQL, запускать команды SQL и просматривать содержимое таблиц и баз данных.
Для запуска phpMyAdmin можно воспользоваться меню OpenServer
Далее для входа нажимаем кнопку Вперёд
PHP и СУБД
PHP поддерживает взаимодействие с большим колличеством различных систем управления базами данных. Традиционно PHP используют совместно с MySQL. К примеру, в PHP4 поддержка MySQL даже была обеспечена по умолчанию. Однако, не стоит забывать и про другие СУБД, которые могут быть полезны при решении определенных задач, если функциональные возможности и производительность MySQL недостаточны. Список СУБД, которые официально поддерживаются разработчиками PHP.
MySQL
SQLite
PostgreSQL
Oracle (OCI8)
Microsoft SQL Server
Sybase
ODBC
mSQL
IBM DB2, Cloudscape и Apache Derby
Informix
Ovrimos SQL
Lotus Notes
DB++
DBM
dBase
DBX
FrontBase
FilePro
Ingres II
SESAM
Firebird / InterBase
Paradox File Access
MaxDB
В PHP 5 были произведены некоторые изменения, касающиеся СУБД (MySQL и SQLite).
В PHP 5 больше не входят клиентские библиотеки MySQL по причинам связанным с лицензией и поддержкой. Поддержка MySQL не прекращается, просто теперь она по умолчанию не включена. Эта означает, что для того чтобы включить по умолчанию MySQL необходимо самостоятельно отредактировать php.ini и разкомментировать строку с подключением php_mysql.dll. Эта библиотека включена в установочный пакет под Windows.
Начиная с PHP 5, модуль SQLite встроен в PHP. SQLite - это встраиваемая SQL СУБД, а не клиентская библиотека для соединения с сервером баз данных (таким как MySQL или PostgreSQL). Библиотека SQLite читает и записывает напрямую в файлы базы данных на диске.
MySQL + PHP
Интерфейс программирования приложений(Application Programming Interface или API), описывает классы, методы, функции и переменные, которые ваше приложение должно использовать для выполнения поставленной задачи. В случае PHP, API для доступа к базам данных доступны в качестве расширений PHP.
API может быть процедурным или объектно ориентированным. В процедурном API, для совершения необходимых действий вы вызываете функции, тогда как в объектно ориентированном API вы инстанциируете классы и вызываете их методы.
Если вы пишите PHP приложение, которому необходимо взаимодействовать с базой данных MySQL, то у вас есть несколько API на выбор:
Расширение MySQL
Расширение MySQLi («i» означает улучшенный)
PDO - PHP Data Objects (Объекты данных PHP)
Рекомендуется использовать mysqli или PDO_MySQL. Не рекомендуется использовать старое расширение mysql ,так как оно объявлено устаревшим в PHP 5.5.0 и окончательно убрано в PHP 7.
Основное преимущество PDO над MySQLi в поддержке различных драйверов. На момент написания этой статьи, PDO поддерживает 12 различных драйверов, в отличие от MySQLi, который поддерживает только MySQL.
Что это значит? В ситуациях, когда в вашем проекте вы решите поменять базу данных, с PDO этот процесс будет достаточно прозрачным. Итак, все что вам нужно будет сделать, это изменить строку подключения и несколько запросов, если в них используются методы, не поддерживаемые вашей новой базой данных. С MySQLi вам придется переписать каждую строчку кода - включая запросы.
На данном курсе в качестве основного инструмента для подключения к серверу баз данных MySQL используется расширение mysqli
Подключение/отключение
Этот простой пример показывает, как соединиться с базой данных.
$host = "localhost";
$login = "root";
$passwd = "";
$db = "my_database";
// Создание соединения
$conn = mysqli_connect($host, $login, $password, $db);
// Проверка на установление соединения
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
//Закрытие соединения
mysqli_close($сonn);
Открытое соединение MySQL и результирующие наборы автоматически удаляются сразу по окончании работы PHP скрипта. Следовательно, закрывать соединения и очищать результирующие наборы не обязательно, но рекомендуется, так как это сразу же освободит ресурсы базы данных и память, занимаемую результатами выборки, что может положительно сказаться на производительности.
Расширение mysqli предоставляет двойной интерфейс программисту. Поддерживаются как процедурная, так и объектно-ориентированная парадигмы программирования.
mysqli расширение весьма схоже с интерфейсом старого расширения, и во многих случаях функции отличаются только префиксом в имени. Некоторые mysqli функции принимают дескриптор соединения первым аргументом, в отличие от соответствующих им функций старого расширения, которые принимают его в качестве последнего необязательного аргумента.
В дополнение к процедурному пользователи могут использовать объектно-ориентированный интерфейс. Документация заточена именно под объектный интерфейс.
Каких-либо принципиальных отличий в производительности между интерфейсами нет.
Выполнение запроса
Отправка запроса к MySQL из PHP сводится к простому вызову функции mysqli_query(), которая принимает два параметра: объект подключения и строку запроса на языке SQL.
....
$query = "SELECT * FROM city";
$result = mysqli_query($conn, $query);
var_dump($result); // возвращает FALSE в случае неудачи
....
В отличие от командной строки MySQL, здесь в конце запроса точка с запятой не нужна, поскольку для завершения запроса используется функция mysqli_query(), которая не может использоваться для запроса, состоящего из последовательно отправляемях частей. Поэтому MySQL знает, что запрос завершен, и не ищет точки с запятой.
Функция mysqli_query() возвращает объект, который содержит результат запроса. В случае неудачи данный объект содержит значение false.
Можно подумать что содержимое переменной $result будет таким же, как тот результат, который возвращался запросом, вводимым в командной строке, с горизонтальныйми и вертикальными линиями, шапкой и т.д. Но в PHP функция mysqli_query() возвращает не такой результат. В случае успешного выполнения запроса переменная будет содержать ресурс(объект), позволяющий извлечь результаты этого запроса.
После возвращения объекта $result его можно использовать для поэлементного извлечения нужных вам данных с помощью имеющейся в PHP функцией mysqli_fetch_assoc().
// запрос к БД
if($result = mysqli_query($conn, $query))
if( mysqli_num_rows($result) > 0 ){
printf("<table>");
// результат в виде ассоциативного массива
while($row = mysqli_fetch_assoc($result))
printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>", $row["ID"], $row["Name"], $row["CountryCode"], $row["District"], $row["Info"]);
printf("</table>");
}
Функция mysqli_fetch_assoc() возвращает ассоциативный массив, соответствующий результирующей выборке или NULL, если других рядов не существует. Имена полей, возвращаемые этой функцией являются регистро-зависимыми. Эта функция устанавливает NULL-поля в значение NULL PHP.
Существует похожая на mysqli_fetch_assoc() функция. Это функция mysqli_fetch_row(), которая выбирает одну строку данных из результирующего набора и возвращает ее в виде массива, в котором индексы элементов соответствуют номерам столбцов (начиная с 0). Каждый последующий вызов функции будет возвращать массив с данными следующей строки набора или NULL, если строки закончились.
$query = "SELECT * FROM city ORDER BY ID DESC LIMIT 100"; // интересный запрос для вывода последних 100 записей
// запрос к БД
if($result = mysqli_query($conn, $query))
if( mysqli_num_rows($result) > 0 ){
printf("<table>");
while($row = mysqli_fetch_row($result))
printf("<tr><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>", $row[0], $row[1], $row[2], $row[3], $row[4]);
printf("</table>");