当前位置:首页 > 问答 > 正文

数据库管理|表操作 C语言实现数据库table的增删改查,c 数据库 table使用方法解析

用C语言玩转数据库表操作:增删改查全攻略

场景引入:从纸质档案到数字管理

想象一下你正在经营一家小型书店,以前,你用厚厚的账本记录每本书的信息——书名、作者、价格、库存量,每次有新书到货,你得手动添加一行;书卖掉了,要划掉一行;价格调整时,还得用涂改液修改...

你决定用C语言把这些数据搬到电脑里管理,这不就是数据库表(table)的典型应用场景吗?让我们一起来看看如何用C语言实现数据库表的基本操作:增(Insert)、删(Delete)、改(Update)、查(Select),也就是俗称的"CRUD"操作。

基础准备:理解数据库表的结构

在开始编码前,我们需要明确几个概念:

// 以书店为例,我们定义一个简单的图书表结构
typedef struct {
    int id;          // 主键,唯一标识
    char title[100]; // 书名
    char author[50]; // 作者
    float price;     // 价格
    int stock;       // 库存量
} Book;

这个结构体就相当于数据库中的一个表(table),每个字段(成员变量)对应表中的一列,每本书的信息就是表中的一行记录。

创建表(Table Creation)

在真正的数据库系统中,我们会用CREATE TABLE语句,在C语言中,我们可以用文件来模拟:

#include <stdio.h>
#include <string.h>
// 初始化数据库文件(创建表)
void create_table(const char* filename) {
    FILE* file = fopen(filename, "wb"); // 以二进制写入模式打开
    if (file == NULL) {
        perror("无法创建表文件");
        return;
    }
    // 可以在这里写入文件头信息,比如版本号、记录数等
    int record_count = 0;
    fwrite(&record_count, sizeof(int), 1, file);
    fclose(file);
    printf("表创建成功: %s\n", filename);
}

插入数据(Insert)

新书到货了,我们需要把它添加到"表"中:

数据库管理|表操作 C语言实现数据库table的增删改查,c 数据库 table使用方法解析

// 向表中插入一条新记录
void insert_record(const char* filename, Book* new_book) {
    FILE* file = fopen(filename, "r+b"); // 读写模式打开
    if (file == NULL) {
        perror("无法打开表文件");
        return;
    }
    // 读取当前记录数
    int record_count;
    fread(&record_count, sizeof(int), 1, file);
    // 设置新记录的ID(自动递增)
    new_book->id = record_count + 1;
    // 移动到文件末尾
    fseek(file, 0, SEEK_END);
    // 写入新记录
    fwrite(new_book, sizeof(Book), 1, file);
    // 更新记录数
    record_count++;
    fseek(file, 0, SEEK_SET);
    fwrite(&record_count, sizeof(int), 1, file);
    fclose(file);
    printf("成功添加新书: %s\n", new_book->title);
}

使用示例:

Book new_book = {= "C程序设计语言",
    .author = "K&R",
    .price = 59.9,
    .stock = 10
};
insert_record("bookstore.dat", &new_book);

查询数据(Select)

顾客来问某本书的信息,我们需要从"表"中查找:

// 根据ID查询记录
Book* select_by_id(const char* filename, int id) {
    FILE* file = fopen(filename, "rb");
    if (file == NULL) {
        perror("无法打开表文件");
        return NULL;
    }
    // 读取记录数
    int record_count;
    fread(&record_count, sizeof(int), 1, file);
    if (id <= 0 || id > record_count) {
        printf("无效的ID\n");
        fclose(file);
        return NULL;
    }
    // 定位到指定记录
    fseek(file, sizeof(int) + (id-1)*sizeof(Book), SEEK_SET);
    Book* result = malloc(sizeof(Book));
    if (fread(result, sizeof(Book), 1, file) != 1) {
        free(result);
        fclose(file);
        return NULL;
    }
    fclose(file);
    return result;
}
// 打印查询结果
void print_book(Book* book) {
    if (book == NULL) {
        printf("未找到指定图书\n");
        return;
    }
    printf("ID: %d\n", book->id);
    printf("书名: %s\n", book->title);
    printf("作者: %s\n", book->author);
    printf("价格: %.2f\n", book->price);
    printf("库存: %d\n", book->stock);
    printf("-------------------\n");
}

使用示例:

Book* book = select_by_id("bookstore.dat", 1);
print_book(book);
free(book); // 记得释放内存

更新数据(Update)

某本书价格调整了,我们需要更新记录:

// 更新记录
void update_record(const char* filename, int id, Book* updated_book) {
    FILE* file = fopen(filename, "r+b");
    if (file == NULL) {
        perror("无法打开表文件");
        return;
    }
    // 读取记录数
    int record_count;
    fread(&record_count, sizeof(int), 1, file);
    if (id <= 0 || id > record_count) {
        printf("无效的ID\n");
        fclose(file);
        return;
    }
    // 定位到指定记录
    fseek(file, sizeof(int) + (id-1)*sizeof(Book), SEEK_SET);
    // 保留原始ID
    updated_book->id = id;
    // 更新记录
    if (fwrite(updated_book, sizeof(Book), 1, file) != 1) {
        perror("更新记录失败");
    } else {
        printf("成功更新ID为%d的记录\n", id);
    }
    fclose(file);
}

使用示例:

Book updated_info = {= "C程序设计语言(新版)",
    .author = "K&R",
    .price = 69.9,  // 价格从59.9调整到69.9
    .stock = 8     // 卖出了2本
};
update_record("bookstore.dat", 1, &updated_info);

删除数据(Delete)

某本书不再销售了,我们需要从"表"中删除:

// 删除记录(逻辑删除)
void delete_record(const char* filename, int id) {
    FILE* file = fopen(filename, "r+b");
    if (file == NULL) {
        perror("无法打开表文件");
        return;
    }
    // 读取记录数
    int record_count;
    fread(&record_count, sizeof(int), 1, file);
    if (id <= 0 || id > record_count) {
        printf("无效的ID\n");
        fclose(file);
        return;
    }
    // 定位到指定记录
    fseek(file, sizeof(int) + (id-1)*sizeof(Book), SEEK_SET);
    // 标记为删除(这里简单地将ID设为-1作为删除标记)
    Book deleted_book;
    fread(&deleted_book, sizeof(Book), 1, file);
    deleted_book.id = -1;
    fseek(file, -sizeof(Book), SEEK_CUR);
    fwrite(&deleted_book, sizeof(Book), 1, file);
    fclose(file);
    printf("已标记删除ID为%d的记录\n", id);
}

注意:在实际应用中,我们通常不会真正从文件中删除数据,而是采用"逻辑删除"(标记删除)的方式,或者使用更复杂的数据结构来管理。

数据库管理|表操作 C语言实现数据库table的增删改查,c 数据库 table使用方法解析

高级查询:条件搜索

顾客想找所有价格低于50元的书,我们需要实现条件查询:

// 条件查询(价格低于指定值)
void select_by_price(const char* filename, float max_price) {
    FILE* file = fopen(filename, "rb");
    if (file == NULL) {
        perror("无法打开表文件");
        return;
    }
    // 读取记录数
    int record_count;
    fread(&record_count, sizeof(int), 1, file);
    printf("价格低于%.2f的图书:\n", max_price);
    printf("-------------------\n");
    Book current;
    int found = 0;
    for (int i = 0; i < record_count; i++) {
        fread(&current, sizeof(Book), 1, file);
        // 跳过已删除的记录
        if (current.id == -1) continue;
        if (current.price < max_price) {
            print_book(&current);
            found++;
        }
    }
    if (!found) {
        printf("未找到符合条件的图书\n");
    }
    fclose(file);
}

使用示例:

select_by_price("bookstore.dat", 50.0);

实用技巧与注意事项

  1. 错误处理:实际应用中要添加更完善的错误检查和处理
  2. 性能优化:对于大型表,可以考虑索引技术加快查询速度
  3. 并发控制:多线程/进程访问时需要加锁
  4. 数据持久化:定期备份重要数据
  5. 内存管理:查询返回的动态内存要记得释放

完整示例:书店管理系统

把上面的功能整合起来,我们可以构建一个简单的命令行书店管理系统:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
    int id;
    char title[100];
    char author[50];
    float price;
    int stock;
} Book;
// 省略之前的函数实现...
int main() {
    const char* filename = "bookstore.dat";
    // 初始化表(如果不存在)
    FILE* test = fopen(filename, "rb");
    if (test == NULL) {
        create_table(filename);
    } else {
        fclose(test);
    }
    // 简单命令行界面
    int choice;
    do {
        printf("\n书店管理系统\n");
        printf("1. 添加新书\n");
        printf("2. 查询图书\n");
        printf("3. 更新图书信息\n");
        printf("4. 删除图书\n");
        printf("5. 按价格搜索\n");
        printf("0. 退出\n");
        printf("请选择操作: ");
        scanf("%d", &choice);
        switch (choice) {
            case 1: {
                Book new_book;
                printf("请输入书名: ");
                scanf(" %[^\n]", new_book.title);
                printf("请输入作者: ");
                scanf(" %[^\n]", new_book.author);
                printf("请输入价格: ");
                scanf("%f", &new_book.price);
                printf("请输入库存量: ");
                scanf("%d", &new_book.stock);
                insert_record(filename, &new_book);
                break;
            }
            case 2: {
                int id;
                printf("请输入要查询的图书ID: ");
                scanf("%d", &id);
                Book* book = select_by_id(filename, id);
                print_book(book);
                if (book != NULL) free(book);
                break;
            }
            case 3: {
                int id;
                printf("请输入要更新的图书ID: ");
                scanf("%d", &id);
                Book updated;
                printf("请输入新书名: ");
                scanf(" %[^\n]", updated.title);
                printf("请输入新作者: ");
                scanf(" %[^\n]", updated.author);
                printf("请输入新价格: ");
                scanf("%f", &updated.price);
                printf("请输入新库存量: ");
                scanf("%d", &updated.stock);
                update_record(filename, id, &updated);
                break;
            }
            case 4: {
                int id;
                printf("请输入要删除的图书ID: ");
                scanf("%d", &id);
                delete_record(filename, id);
                break;
            }
            case 5: {
                float price;
                printf("请输入最高价格: ");
                scanf("%f", &price);
                select_by_price(filename, price);
                break;
            }
            case 0:
                printf("感谢使用书店管理系统\n");
                break;
            default:
                printf("无效的选择,请重新输入\n");
        }
    } while (choice != 0);
    return 0;
}

通过这个简单的例子,我们展示了如何用C语言实现数据库表的基本操作,虽然这只是一个简化版本,但它涵盖了数据库系统的核心概念:

  1. 表的创建与结构定义
  2. 记录的插入(Insert)
  3. 记录的查询(Select)
  4. 记录的更新(Update)
  5. 记录的删除(Delete)
  6. 条件查询的实现

在实际的数据库系统中,这些操作会更加复杂和高效,但基本原理是相通的,理解这些基础操作后,你就能更好地使用真正的数据库系统,或者根据需求开发自己的轻量级数据存储解决方案。

好的数据库设计是应用成功的关键,在你开始编码前,花时间规划好表结构和关系,这将为你省去后续许多麻烦。

发表评论