检查mysql用户是否存在。

34

如何检查用户是否存在?

我正在为MySQL数据库制作安装程序,我需要检查用户是否存在,如果不存在则创建该用户,如果存在则删除该用户并重新创建。

这样我就可以放心地执行脚本了。

谢谢。

7个回答

76

MySQL 把用户数据存储在一个名为mysql(默认情况下)的数据库中的表中,该表名为user。如果存在指定用户名的用户,则以下查询将返回1,否则返回0

SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'username')

为什么不直接使用 SELECT count(*) FROM mysql.user WHERE user = 'username'。任何 >1 的结果都意味着用户存在。 - Fr0zenFyr
"Exists"比"count"更高效。 - Soheil Rahsaz
如果您想检查userhost两者,可以运行类似以下的语句:SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'username' AND host = 'localhost') - Flimm

9

如果您要删除MySQL用户,那么没有必要先检查它是否存在。如果没有需要删除的内容,MySQL不会抛出任何错误:

DELETE FROM mysql.user WHERE User = 'username';

10
如果采用这种方法,将仅从用户表中删除用户,您还需要从mysql.columns_priv、mysql.db和mysql.tables_priv中删除。此外,这些表的列表可能会在未来的MySQL版本中发生变化。 - stivlo
8
永远不要用这种方式删除用户。请使用DROP USER命令。 - micheal65536
1
如果我们需要检查用户是否存在,以便提示用户是否应该被删除呢? - Leland Hepworth

6
随着MySQL新版本的推出,此选项已可用:
DROP USER IF EXISTS 'username'@'host';

不支持在 MySql 6 中。 - shareef

2

如果需要检查用户是否存在,但不想删除它(例如仅在某些情况下跳过一些指令而不是无论如何都执行它们),可以使用以下代码(其中$USER是要检查的用户):

if [ $(echo "SELECT COUNT(*) FROM mysql.user WHERE user = '$USER'" | mysql | tail -n1) -gt 0 ]
then
  echo "User exists"
else
  echo "User doesn't exist"
fi

注意:

  • mysql 命令需要额外的参数和/或配置来进行身份验证。
  • tail -n1 用于删除查询结果的标题。

1
这是我如何做到的:

#!/usr/bin/env bash

set -o errexit
set -o nounset

# Create credentials file
echo -e "[client]\nuser=root\npassword=${MYSQL_ROOT_PASSWORD}" > ~/.my.cnf

# Create standard user and grant permissions
if ! echo "SELECT COUNT(*) FROM mysql.user WHERE user = 'myuser';" | mysql | grep 1 &> /dev/null; then
    echo "Creating database user ..."
    echo "CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword';
          GRANT ALL PRIVILEGES ON mydatabase.* TO 'myuser'@'localhost';
          FLUSH PRIVILEGES;" | mysql
else
    echo "Database user already created. Continue ..."
fi

请根据实际情况更改myusermydatabasemypassword


如果用户名包含数字1,则此方法效果不佳,因此可能会导致问题。 - Joachim
@Joachim 刚刚用用户名中带有数字1的用户进行了测试,结果完美无误。您确定吗?为什么不能适用于用户名中带有数字1的用户? - Havok
为什么要使用 grep 1?如果 SELECT COUNT(*) 返回 2,会怎样呢? - Fr0zenFyr
@Fr0zenFyr 如果你使用 mysql; describe user; 命令,你会发现:User | char(32) | PRI。因为 user 是主键,这意味着它是唯一的。也就是说,精确匹配 == 不可能返回多个结果。 - Havok
实际上这是一个复合键。User列本身不是PRI。如果你仔细看,你会发现主键是由Host+User组成的复合键。Host char(60) NO PRIUser char(32) NO PRI - Fr0zenFyr
显示剩余2条评论

1

MySQL缺少DROP USER IF EXISTS结构。

一个好的解决方法是在删除用户之前授予一个无害的特权给该用户。这将创建用户(如果不存在),以便可以安全地删除,如下所示:

GRANT USAGE ON *.* TO 'username'@'localhost';
DROP USER 'username'@'localhost';
FLUSH PRIVILEGES;

USAGE 实际上意味着没有特权。

来源:http://bugs.mysql.com/bug.php?id=19166


2
为了后人,这个解决方法已经不再适用。引用另一个答案的评论:“这不再是一个选项。 :( MySQL的当前版本不再为GRANT语句创建新用户。这是他们添加的“功能”。;)”有关原始参考,请参见:https://dev59.com/L3RB5IYBdhLWcg3wiHll#3241918 - Lynn Crumbling

0

MySQL 5.7已经包含了DROP USER IF EXISTS,但对于旧版本,我使用percona-toolkit中的pt-show-grants --drop,并将DROP USER部分反馈给mysql:

pt-show-grants --drop --only=$username | grep '^DROP USER' | mysql -v

如果有多个用户名-主机名对,这将删除所有这些对。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接