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
INTINTEGER 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;

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 <mysql/mysql.h>

  • 使用方式

    • 初始化连接

    • 发送 SQL 查询

    • 获取结果集

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

    cpp 复制代码
    #include <mysql++/mysql++.h>
    
    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++/

cpp 复制代码
#include <mysql++/mysql++.h>

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

  • 头文件<mysql_driver.h><mysql_connection.h>

cpp 复制代码
#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/prepared_statement.h>

sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
std::unique_ptr<sql::Connection> con(driver->connect("tcp://127.0.0.1:3306", "root", "pwd"));
con->setSchema("testdb");

std::unique_ptr<sql::PreparedStatement> 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 操作 数据库

cpp 复制代码
// include/db.hpp

#pragma once
#include <string>
#include <vector>

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<FileMeta> query_files_by_path(const std::string &path);
cpp 复制代码
// src/db.cpp

#include "db.hpp"
#include <iostream>
#include <mysql/mysql.h>

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<FileMeta> query_files_by_path(const std::string &path) {
  std::vector<FileMeta> 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;
}
cpp 复制代码
//src/main.cpp
#include "db.hpp"
#include <iostream>

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;
}
cpp 复制代码
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)

cpp 复制代码
#pragma once
#include <string>
#include <vector>

struct FileMeta {
  std::string filename;
  std::string filepath;
  std::string user;
  long size;
};

bool init_db();
bool insert_file(const FileMeta &file);
std::vector<FileMeta> list_files(const std::string &path);
cpp 复制代码
#include "db.hpp"
#include <cppconn/prepared_statement.h> //SQL执行
#include <cppconn/resultset.h>          //查询结果
#include <fstream>
#include <mysql_connection.h> //链接数据库
#include <mysql_driver.h>     //驱动
#include <nlohmann/json.hpp>

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<FileMeta>
//中返回
std::vector<FileMeta> list_files(const std::string &path) {
  std::vector<FileMeta> 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;
}
cpp 复制代码
#include "db.hpp"
#include <iostream>

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;
}
cpp 复制代码
-- sql/init.sql

CREATE 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
);
cpp 复制代码
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(假设你用的是头文件方式)
相关推荐
L73S372 小时前
MySQL数据类型
mysql·考研·学习方法
yzhSWJ3 小时前
MySQL 中查询 VARCHAR 类型 JSON 数据的
mysql·adb·json
java1234_小锋6 小时前
MySQL中有哪几种锁?
数据库·mysql
zybishe8 小时前
免费送源码:Java+ssm+MySQL 酒店预订管理系统的设计与实现 计算机毕业设计原创定制
java·大数据·python·mysql·微信小程序·php·课程设计
王军新9 小时前
MySQL索引介绍
数据库·mysql
努力奋斗的小杨9 小时前
学习MySQL的第八天
数据库·笔记·学习·mysql·navicat
Another Iso10 小时前
MySQL 事务的优先级
数据库·mysql
老李不敲代码12 小时前
榕壹云门店管理系统:基于Spring Boot+Mysql+UniApp的智慧解决方案
spring boot·后端·mysql·微信小程序·小程序·uni-app·软件需求
butiehua020214 小时前
MySQL 优化方案大全
数据库·mysql
何似在人间57516 小时前
Seata 支持哪些模式的分布式事务?
分布式·mysql·seata·分布式事务