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;
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 查詢
-
獲取結果集
-
-
適合:底層開發、嵌入式開發、對性能控制要求高的場景。
#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++/
#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>
等
#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 操作 數據庫
// 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);
// 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;
}
//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;
}
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 <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);
#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;
}
#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;
}
-- 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(假設你用的是頭文件方式)