> 技术文档 > MySQL介绍及使用

MySQL介绍及使用


1. 安装、启动、配置 MySQL

1. 安装 MySQL

更新软件包索引
sudo apt update
安装 MySQL 服务器
sudo apt install mysql-server

安装过程中可能会提示你设置 root 用户密码。如果没有提示,可以跳过,后续可以手动设置。


2. 配置 MySQL

运行安全脚本

安装完成后,运行以下命令以提高 MySQL 的安全性:

sudo mysql_secure_installation

按照提示进行操作:

  • 设置 root 用户密码(如果之前未设置)。

  • 移除匿名用户(建议选择 Y)。

  • 禁止 root 用户远程登录(如果不需要远程访问,建议选择 Y)。

  • 删除测试数据库(建议选择 Y)。

  • 重新加载权限表(选择 Y)。


3. 设置 MySQL 用户密码

如果在安装过程中没有设置密码,或者需要更改密码,可以通过以下步骤设置密码。

登录到 MySQL
sudo mysql -uroot -p

如果之前没有设置密码,直接按回车键即可登录。

设置密码
ALTER USER \'root\'@\'localhost\' IDENTIFIED WITH mysql_native_password BY \'新密码\';

新密码 替换为你想要设置的密码。

FLUSH PRIVILEGES;
退出 MySQL
exit;

4. 配置远程访问(可选)

如果你需要从其他计算机远程访问 MySQL 数据库,可以按照以下步骤配置。

登录到 MySQL
sudo mysql -uroot -p
创建远程用户并授予权限
CREATE USER \'root\'@\'%\' IDENTIFIED BY \'新密码\';GRANT ALL PRIVILEGES ON *.* TO \'root\'@\'%\';
  • CREATE USER 创建一个允许从任何 IP 地址访问的 root 用户。

  • GRANT ALL PRIVILEGES 授予该用户所有数据库和表的完全访问权限。

刷新权限
FLUSH PRIVILEGES;
退出 MySQL
exit;

5. 配置 MySQL 服务:实现所有IP都能访问

编辑 MySQL 配置文件
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
修改 bind-address
bind-address = 127.0.0.1
bind-address = 0.0.0.0
保存并退出

保存文件并退出编辑器。

重启 MySQL 服务
sudo systemctl restart mysql

6. 测试远程访问(可选)

在另一台计算机上,使用以下命令测试远程访问:

mysql -uroot -h[MySQL服务器IP] -p

输入你设置的密码,如果能够成功连接,说明配置成功。


7. 安装 MySQL 客户端(可选)

如果你需要从其他计算机连接到 MySQL 数据库,可以在客户端计算机上安装 MySQL 客户端。

安装 MySQL 客户端
sudo apt install mysql-client

2.MySQL介绍 

MySQL 是一个 关系型数据库管理系统(RDBMS),使用 结构化查询语言(SQL) 来管理和操作数据。

“关系”在这里指的是二维表格(表 / table),每张表由行(row)列(column) 组成,数据以结构化形式存储。

名称 说明 数据库(Database) 数据的集合,一个数据库中可以有多张表 表(Table) 类似 Excel 表格,用来存储结构化数据 行(Row) 表中的一条记录,例如一个用户信息 列(Column) 数据的字段,比如姓名、年龄、邮箱等 主键(Primary Key) 每行的唯一标识,不可重复 外键(Foreign Key) 引用其他表的主键,用于建立表之间的关系

1.数值类型

1. 整数类型
数据类型 存储大小(字节) 范围(有符号) 范围(无符号) TINYINT 1 -128 到 127 0 到 255 SMALLINT 2 -32768 到 32767 0 到 65535 MEDIUMINT 3 -8388608 到 8388607 0 到 16777215 INT 或 INTEGER 4 -2147483648 到 2147483647 0 到 4294967295 BIGINT 8 -9223372036854775808 到 9223372036854775807
2. 浮点数类型
数据类型 存储大小(字节) 范围 FLOAT 4 依赖于精度 DOUBLE 8 依赖于精度

2、字符串类型

1. 字符类型
数据类型 存储大小 用途 CHAR 固定长度 存储固定长度的字符串,如电话号码 VARCHAR 可变长度 存储可变长度的字符串,如用户名
2. 二进制字符串类型
数据类型 存储大小 用途 BINARY 固定长度 存储固定长度的二进制字符串 VARBINARY 可变长度 存储可变长度的二进制字符串
3. 文本类型
数据类型 存储大小 用途 TINYTEXT 最大 255 字节 存储较短的文本 TEXT 最大 65535 字节 存储中等长度的文本 MEDIUMTEXT 最大 16777215 字节 存储较长的文本 LONGTEXT 最大 4294967295 字节 存储非常长的文本

3.MySQL使用

SQL(结构化查询语言) 是操作关系型数据库的标准语言,包括:

  • SELECT:查询数据

  • INSERT:插入数据

  • UPDATE:更新数据

  • DELETE:删除数据

  • CREATE / DROP:创建或删除表和数据库

  • JOIN:多表联查

1.SQL

1. 登录 MySQL

在终端中输入以下命令登录 MySQL:

mysql -u root -p
  • -u root 表示以管理员用户登录(root 是 MySQL 的默认管理员账号)。

  • -p 表示提示输入密码。输入你在安装过程中设置的 MySQL 管理员密码。

如果密码正确,你会看到 MySQL 的命令行提示符,类似如下:

mysql>

2. 查看数据库

登录后,查看当前数据库列表:

SHOW DATABASES;

你会看到类似以下输出:

+--------------------+| Database  |+--------------------+| information_schema || mysql  || performance_schema || sys |+--------------------+

这些是 MySQL 系统自带的数据库。你可以创建自己的数据库。

3. 创建数据库

创建一个新的数据库,例如 mydatabase

CREATE DATABASE mydatabase;

4. 切换到新创建的数据库

USE mydatabase;

5. 创建表

mydatabase 数据库中创建一个表,例如 students

CREATE TABLE students ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, age INT, grade VARCHAR(10));
  • id 是主键,自动递增。

  • name 是字符串类型,最大长度为 50,不能为空。

  • age 是整数类型。

  • grade 是字符串类型,最大长度为 10。

6. 插入数据

students 表中插入数据:

INSERT INTO students (name, age, grade) VALUES (\'Alice\', 20, \'A\');INSERT INTO students (name, age, grade) VALUES (\'Bob\', 22, \'B\');

7. 查询数据

查询 students 表中的所有数据:

SELECT * FROM students;
+----+-------+-----+-------+| id | name | age | grade |+----+-------+-----+-------+| 1 | Alice | 20 | A || 2 | Bob | 22 | B |+----+-------+-----+-------+

8. 更新数据

更新表中的数据,例如将 Alice 的年龄改为 21:

UPDATE students SET age = 21 WHERE name = \'Alice\';

9. 删除数据

删除表中的数据,例如删除 Bob 的记录:

sql复制

DELETE FROM students WHERE name = \'Bob\';

再次查询数据,确认删除是否成功:

sql复制

SELECT * FROM students;

10. 退出 MySQL

EXIT;

11. 其他常用操作

  • 查看表结构

    DESCRIBE students;
  • 删除表

    DROP TABLE students;
  • 删除数据库

    DROP DATABASE mydatabase;
  • 删除表中所有内容

想删除表中的所有数据,可以使用 TRUNCATE TABLEDELETE 语句。以下是这两种方法的详细说明:

1. TRUNCATE TABLE
TRUNCATE TABLE 表名;
  1. 速度快TRUNCATE TABLE 是一种非常快速的操作,因为它不会逐行删除数据,而是直接删除表中的所有行,然后重新初始化表的存储结构。

  2. 不可恢复:一旦执行 TRUNCATE TABLE,表中的数据将无法恢复。这是因为 TRUNCATE TABLE 实际上是删除表后再重新创建一个空表,所以不会产生回滚日志。

  3. 不触发触发器TRUNCATE TABLE 不会触发 DELETE 触发器,因为它不是逐行删除数据。

  4. 重置自增列:如果表中包含自增列(AUTO_INCREMENT),TRUNCATE TABLE 会将自增列的值重置为初始值(通常是 1)。

2. DELETE
DELETE FROM 表名;
  • 特点

    1. 速度相对较慢DELETE 是逐行删除表中的数据,因此速度比 TRUNCATE TABLE 慢,尤其是当表中有大量数据时。

    2. 可恢复DELETE 操作会产生回滚日志,因此可以通过事务回滚来恢复数据。

    3. 触发触发器:如果表上有 DELETE 触发器,DELETE 操作会触发这些触发器。

    4. 不重置自增列DELETE 不会重置表中的自增列,自增列的值会保持在删除前的最大值。

2.列的完整性约束

1. 主键约束(Primary Key)

  • 作用:唯一标识表中的每条记录。

  • 特点:值必须唯一且不能为空。

  • 示例

    sql复制

    CREATE TABLE students ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50));

2. 外键约束(Foreign Key)

  • 作用:建立表与表之间的关系。

  • 特点:值必须是另一个表的主键值,或者为空。

  • 示例

    sql复制

    CREATE TABLE enrollments ( student_id INT, FOREIGN KEY (student_id) REFERENCES students(id));

3. 唯一约束(Unique)

  • 作用:确保列中的值是唯一的。

  • 特点:允许空值,但每个值必须唯一。

  • 示例

    sql复制

    CREATE TABLE users ( email VARCHAR(100) UNIQUE);

4. 非空约束(NOT NULL)

  • 作用:确保列中的值不能为空。

  • 特点:插入或更新时必须提供值。

  • 示例

    sql复制

    CREATE TABLE employees ( name VARCHAR(50) NOT NULL);

5. 默认值约束(DEFAULT)

  • 作用:为列指定默认值。

  • 特点:插入记录时未指定值时自动使用默认值。

  • 示例

    sql复制

    CREATE TABLE orders ( order_date DATE DEFAULT CURRENT_DATE);

6. 检查约束(CHECK)

  • 作用:限制列的值必须满足某些条件。

  • 特点:确保数据符合特定规则。

  • 示例

    sql复制

    CREATE TABLE products ( price DECIMAL(10, 2) CHECK (price > 0));

7. 添加和删除约束

  • 添加约束

    sql复制

    ALTER TABLE table_name ADD CONSTRAINT constraint_name constraint_type;
  • 删除约束

    sql复制

    ALTER TABLE table_name DROP CONSTRAINT constraint_name;

 4.操作 MySQL 的三种主流 C/C++ 接口/库

名称 语言 说明 libmysqlclient-dev C 最底层、官方提供的 C API libmysql++ C++ C++ 封装库,封装了上面的 C API MySQL Connector/C++ C++ Oracle 官方维护的 C++ 驱动,现代化设计

1️⃣ libmysqlclient-dev - 最底层的 C API(推荐了解)

  • 作用:提供最基础的 C API 来操作 MySQL。

  • 包管理器名(Debian/Ubuntu)

    sudo apt install libmysqlclient-dev

  • 常用头文件#include

  • 使用方式

    • 初始化连接

    • 发送 SQL 查询

    • 获取结果集

  • 适合:底层开发、嵌入式开发、对性能控制要求高的场景。

    #include mysqlpp::Connection conn(false);conn.connect(\"testdb\", \"localhost\", \"root\", \"password\");mysqlpp::Query query = conn.query(\"SELECT * FROM users\");mysqlpp::StoreQueryResult res = query.store();

✅ 优点:轻量、速度快、控制力强
❌ 缺点:接口是 C 风格,写起来繁琐、类型安全差、易出错


2️⃣ libmysql++ - 对 C API 的 C++ 封装(较旧但简单)

  • 作用:基于 libmysqlclient 封装,提供更易用的 C++ 接口。

  • 安装方式(Ubuntu)

    sudo apt install libmysql++-dev

  • 项目地址:http://tangentsoft.com/mysql++/

#include mysqlpp::Connection conn(false);conn.connect(\"testdb\", \"localhost\", \"root\", \"password\");mysqlpp::Query query = conn.query(\"SELECT * FROM users\");mysqlpp::StoreQueryResult res = query.store();

✅ 优点:写起来比 C API 简洁
❌ 缺点:项目已经多年未更新,缺乏现代 C++ 特性(比如 smart pointer, exception 安全等)


3️⃣ MySQL Connector/C++ - Oracle 官方的现代 C++ 驱动(推荐)

  • 作用:Oracle 提供的官方 C++ 库,支持 C++11/14 风格编程,模块化、支持连接池等。

  • 安装方式(Ubuntu)

    sudo apt install libmysqlcppconn-dev

  • 头文件

#include #include #include sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();std::unique_ptr con(driver->connect(\"tcp://127.0.0.1:3306\", \"root\", \"pwd\"));con->setSchema(\"testdb\");std::unique_ptr stmt( con->prepareStatement(\"INSERT INTO users(name) VALUES(?)\"));stmt->setString(1, \"Alice\");stmt->execute();

✅ 优点:

  • 支持 prepared statements(防注入)

  • 面向对象

  • 官方维护,现代设计

❌ 缺点:比 C API 慢一点,依赖较多


✅ 总结:我该选哪个?

如果你是... 推荐选择 理由 新手/想快速开发 MySQL Connector/C++ (libmysqlcppconn-dev) 现代 C++ 风格、易用、安全 想学底层 / 嵌入式 libmysqlclient-dev 学会底层原理,便于扩展 想用老项目代码 libmysql++ 有些老代码仍然使用它,但新项目建议不要用了

5.C/C++ 使用 MySQL API 操作 数据库

// include/db.hpp#pragma once#include #include struct FileMeta { std::string filename; std::string filepath; std::string user; long size;};bool init_db();void close_db();bool insert_file(const FileMeta &file);std::vector query_files_by_path(const std::string &path);
// src/db.cpp#include \"db.hpp\"#include #include MYSQL *conn = nullptr;bool init_db() { // 1.初始化一个 MySQL 连接句柄 conn = mysql_init(nullptr); if (!conn) { std::cerr << \"mysql_init failed\\n\"; return false; } // 2.建立与 MySQL 数据库 if (!mysql_real_connect(conn, \"127.0.0.1\", \"root\", \"123456\", \"metadb\", 3306, nullptr, 0)) { std::cerr << \"mysql_real_connect failed: \" << mysql_error(conn) << \"\\n\"; return false; } return true;}void close_db() { if (conn) { //关闭与MySQL数据库的连接 mysql_close(conn); conn = nullptr; }}// 向数据库插入文件元数据bool insert_file(const FileMeta &file) { // 1.SQL 插入语句格式化到 query 数组 char query[1024]; snprintf(query, sizeof(query),  \"INSERT INTO file_metadata (filename, filepath, user, size) VALUES \"  \"(\'%s\', \'%s\', \'%s\', %ld)\",  file.filename.c_str(), file.filepath.c_str(), file.user.c_str(),  file.size); // 2.mysql_query 函数执行 SQL 查询语句 if (mysql_query(conn, query)) { std::cerr << \"Insert failed: \" << mysql_error(conn) << \"\\n\"; return false; } return true;}std::vector query_files_by_path(const std::string &path) { std::vector results; std::string query = \"SELECT filename, filepath, user, size FROM \"\"file_metadata WHERE filepath = \'\" +path + \"\'\"; if (mysql_query(conn, query.c_str())) { std::cerr << \"Query failed: \" << mysql_error(conn) << \"\\n\"; return results; } // 3.mysql_store_result 函数获取查询结果。 MYSQL_RES *res = mysql_store_result(conn); if (!res) { std::cerr << \"mysql_store_result failed\\n\"; return results; } // 4.mysql_fetch_row 函数逐行获取查询结果 MYSQL_ROW row; while ((row = mysql_fetch_row(res))) { FileMeta file; file.filename = row[0]; file.filepath = row[1]; file.user = row[2]; file.size = std::stol(row[3]); results.push_back(file); } mysql_free_result(res); return results;}
//src/main.cpp#include \"db.hpp\"#include int main() { if (!init_db()) { return 1; } FileMeta file = {\"report.docx\", \"/home/user/docs\", \"alice\", 5120}; insert_file(file); auto files = query_files_by_path(\"/home/user/docs\"); for (const auto &f : files) { std::cout << f.filename << \" (\" << f.size << \" bytes) - \" << f.user << \"\\n\"; } close_db(); return 0;}
cmake_minimum_required(VERSION 3.10)project(MetaFS_C_API)set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED True)# 设置头文件路径include_directories(${PROJECT_SOURCE_DIR}/include)# 设置源文件file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp)# 生成可执行文件add_executable(meta_fs ${SOURCES})# 链接 MySQL client 库target_link_libraries(meta_fs mysqlclient)

——————————————————————————————————————————

#pragma once#include #include struct FileMeta { std::string filename; std::string filepath; std::string user; long size;};bool init_db();bool insert_file(const FileMeta &file);std::vector list_files(const std::string &path);
#include \"db.hpp\"#include  //SQL执行#include  //查询结果#include #include  //链接数据库#include  //驱动#include using json = nlohmann::json;static sql::Connection *conn = nullptr;bool init_db() { std::ifstream file(\"config/db_config.json\"); json cfg; file >> cfg; // 1.创建 MySQL 驱动对象,初始化驱动 sql::mysql::MySQL_Driver *driver = sql::mysql::get_mysql_driver_instance(); // 2. 建立连接 conn = driver->connect(cfg[\"host\"], cfg[\"user\"], cfg[\"password\"]); // 3. 选择数据库 conn->setSchema(cfg[\"database\"]); return true;}// 将文件元数据插入到数据库中bool insert_file(const FileMeta &file) { // 1.准备SQL语句 sql::PreparedStatement *stmt = conn->prepareStatement(\"INSERT INTO file_metadata(filename, filepath, \" \"user, size) VALUES (?, ?, ?, ?)\"); // 2.设置参数 stmt->setString(1, file.filename); stmt->setString(2, file.filepath); stmt->setString(3, file.user); stmt->setInt64(4, file.size); // 3.执行SQL语句 stmt->execute(); // 4.释放PreparedStatement对象,避免内存泄漏 delete stmt; return true;}//从数据库中查询指定路径下的所有文件元数据,并将结果存储到一个std::vector//中返回std::vector list_files(const std::string &path) { std::vector files; sql::PreparedStatement *stmt = conn->prepareStatement(\"SELECT filename, filepath, user, size FROM \" \"file_metadata WHERE filepath = ?\"); stmt->setString(1, path); // 3.执行查询 sql::ResultSet *res = stmt->executeQuery(); // 4.处理查询结果 while (res->next()) { files.push_back({res->getString(\"filename\"), res->getString(\"filepath\"),  res->getString(\"user\"), res->getInt64(\"size\")}); } delete res; delete stmt; return files;}
#include \"db.hpp\"#include int main() { if (!init_db()) { std::cerr << \"DB init failed\\n\"; return 1; } FileMeta f1 = {\"data.txt\", \"/home/user/docs\", \"alice\", 2048}; insert_file(f1); auto files = list_files(\"/home/user/docs\"); for (const auto &f : files) { std::cout << f.filename << \" (\" << f.size << \" bytes) - \" << f.user << \"\\n\"; } return 0;}
-- sql/init.sqlCREATE DATABASE IF NOT EXISTS metadb;USE metadb;CREATE TABLE IF NOT EXISTS file_metadata ( id INT AUTO_INCREMENT PRIMARY KEY, filename VARCHAR(255) NOT NULL, filepath VARCHAR(255) NOT NULL, user VARCHAR(64), create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, size BIGINT);
cmake_minimum_required(VERSION 3.10)project(MiniMetaFS)set(CMAKE_CXX_STANDARD 17)include_directories(include)add_executable(minifs src/main.cpp src/db.cpp)find_package(MySQL REQUIRED)target_link_libraries(minifs mysqlcppconn)# 使用 nlohmann/json(假设你用的是头文件方式)