HOWTO · MySQL

在 MySQL 数据库中搜索字符串的出现

本教程将指导你如何搜索完整的数据库以在 MySQL Workbench 和 phpMyAdmin 中查找模式或字符串的出现。

本页内容

作为数据库管理员,你有时需要搜索整个 MySQL 数据库,找出某个字符串或模式的所有出现位置——例如,统计有多少员工注册了 Gmail 地址,或者在不知道某个值存在哪张表中时定位它。

本教程介绍两种图形用户界面(GUI)方法:使用 phpMyAdmin 搜索和使用 MySQL Workbench 搜索。你也可以编写完成相同任务的 SQL 命令和存储过程,但本文的重点是 GUI 选项。

为搜索准备一个示例数据库

下面两种方法使用相同的示例数据:一个名为 person 的数据库,其中包含 student 和 teacher 两张表。每张表都有一个 ID 主键以及 FIRST_NAME、LAST_NAME、GENDER 和 EMAIL 列。

在你自己的 MySQL 服务器上运行以下语句——例如在 phpMyAdmin 的 SQL 选项卡或 MySQL Workbench 的查询选项卡中——然后再按照下面任一 GUI 方法操作。

CREATE DATABASE person;

USE person;

CREATE TABLE student (ID INT PRIMARY KEY, FIRST_NAME VARCHAR(50), LAST_NAME VARCHAR(50), GENDER VARCHAR(10), EMAIL VARCHAR(100));

CREATE TABLE teacher (ID INT PRIMARY KEY, FIRST_NAME VARCHAR(50), LAST_NAME VARCHAR(50), GENDER VARCHAR(10), EMAIL VARCHAR(100));

使用多行 INSERT 语句填充两张表。注意每个行组之间的逗号:VALUES 各行之间缺少逗号是导致语法错误的常见原因。

INSERT INTO student (ID, FIRST_NAME, LAST_NAME, GENDER, EMAIL) VALUES (1, 'Shaajeel', 'Daniel', 'Male', 'shajeeld@gmail.com'), (2, 'Nayya', 'Preston', 'Female', 'npreston@yahoo.com'), (3, 'James', 'Robert', 'Male', 'james@yahoo.com'), (4, 'Jennifer', 'John', 'Female', 'jennifer09@hotmail.com'), (5, 'Sarah', 'Paul', 'Female', 'sarahpaul011@yahoo.com'), (6, 'Karen', 'Donald', 'Female', 'dkaren@gmail.com');

INSERT INTO teacher (ID, FIRST_NAME, LAST_NAME, GENDER, EMAIL) VALUES (1, 'Thomas', 'Christopher', 'Male', 'thomasC098@hotmail.com'), (2, 'Lisa', 'Mark', 'Female', 'lisamark@gmail.com'), (3, 'Anthony', 'Richard', 'Male', 'anthony044@yahoo.com'), (4, 'Matthew', 'Charles', 'Male', 'matthewcharles@gmail.com'), (5, 'Kiren', 'Donald', 'Female', 'dkiren@gmail.com');

在 phpMyAdmin 中,新建的 person 数据库及其两张表会出现在左侧导航面板中:

phpMyAdmin 导航面板,显示 person 数据库及其 student 和 teacher 表

使用 SELECT * FROM teacher; 和 SELECT * FROM student; 验证插入的行:

phpMyAdmin 浏览视图,显示 teacher 表中的五行数据

phpMyAdmin 浏览视图,显示 student 表中的六行数据

使用 phpMyAdmin 搜索所有表

phpMyAdmin 可以一次性搜索数据库中的每张表:

  1. 在左侧面板中选择数据库,使搜索应用于该库(下方截图中的方框 1)。
  2. 打开 Search(搜索)选项卡,输入要查找的字符串、单词或短语(方框 2)。
  3. 选择一个匹配选项——例如,the exact phrase as substring 会查找该文本出现在列内任意位置的行(方框 3)。
  4. 选择要包含的表——要进行全库搜索则全部选中(方框 4)——然后点击 Go。

phpMyAdmin 的 Search 选项卡,显示已选中的数据库、搜索词输入框、匹配条件选项和表选择列表

随后 phpMyAdmin 会报告每张表中找到的匹配数量。点击某张表计数旁边的 Browse,即可直接打开匹配的行。

phpMyAdmin 搜索结果,显示每张表的匹配计数,以及用于打开匹配行的 Browse 链接

使用 MySQL Workbench 搜索选定的表

MySQL Workbench 通过 Database → Search Table Data 提供类似的功能,但它只搜索你事先选定的表:

  1. 在 Schemas 面板中选择要搜索的表(方框 1)。MySQL Workbench 会跳过所有未选中的表,因此要覆盖整个数据库请全部选中。
  2. 打开 Database 菜单并选择 Search Table Data。
  3. 选择一个匹配选项——CONTAINS 会查找搜索文本出现在值中任意位置的行(方框 3)。
  4. 输入要查找的字符串或表达式(方框 4)。
  5. 可选:设置每张表以及整个数据库的最大匹配数量,并选择是否搜索所有列类型。
  6. 点击 Start Search。

结果网格会报告模式(schema)、表名、主键、找到匹配项的列名以及匹配到的值(方框 6),因此你可以直接跳转到包含该字符串的行。

MySQL Workbench 的 Search Table Data 对话框,显示已选中的表、CONTAINS 匹配选项、搜索表达式输入框和结果网格

解读结果并选择搜索方法

这两个工具报告匹配的方式不同。phpMyAdmin 回答的是“哪些表包含这个字符串?”——它给出每张表的匹配计数和一个指向匹配行的 Browse 链接,适合快速了解某个值分布在哪里。MySQL Workbench 回答的是“具体哪些行和列包含它?”——它列出每个匹配项的模式、表、主键、列和值,适合需要精确定位的情况。

这两个界面最终都会对服务器执行 SQL。下面这个可运行的程序使用 Python 标准库中的 sqlite3 模块,在同样的示例数据上演示这类搜索在查询层做了什么:它检查每张表的字符列是否包含子字符串,并报告每个命中项所在的表、列和主键。运行此示例:

本节中的代码以及显示的标签或输出仍为英文。

import sqlite3

connection = sqlite3.connect(":memory:")
cursor = connection.cursor()

cursor.execute("CREATE TABLE student (id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT, gender TEXT, email TEXT)")
cursor.execute("CREATE TABLE teacher (id INTEGER PRIMARY KEY, first_name TEXT, last_name TEXT, gender TEXT, email TEXT)")

students = [
    (1, "Shaajeel", "Daniel", "Male", "shajeeld@gmail.com"),
    (2, "Nayya", "Preston", "Female", "npreston@yahoo.com"),
    (3, "James", "Robert", "Male", "james@yahoo.com"),
    (4, "Jennifer", "John", "Female", "jennifer09@hotmail.com"),
    (5, "Sarah", "Paul", "Female", "sarahpaul011@yahoo.com"),
    (6, "Karen", "Donald", "Female", "dkaren@gmail.com"),
]
teachers = [
    (1, "Thomas", "Christopher", "Male", "thomasC098@hotmail.com"),
    (2, "Lisa", "Mark", "Female", "lisamark@gmail.com"),
    (3, "Anthony", "Richard", "Male", "anthony044@yahoo.com"),
    (4, "Matthew", "Charles", "Male", "matthewcharles@gmail.com"),
    (5, "Kiren", "Donald", "Female", "dkiren@gmail.com"),
]

cursor.executemany("INSERT INTO student VALUES (?, ?, ?, ?, ?)", students)
cursor.executemany("INSERT INTO teacher VALUES (?, ?, ?, ?, ?)", teachers)

term = "%gmail%"
columns = ["first_name", "last_name", "gender", "email"]

for table in ("student", "teacher"):
    for column in columns:
        rows = cursor.execute(
            f"SELECT id, {column} FROM {table} WHERE {column} LIKE ?", (term,)
        ).fetchall()
        for row in rows:
            print(f"{table}.{column} (id={row[0]}): {row[1]}")

connection.close()
student.email (id=1): shajeeld@gmail.com
student.email (id=6): dkaren@gmail.com
teacher.email (id=2): lisamark@gmail.com
teacher.email (id=4): matthewcharles@gmail.com
teacher.email (id=5): dkiren@gmail.com

对于一次性的查找,任一 GUI 都够用。对于想要定时执行或写入脚本的可重复检查,纯 SQL——按列使用 LIKE 模式,或由 INFORMATION_SCHEMA 驱动的存储过程——是更自然的选择。