数据库项目初体验:使用C语言连接数据库完成短地址服务(本地运行版)
前言:初学者的思考
作为一个刚初学数据库的小白并且在之前我的博客中我有尝试使用C语言写过一个短地址服务,但是使用C语言编写的短地址服务只有短记忆性,正好刚刚学习到这部分,所以决定巩固一下学习的知识做一个简易的连接数据库的C语言短地址服务
这个项目算是比较认真学习的一个项目希望你觉得对你有用的话可以多给我点个赞点个收藏!
一、项目简介
本项目通过C语言调用MySQL数据库,实现一个本地运行的“短地址服务”小系统。你可以输入一个长网址,系统会生成一个短码,之后通过短码可以查回原始网址,并统计访问次数。
本项目适合初学者体验C语言与数据库的结合,所有代码和SQL均为本地运行版,简单易懂。
二、环境准备
1. 安装MySQL数据库
- Windows推荐用MySQL Installer安装,Linux用包管理器安装。
- 安装好后记住你的MySQL用户名(如root)和密码。
2. 安装MySQL开发库
- Windows:安装MySQL时勾选“MySQL C API开发文件”。
- Linux:
sudo apt-get install libmysqlclient-dev
3. 安装C语言编译器
- Windows:推荐MSYS2/MinGW-w64,安装后有gcc。
- Linux:
sudo apt-get install build-essential
4.为即将连接的数据库创建一个用户和密码
创建用户 tom
sudo mysql
create user tom@'%' identified by '123456';
创建用户tom
密码是123456
连接库操作在完成数据库建立后进行
三、数据库表结构(SQL)
新建一个文件 short_url_db.sql
,内容如下:
-- 包含短地址映射表和访问统计表,
CREATE DATABASE IF NOT EXISTS short_url_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE short_url_db;
-- 1. 短地址映射表
CREATE TABLE IF NOT EXISTS short_urls (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
short_code VARCHAR(10) UNIQUE NOT NULL COMMENT '短代码',
long_url TEXT NOT NULL COMMENT '原始长地址',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX idx_short_code (short_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短地址映射表';
以下是对于代码的一些解释
CREATE DATABASE IF NOT EXISTS short_url_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 创建一个名为
short_url_db
的数据库。 IF NOT EXISTS
表示如果数据库已存在则不会报错。CHARACTER SET utf8mb4
设置字符集为utf8mb4,支持更多字符(如表情符号)。COLLATE utf8mb4_unicode_ci
设置排序规则为不区分大小写的Unicode排序。
USE short_url_db;
- 选择刚刚创建的
short_url_db
数据库,后续的表都建在这个库里。
CREATE TABLE IF NOT EXISTS short_urls (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
short_code VARCHAR(10) UNIQUE NOT NULL COMMENT '短代码',
long_url TEXT NOT NULL COMMENT '原始长地址',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX idx_short_code (short_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='短地址映射表';
创建短地址映射表 short_urls,用于存储短网址与原始长网址的映射关系。
字段说明:
id:主键,自增,唯一标识每条记录。
short_code:短网址代码,长度最多10个字符,唯一且不能为空。
long_url:原始长网址,类型为TEXT,不能为空。
created_at:记录创建时间,默认为当前时间。
idx_short_code:为 short_code 字段创建索引,加快查询速度。
表使用 InnoDB 引擎,字符集为 utf8mb4,表注释为“短地址映射表”
执行方法:
- 打开MySQL命令行或图形工具,登录后执行以上SQL,或用命令行导入:
mysql -u root -p < short_url_db.sql
将用户tom连接到数据库
grant all on short_url_db.* to tom@'%';
授权 tom 访问数据库 short_url_db 中所有的数据对象
验证用户能否连接
mysql -u tom -p
四、C语言主程序
新建 short_url_my.c
,内容如下:
// short.c
// 编译: gcc short.c -o short -lmysqlclient
// 简单短地址服务演示程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>
// 生成随机短码
void generate_code(char *code, int len) {
const char *charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (int i = 0; i < len; ++i) {
code[i] = charset[rand() % 62];
}
code[len] = '\0';
}
int main() {
MYSQL *conn;
conn = mysql_init(NULL);
if (!conn) {
fprintf(stderr, "初始化错误:%s\n", mysql_error(conn));
return 1;
}
// 修改为你的MySQL信息
char *host = "127.0.0.1";
char *user = "root";
char *passwd = "你的密码"; // <-- 这里填写你的MySQL密码
char *db = "short_url_db";
int port = 3306;
if (!mysql_real_connect(conn, host, user, passwd, db, port, NULL, 0)) {
fprintf(stderr, "连接失败:%s\n", mysql_error(conn));
mysql_close(conn);
return 1;
}
printf("连接成功\n");
int choice;
char long_url[2048], short_code[7], query[4096];
while (1) {
printf("\n1. 生成短地址\n2. 查询长地址\n3. 统计访问量\n4. 退出\n请选择:");
scanf("%d", &choice);
getchar(); // 吸收回车
if (choice == 1) {
printf("输入长地址:");
fgets(long_url, sizeof(long_url), stdin);
long_url[strcspn(long_url, "\n")] = 0;
// 防止短码重复:循环生成直到唯一
int is_unique = 0;
while (!is_unique) {
generate_code(short_code, 6);
sprintf(query, "SELECT id FROM short_urls WHERE short_code='%s'", short_code);
if (mysql_query(conn, query)) {
fprintf(stderr, "查询短码时出错:%s\n", mysql_error(conn));
return 1;
}
MYSQL_RES *res = mysql_store_result(conn);
if (res) {
if (mysql_num_rows(res) == 0) {
is_unique = 1; // 没有重复,可以用
}
mysql_free_result(res);
}
}
sprintf(query, "INSERT INTO short_urls(long_url, short_code) VALUES('%s', '%s')", long_url, short_code);
if (mysql_query(conn, query)) {
fprintf(stderr, "插入失败:%s\n", mysql_error(conn));
} else {
printf("短地址生成成功,短码为:%s\n", short_code);
}
} else if (choice == 2) {
printf("输入短码:");
scanf("%s", short_code);
sprintf(query, "SELECT id, long_url FROM short_urls WHERE short_code='%s'", short_code);
if (mysql_query(conn, query)) {
fprintf(stderr, "查询失败:%s\n", mysql_error(conn));
} else {
MYSQL_RES *res = mysql_store_result(conn);
MYSQL_ROW row = mysql_fetch_row(res);
if (row) {
printf("长地址为:%s\n", row[1]);
// 记录访问
sprintf(query, "INSERT INTO url_stats(short_url_id, ip_address, user_agent) VALUES(%s, '127.0.0.1', 'C-Client')", row[0]);
mysql_query(conn, query);
} else {
printf("未找到该短码\n");
}
mysql_free_result(res);
}
} else if (choice == 3) {
printf("输入短码:");
scanf("%s", short_code);
sprintf(query, "SELECT COUNT(*) FROM url_stats s JOIN short_urls u ON s.short_url_id=u.id WHERE u.short_code='%s'", short_code);
if (mysql_query(conn, query)) {
fprintf(stderr, "统计失败:%s\n", mysql_error(conn));
} else {
MYSQL_RES *res = mysql_store_result(conn);
MYSQL_ROW row = mysql_fetch_row(res);
printf("访问次数:%s\n", row ? row[0] : "0");
mysql_free_result(res);
}
} else if (choice == 4) {
break;
} else {
printf("无效选择\n");
}
}
mysql_close(conn);
return 0;
}
五、编译与运行
1. 编译
- Linux:
gcc short.c -o short -lmysqlclient
- Windows(假设已配置好MySQL开发库和MinGW-w64):
gcc short.c -o short.exe -I"C:\\Program Files\\MySQL\\MySQL Server 8.0\\include" -L"C:\\Program Files\\MySQL\\MySQL Server 8.0\\lib" -lmysqlclient
2. 运行
- Linux:
./short
- Windows:
运行成功!.\\short.exe
以我的csdn博客主页为例
项目完成!
六、如何查询使用完程序之后的数据库产生的数据
我相信很多同学做完了项目可能就忽略了这点,这就是纯C语言制作短地址项目与连接数据库最大的不同,他会将历史数据都存储在里面方便查看
使用MySQL命令行查询
登录MySQL
mysql -u tom -p
输入你的MySQL密码。
切换到你的数据库
USE short_url_db;
查询所有短地址映射
SELECT * FROM short_urls;
你会看到所有生成过的短码、原始长地址、创建时间等信息。
(这是我在刚刚生成的一条短地址)查询访问统计记录
SELECT * FROM url_stats;
你会看到每次访问的短码ID、访问时间、IP、User-Agent等信息。
根据短码查找原始网址
SELECT long_url FROM short_urls WHERE short_code='你的短码';
统计某个短码的访问次数
SELECT COUNT(*) FROM url_stats s JOIN short_urls u ON s.short_url_id=u.id WHERE u.short_code='你的短码';
- 所有历史数据都在MySQL数据库的
short_urls
和url_stats
两张表里。 - 只要数据库没删,数据都在,随时可查!
七、常见问题与排查
- 找不到mysql.h:开发库没装好或-I路径没写对。
- 找不到-lmysqlclient:库文件没装好或-L路径没写对。
- 连接失败:用户名、密码、数据库名不对,或MySQL服务没启动。
- 插入失败:Unknown column ‘user_id’ in ‘field list’:表结构和代码不一致,按本博客的SQL和代码即可避免。
短码重复:本文章中我已经进行了代码修改即采用伪代码逻辑,现在程序会在插入短码前自动检查数据库,确保不会生成重复的短码。如果生成的短码已存在,会自动重新生成,直到唯一为止。
网页逻辑检验:有输入以 http://、https:// 开头,或包含 .com、.cn、.net、.org 等常见域名后缀时,才会继续生成短码,否则会提示“输入的不是有效的网址,请重新输入!”并让用户重新输入。
八、项目结构参考
short_url_service/
├── db_setup_no_user.sql # 数据库建表脚本
├── short_url_my.c # C语言主程序
九、总结
本项目用最基础的C语言和MySQL数据库,带你体验了“短地址服务”的完整开发流程。
你学会了:
- 如何用SQL建表
- 如何用C语言连接和操作数据库
- 如何编译和运行本地C程序
- 如何查询使用C程序之后在数据库中存入的数据
建议:
- 进一步学习可以尝试加上用户系统、密码哈希、Web接口等功能。
祝你玩转C语言+数据库,迈出项目开发第一步!