Казалось бы тема проще некуда, но, судя по форумам и специализированным сайтам ответов, у многих людей она вызывает вопросы, надо прояснить. Как же создать пользователя в СУБД MySQL и наделить его правами администратора? Разумеется, речь идёт о SQL, т.к. как создавать пользователей через какой-нибудь менеджер БД типа «PhpMyAdmin» или «MySQL Workbench» все конечно знают.
OK, let’s create users. Создавать будем самый распространённый вид пользователя, который со всеми правами на какую-нибудь базу или на все базы сразу. Обычно именно таких пользователей и создают и не настраивают детально права на таблицы и операции с данными.
На одного пользователя нужно, как правило, всего 2 sql-запроса: создание пользователя и выдача ему необходимых прав на сервере. Однако многие забывают о 3-ем шаге — обновление данных о правах пользователей. Поэтому получается, что создание пользователя и наделения его правами в СУБД MySQL состоит как минимум из 3-ёх отдельных SQL запросов (команд): CREATE USER
, GRANT
, FLUSH PRIVILEGES
.
Достаточно вводной теоретической части, давайте приступать к работе. Поскольку мне так удобнее, писать буду отчасти на английском и давать переводы в скобках, хотя там и так всё предельно понятно.
Create user (создание пользователя):
CREATE USER 'some_user'@'%' IDENTIFIED BY 'some_password';
where ‘some_user’ — user name, ‘%’ — host (% — any host), ‘some_password’ — password as plain text
or
CREATE USER 'some_user'@'%' IDENTIFIED WITH mysql_native_password AS 'some_password';
Empowerment, give rights (наделение правами):
GRANT ALL ON *.* TO 'some_user'@'%';
where ‘*.*’ — database («*» — any database, all dbs)
or
GRANT ALL PRIVILEGES ON *.* TO 'some_user'@'%' IDENTIFIED BY 'some_password';
or
GRANT ALL PRIVILEGES ON *.* TO 'some_user'@'%' IDENTIFIED BY 'PASSWORD' WITH GRANT OPTION;
or
GRANT ALL PRIVILEGES ON *.* TO 'some_user'@'%' WITH GRANT OPTION;
or
GRANT ALL PRIVILEGES ON *.* TO 'some_user'@'%' REQUIRE NONE WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
Update, entry into force changes. This necessarily (Обновление, вступление в силу изменений. Это обязательно):
FLUSH PRIVILEGES;
Именно последний шаг многие часто забывают и поэтому случаются проблемы.
Это всё, что требуется для добавления (создания) нового пользователя в СУБД MySQL.
Work examples
Теперь давайте посмотрим на примеры созданий пользователей.
Example 1
CREATE USER 'some_user'@'%' IDENTIFIED BY 'password'; GRANT ALL ON *.* TO 'some_user'@'%'; FLUSH PRIVILEGES;
Example 2
CREATE USER 'some_user2'@'%' IDENTIFIED BY 'password2'; GRANT ALL ON *.* TO 'some_user2'@'%' IDENTIFIED BY 'password2'; FLUSH PRIVILEGES;
Таблица с пользователями
Вообще пользователи находятся в таблице «user» технической базы «mysql», т.е. теоретически пользователей можно переносить как и обычные данные. Однако физический перенос пользователей в sql запросах, как обычные данные, считается крайне нежелательным и даже неправильным. Всё дело в том, что структура технической таблицы «mysql.user» постоянно меняется от версии к версии и никто не гарантирует, что методом обычного переноса данные импортируются и подойдут под структуру таблицы на новом сервере. Поэтому пользователей надо не переносить как обычные данные, а именно вновь создавать на новом сервере по стандартному sql синтаксису создания пользователей в СУБД MySQL.
Системная таблица с пользователями имеет примерно такую структуру:
CREATE TABLE `user` ( `Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '', `User` char(16) COLLATE utf8_bin NOT NULL DEFAULT '', `Password` char(41) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', `Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N', `ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '', `ssl_cipher` blob NOT NULL, `x509_issuer` blob NOT NULL, `x509_subject` blob NOT NULL, `max_questions` int(11) unsigned NOT NULL DEFAULT '0', `max_updates` int(11) unsigned NOT NULL DEFAULT '0', `max_connections` int(11) unsigned NOT NULL DEFAULT '0', `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0', `plugin` char(64) COLLATE utf8_bin DEFAULT '', `authentication_string` text COLLATE utf8_bin, PRIMARY KEY (`Host`,`User`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges';
Структура этой системной таблицы пользователей постоянно меняется в разных версиях СУБД MySQL.
Примеры переноса пользователей
Перенос только самого необходимого (хост, имя):
INSERT INTO user VALUES ('%','some_user');
Перенос необходимого (хост, имя, пароль):
INSERT INTO mysql.user (Host, User, authentication_string) VALUES ('localhost', 'user', 'password')
Большого смысла в таком переносе нет. Даже если всё будет в порядке, то права всё равно придётся задавать отдельно т.к. у этого пользователя не будет никаких прав ибо они не перенесены.
Попытка полностью перенести всю информацию о пользователе:
INSERT INTO mysql.user VALUES ('%','some_user','*24C62363EE50A2A9110686F1451B862BD197ABD1','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'',NULL)
INSERT INTO user VALUES ('%','bar_user','*24C62363EE50A2A9110686F1451B862BD197ABD1','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0,'',NULL)
Все подобные попытки переносов пользователей напрямую считаются дурным тоном и вообще это крайне не рекомендуется делать, поэтому делать так не надо.