СУБД MySQL использует специальную базу данных для предоставления прав доступа к своим базам данных. Эти права могут базироваться на именах серверов и/или пользователей и предоставляться для одной или нескольких баз данных
Пользовательские аккаунты могут быть снабжены паролями. При обращении к базе данных, пароль шифруется. Поэтому он не может быть перехвачен и использован посторонним (это мнение автора СУБД...).
СУБД MySQL имеет три таблицы, а именно:
База данных: mysql Таблица: db
Поле | Тип | Null | Ключ | Умолчание | Extra |
---|---|---|---|---|---|
Хост | char(60) | PRI | |||
Db | char(32) | PRI | |||
Пользователь | char(16) | PRI | |||
Select_priv | char(1) | N | |||
Insert_priv | char(1) | N | |||
Update_priv | char(1) | N | |||
Delete_priv | char(1) | N | |||
Create_priv | char(1) | N | |||
Drop_priv | char(1) | N |
Поле | Тип | Null | Ключ | Умолчание | Extra |
---|---|---|---|---|---|
Хост | char(60) | PRI | |||
Db | char(32) | PRI | |||
Select_priv | char(1) | N | |||
Insert_priv | char(1) | N | |||
Update_priv | char(1) | N | |||
Delete_priv | char(1) | N | |||
Create_priv | char(1) | N | |||
Drop_priv | char(1) | N |
База данных: mysql Таблица: user
Поле | Тип | Null | Key | Умолчание | Extra |
---|---|---|---|---|---|
Хост | char(60) | PRI | |||
Пользователь | char(16) | PRI | |||
Пароль | char(8) | ||||
Select_priv | char(1) | N | |||
Insert_priv | char(1) | N | |||
Update_priv | char(1) | N | |||
Delete_priv | char(1) | N | |||
Create_priv | char(1) | N | |||
Drop_priv | char(1) | N | |||
Reload_priv | char(1) | N | |||
Shutdown_priv | char(1) | N | |||
Process_priv | char(1) | N | |||
File_priv | char(1) | N |
Пример добавления новых пользователей:
$ mysql mysql mysql> INSERT INTO user VALUES ('%','monty',password('something'), -> 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); mysql> INSERT INTO user (host,user,password) values('localhost','dummy',''); mysql> INSERT INTO user VALUES ('%','admin','','N','N','N','N','N','N','Y','N','Y','N'); mysql> quit $ mysqladmin reload
Добавлено три новых пользователя (юзверя):
monty: Суперпользователь (администратор), должен использовать пароль, для работы с mysql.
dummy: Должен быть допущен к индивидуальной базе данных по таблице 'db '.
admin: Не нуждается в пароле, но разрешено выполнение только команд 'mysqladmin reload' and 'mysqladmin processlist'. Может быть допущен к индивидуальной базе данных через таблицу 'db'.
ВНИМАНИЕ! Вы ДОЛЖНЫ использовать функцию password() при создании пользователя, имеющего пароль. СУБД MySQL ожидает получить зашифрованный пароль.
Атрибуты, установленные в таблице пользователей перекрывают атрибуты, установленные в таблице DB. Если сервер поддерживает много баз данных, лучше создавать пользователей без прав доступа в таблице пользователей и назначать им права доступа к базе данных по таблице db.
Если Вы используете MIT threads package, обратите внимание, что имя localhost не будет работать, так как MIT threads package не поддерживает socket-подключения. Это означает, что Вы должны всегда определять ваш hostname (имя сервера) при подключении, даже если Вы работаете с одним и тем же сервером.
Следует помнить следующие правила при настройке прав доступа:
Пользователь | Сортируется по именам серверов и пользователей. |
db | Сортируется по именам серверов, пользователей и баз данных. |
Сервер | Сортируется по именам серверов и баз данных. |
Начиная с версии 3.20.19 сервера введена еще одна хитрость, для попытки вычислить, как данный пользователь обратится к данной базе данных. Допустим существование пользователя с именем Джо, который зарегистрирован так:
Проверка таблицы баз данных будет выполнена для пользователя '' (пустое имя), а не для пользователя Джо, даже если пользователь, Джо имеет запись в таблице доступа к базам данных (db таблице).
Создание пользовательских аккаунтов - вероятно, наиболее путающий аспект СУБД MySQL, (особенно, если никогда не имел с ней дела), так что не удивляйтесь, если потребуется некоторое время, чтобы во всем разобраться и получить парочку несколько неприятных сюрпризов. Использование программы mysqlaccess делает управление доступом несколько более ясным.
Вообще лучше избегать использования регулярных выражений SQL в полях имени сервера. Это упрощает отладку.
Конкретно, установите все поля "имя сервера" в '%' и очистите таблицу серверов. Как только все начнет нормально функционировать, можно начинать эксперименты с добавлением имен серверов в таблицу серверов в случае такой необходимости.
Если получено сообщение об ошибке 'Access denied', то скорее всего вы нормально связались с демоном mysqld, но имеете неправильную информацию в вашей таблице пользователей.
Зашифрованный пароль сохраняется в таблице пользователей ('user ').
Запуск mysqld (при загрузке системы)
Solaris
Скопируйте скрипт mysql.server из каталога mysql bin в /etc/init.d .
Проверьте все пути в скрипте mysql.server. Проверьте и установите safe_mysqld в /etc/init.d/mysql.server и в /etc/rc2.d/S99mysql.server .
Linux
В Caldera Open Linux надо добавить в файл /etc/rc.d/rc.local следующее:
/usr/local/bin/safe_mysql &
Конечно, здесь надо задать правильный путь в каталог с MySQL.
Запуск mysqld (при запущенной системе)
Программа mysqld может быть запущена от имени любого пользователя. По умолчанию она запускается от имени root. Если она запускается от имени любого другого пользователя, надо установить правильные права доступа ко всем необходимым файлам.
Зайдите в систему как пользователь-владелец MySQL и дайте следующую команду (Предполагается, что исполняемый модуль mysql находится в вашем пути. Если это не так, укажите полный путь):
safe_mysql &
Как и большая часть программ для unix, MySQL поставляется в виде исходного текста, который надо откомпилировать. Перед компиляцией можно произвести некоторую настройку пакета на уровне исходного текста.
Выключение альтернативных пользовательских логинов
Если вы не хотите, чтобы пользователи могли применять опцию -u для входа в mysql под другим логином, можно закомментировать в файле global.h строку:
#define SAFE_USER 1 /* Comment this if you are paranoid */
Выключение автоматического присваивания значений по умолчанию
По умолчанию MySQL автоматически назначит значение по умолчанию полям, которые явно не объявлены. MySQL будет делать это исходя из типа конкретного поля. Если Вы предпочли бы, чтобы поля с необъявленными значениями имели значение NULL, то добавьте в файл global.h строку:
#define DONT_USE_DEFAULT_FIELDS
Изменение используемой длины ключа
По умолчанию MySQL рассматривает только 1120 байтов ключа. Вы можете увеличивать это значение, редактируя файл nisam.h и изменяя значение N_MAX_KEY_LENGTH. Обратите внимание, что это может вести к снижению производительности. Нет причины делать это значение меньше, поскольку можно определить ключ, длина которого меньше указанного поля. Более подробно это рассмотрено в разделе "Ключи".
Изменение порядка сортировки
По умолчанию MySQL сортирует строки согласно ISO8859-1 (latin1). Вы можете изменить это во время конфигурации, определяя следующую опцию.
--with-charset=[charset]
Где [charset] может быть один из: latin1, latin2, koi8_ru, dec8, dos, hp8, swe7, usa7.
Чтобы узнать о том, как добавлять новые наборы символов, посмотрите каталог строк в исходниках.
Обратите внимание: Если Вы меняете наборы символов уже создав базу данных, Вы будете должны выполнить isamchk с параметрами -e, и -q для всех таблиц, иначе MySQL не будет работать правильно.
Если Вы понимаете C++, и Yacc, то относительно просто добавить функцию к СУБД MySQL. Если не понимаете, то дело хуже.
Сначала добавьте строку в файл sql_lex.cc с именем функции в массив sql_functions.
Затем добавьте две строки в файл sql_yacc.y. Первая определяет символ препроцессора yacc. Вы должны добавить это к началу файла. Затем определите параметры функции, и создайте 'item' с этими параметрами.
В файле item_func.h объявляют класс, который наследуется из Item_num_func или Item_str_func, в зависимости от того, возвращает ли ваша функция число или строку.
В intem_func.cc добавьте:
double *Item_func_newname::val()
если Вы определяете числовую функцию, или
String *Item_func_newname::Str(String *str)
если Вы определяете строковую функцию.
Для строковой функции вы должны также определить следующую функцию:
void Item_func_newname::fix_length_and_dec()
Она должна по крайней мере вычислить 'max_length' основанный на полученных параметрах. max_length - максимальное число символов, которое функция может вернуть (максимальная длина возвращаемого значения).
Если функция не может возвращать null, Вы должны также установить 'maybe_null=0'.
Для строковых функций параметр 'String *str', предоставляет буфер для хранения результата. Строковая функция должна вернуть строку, которая хранит результат.
Все строковые функции должны избегать выделения памяти больше, чем им абсолютно необходимо! Системные ресурсы не бесконечны...
Самый быстрый способ загружать данные в MySQL - команда LOAD DATA INFILE. Это в 3-20 раз быстрее, чем использование инструкций INSERT. Для еще большего количества быстродействия Вы можете использовать следующую процедуру, чтобы отключить формирование ключа на вашей таблице, в то время как данные загружаются. Для этого надо находиться в вашем MySQL каталоге баз данных, или обеспечивать полные пути к вашей базе данных.
isamchk -rq -k0 [имя_базы_данных]/[имя_таблицы] | Удаление ключей |
LOAD DATA INFILE ... | Чтение Ваших данных |
isamchk -rq [имя_базы_данных]/[имя_таблицы] | Создание ключей таблицы заново |
mysqladmin reload. | Сообщите, чтобы mysql использовал новую таблицу |
Когда Вы указываете опцию -O, отдельно (без дополнительных параметров) Вы получите список всех переменных и их текущих значений. Это может выглядеть примерно так:
$ mysqld -O
Возможные переменные в опции -O:
Имя | Значение по умолчанию |
back_log | Определите размер очереди для входящих tcp/ip подключений. Убедитесь, что установили его побольше, когда Вы ожидаете большое количество подключений в коротком периоде времени. Некоторые ОС могут иметь максимальное значение этой переменной 128 или 256. Подробности об этой очереди можно посмотреть на man-странице listen(2). |
keybuffer | Размер кэш-буфера, для хранения всех недавно использованных ключей. Большой буфер дает самую лучшую эффективность. С переключателем -Sl распределен только один буфер. |
max_allowed_packet | Буфер подключений сервера может быть изменен до этого значения, если пользователь дает длинную команду. Начальный буфер = 'net_buffer_length'. На каждое подключение выделяется один буфер. |
net_buffer_length | Начальный размер буфера подключений. На каждое подключение выделяется один буфер. |
max_connections | Максимальное число подключений, которые mysqld может иметь открытыми в одно и то же время. |
table_cache | Максимальное число таблиц сохраняемых открытыми на сервере. Таблицы хранятся открытыми, для ускорения запроса к часто используемым таблицам. Однако, каждая открытая таблица требует много памяти. |
recordbuffer | Размер кэш-буфера для хранения прочитанных записей. На каждое подключение выделяется один буфер. |
sortbuffer | Размер буфера, используемого при сортировке. На каждое подключение выделяется один буфер. |
max_sort_length | Максимальное время для сортировки? |
Полезные замечания
Если Вы имеете прикладную программу, которая требует большого количества потоков, это является хорошим способом уменьшить значения recordbuffer и sortbuffer примерно до 32K. Вы можете даже уменьшить recordbuffer до 8КБ без особых проблем. Кроме того можно рассматривать уменьшение значения переменной keybuffer до размера в 512КБ. Это сохранит большой объем памяти, и повысит эффективность работы.
Маленькие хитрости по улучшению производительности
После того, как Вы загрузили данные в вашу базу данных, Вы можете выполнить команду 'isamchk -a' над вашими таблицами. Программа isamchk соберет статистику по вашим таблицам, которую сможет использовать оптимизатор. Вообще, надо выполнить isamchk только однажды на таблице. При этом предполагается, что что данные в таблице во время isamchk выполнены в типичном представлении для вашей таблицы.
Какая оптимизация выполняется для условия WHERE?
key = 1 or A = 10 -> NULL (Нельзя использовать ключ) key = 1 or A = 10 and key=2 -> key = 1 OR key = 2 key_part_1 = const and key_part_3 = const -> key_part_1 = const
Постоянные таблицы:
const_table.key = constant const_table.key_part_1 = const_table2.field and const_table.key_part_2 = constant
Оптимизация памяти, используемой таблицами
Есть несколько вещей, которые Вы можете сделать, чтобы минимизировать количество места, которое используют ваши таблицы. Прежде всего используйте НЕ ПУСТОЙ указатель всякий раз, когда возможно. Это ускорит запросы, и сохранит 1 бит на поле.
Вы можете сохранить много места, используя меньшие целочисленные переменные. Например, MEDIUMINT часто вполне достаточен.
Вообще Вы должны выбрать самый маленький тип данных, в котором Вы будете нуждаться, если есть проблемы с памятью.
Имейте в виду, что поля фиксированной длины в mysql обрабатываются значительно быстрее. Избегая полей переменной длины (VARCHAR, BLOBs), можно повысить эффективность на 10-200%.
В настоящее время инструкция INSERT дает ошибку только при вставке пустого указателя (NULL) в не пустой столбец.
При использовании INSERT или команды, которая может воздействовать на много записей, выполняется следующее:
Во время связи клиента с сервером 'warnings information' возвращается только при использовании 'ALTER TABLE' или 'LOAD DATA FROM...'.
Версии MySQL нумеруются по следующей схеме:
111.222.333
111 | Если первая цифра изменяется, это означает, что были сделаны серьезные изменения. Они могут включать поддержку новых форматов файлов, новые протоколы, и т.д. Будьте готовы сделать некоторые модификации ваших прикладных программ перед выполнением после обновления. По крайней мере Вам придется выполнить дамп и перезагрузить Ваши таблицы. |
222 | Значительный новый код/функциональные возможности. Может включать мелочь в поддержке синтаксиса SQL или интерфейса пользователя. Вам не придется делать сильных изменений в Ваших прикладных программах, но тщательно проверьте их перед выполнением. |
333 | Маленькие безопасные изменения, которые не должны разорвать что-нибудь у сисопа на части. Самая большая проблема здесь - добавление ключевых слов SQL, которые находятся в противоречии с существующими именами таблицы. Если Вы избегаете использовать ключевые слова стандарта SQL-92 для ваших имен таблиц (так вообще-то и надо...), все должно быть ХОРОШО. |
Хорошая идея - всегда проверять файл NEWS, когда Вы загружаете новую версию. Это должно дать Вам, представление о том, что именно изменилось, начиная с вашей последней модификации.
На всякий случай приведу подробное описание протокола "клиент-сервер", используемого пакетом MySQL для связи между клиентом и сервером базы данных.
Обозначения
< = клиент > = сервер [] 1 байт [2: ] 2 байта (нижний байт первый) [3: ] 3 байта (нижний байт первый) [4: ] 4 байта (нижний байт первый) [string: ] строка, кончающаяся нулем. [length: ] длина целого числа. Проверьте Net_store_length() для этого! Идея в том, чтобы наиболее часто получать данные длиной в 1 байт, но допускать и более длинные данные (и NULL).
Детальное описание
Каждый передаваемый пакет имеет следующий префикс:
[3: длина пакета] [номер пакета] данные
При приеме пакета добавляется [0] после каждого принятого пакета, чтобы получить простую обработку строк ошибки.
Номера пакетов начинаются с 0 и увеличиваются для каждого посланного/полученного пакета.
Типы пакетов
:connect
> [protocol version] [string: password crypt seed] < [2: 0] [3: max_allowed_client_packet_length] [string: user name] [string: scrambled password] > ok packet
Посмотрите в файле password.c из исходников MySQL какой метод используется для шифрования паролей. Пароль должен быть пустым, если пользователь не имеет никакого пароля.
:ok
[0] [length: affected_rows] [length: unique id]
:error
Может приходить в любое время.
> [255] [string: error message]
:command
< [command number] enum enum_server_command{SLEEP,QUIT,INIT_DB,QUERY,FIELD_LIST, CREATE_DB,DROP_DB,RELOAD,SHUTDOWN,STATISTICS, PROCESS_INFO,CONNECT}
:query
< [QUERY command] [string: query string] (The end null is not sent) > [0] [length: affected rows] [length: insert id] (Insert, delete...)
или:
> [length: column_count] (a query result) > column field data packets > row data packets
:data
: Данные передаются пока не придет пакет, который состоит только из одиночного символа [254]. Остерегайтесь: могут иметься пакеты, которые начинаются с символа 254! Каждый пакет типа 'data' имеет поле 'column count'.
Формат каждого поля:
[:length] == NULL_LENGTH -> NULL field
или:
[:length] [length data] (Строка не оканчивается на \0!)
Пакет данных столбца состоит из 5 столбцов со следующими данными:
[:string table name] [:string column name] [:3 create length of column (may be larger in a few cases)] [:1 type (as of enum_field_types)] [:1 flag] [:1 decimals] (2 байта!)
При использовании команды list_fields имеется шестой столбец:
[:string default]
Посмотрите в файлах libmysql.c, net.c и password.c более подробную информацию о форматах пакетов.
Для получения описания таблицы используйте команду (Вы должны перейти в каталог, который содержит таблицу, информацию о которой Вы желаете получить. Вообще это будет $DATADIR/[dbname], где dbname - имя базы данных, которая содержит таблицу.):
prompt> isamchk -d table_name ISAM file: table_name Data records: 215 Deleted blocks: 0 Recordlength: 85 Record format: Packed table description: Key Start Len Index Type 1 37 14 unique text packed stripped 2 1 30 multip. text packed stripped 3 51 4 multip. long 4 31 2 multip. short 33 2 short 35 2 short
Для более подробных сведений о таблице попробуйте: prompt> isamchk -d -v table_name
ISAM file: Customer Isam-version: 2 Creation time: 1996-12-17 21:40:04 Data records: 0 Deleted blocks: 0 Datafile: Parts: 0 Deleted data: 0 Datafilepointer (bytes): 4 Keyfile pointer (bytes): 3 Recordlength: 374 Record format: Packed table description: Key Start Len Index Type Root Blocksize Rec/key 1 2 2 unique short -1 1024 1 2 4 80 multip. text packed stripped -1 1024 1 3 2 2 multip. short -1 1024 1
Объяснение полученного результата:
ISAM file | Имя ISAM-файла. |
Isam-version | Версия ISAM формата. Сейчас всегда 2. |
Creation time | Когда файл данных был создан? |
Recover time | Когда в последний раз был восстановлен файл индекса/данных? |
Data records | Сколько записей/строк. |
Deleted blocks | Сколько удаленных блоков все еще занимают место? См. примеры в разделе по isamchk для информации относительно избавления от неиспользуемого места. |
Datafile: Parts | Для динамической записи это показывает, сколько блоков данных в ней. Для оптимизированной таблицы без дырок это будет то же, что и Data records. |
Deleted data | Сколько всего байт занимают удаленные данные. |
Datafilepointer | Сколько байтов занимает указатель файла данных? Это 2, 3 или 4 байта. Большинство таблиц обходится 2 байтами, но это не может управляться из MySQL. Для фиксированных таблиц это адрес записи. Для динамических таблиц это адрес байта. |
Keyfile pointer | Сколько байтов занимает указатель файла данных? Это обычно 1, 2 или 3 байта. Большинство таблиц обходится 2 байтами, но это вычисляется mysql автоматически. Это всегда адрес блока. |
Max datafile length | Сколько байт может использовать для этой таблицы файл данных (.ISD). |
Max keyfile length | Сколько байт может использовать для этой таблицы файл ключей. |
Recordlength | Сколько пробела занимает каждая запись/строка? |
Record format | Какой формат имеет каждая запись/строка? |
table description | Список всех ключей в таблице. Для каждого ключа выводится краткая информация низкого уровня (большее количество информации в следующей таблице). |
Краткая информация низкого уровня для каждого ключа:
Key | Номер ключа. |
Start | Где в записи/строке начинается индексная часть. |
Len | Какой длины индексная часть? Для упакованных чисел это всегда полная длина поля. Для строк она может быть короче полной длины (хотя MySQL все же не поддерживает такой вариант). |
Index | unique или multip. |
Type | Какой тип данных имеет эта индексная часть? Это - C тип данных (опционально packed или short). |
Root | Адрес корня индексного блока. |
Blocksize | Размер каждого индексного блока. По умолчанию 1024, но это может быть изменено во время компиляции. |
Rec/key | Статистическое значение, используемое оптимизатором. Оно сообщает, сколько записей приходится на этот ключа. Уникальный ключ всегда имеет значение 1. Это может измениться после того, как таблица загружена и стабилизирована, используя isamchk -a . По умолчанию 30. |
MySQL FAQ имеет обширную информацию по этой теме.
Ниже дается некоторая информацию низкого уровня относительно того, как ключи хранятся и используются в MySQL.
Текущий размер блока для B-tree равен 1024 и и всех блоков (за исключением root) - по крайней мере 2/3 от полного. Для типичного идентификатора (id = 4 байта) это означает 1024/(4+4)*2/3=85 ключей в соответствии с записью, и таким образом можно находить позицию реальной записи в 5 позиционированиях.
Если Вы желаете, чтобы ваши индексы B-tree были 100% полными, выполните isamchk с опцией -rq над вашими файлами таблицы.
Только первая часть ключа может быть префиксно сжата. Если два ключа имеют тот же самый префикс, другая часть ключа будет занимать 1 байт. Все строковые части длиннее 4 символов имеют удаленные хвостовые пробелы.
Если ключ фиксированного размера, то nisam использует двоичный поиск в каждом блоке, иначе используется последовательный поиск.
Все блоки ключей читаются/пишутся через key_buffer (по умолчанию 1M) так что блок root буферизуется всегда.
Чтение следующего оптимизировано, так что библиотека не должна консультироваться с любым другим блоком при чтении из списка блоков. Это дает очень хорошую эффективность, когда Вы должны читать группу записей с тем же самым ключом.
Ниже приводятся планы по дальнейшему развитию и совершенствованию пакета MySQL и его будущих версиях.
Включение блокировки таблицы и сохраненных процедур должно пройти длинный путь к предоставлению людям функциональных возможностей, в которых они нуждаются без серьезного воздействия на эффективность MySQL.
Такие свойства как views, rollback и triggers будут добавлены на каком-то этапе опционально. Они требуют основательной переработки пакета.
Внутренние и внешние объединения, возможно, будут добавлены в версии 3.21.0
Когда MySQL запущен на Linux системе и использует потоки Linux, Вы будете видеть минимум три процесса. Фактически, это потоки. Будет иметься один поток для Linux Threads manager, один, чтобы обрабатывать подключения и один, чтобы обработать сигналы.
Назад | Содержание | Вперед