当前位置:首页 > 数据库 > 正文

一个简单的数据库代码怎么写

Python结合SQLite,先导入sqlite3库,创建连接与游标,执行建表语句如 CREATE TABLE tb(id INT PRIMARY KEY, name TEXT),再增删改查

理解需求与选择工具

要创建一个“简单”的数据库系统,首先需明确目标:存储结构化数据(如用户信息、商品清单)、支持增删改查操作(CRUD),对于初学者而言,推荐使用轻量级关系型数据库管理系统(RDBMS),SQLite(无需安装服务器,文件即数据库)或 MySQL/PostgreSQL(适合进阶练习),这里以 Python + SQLite 组合为例,因其跨平台且语法直观。

关键技术栈对比表:

组件 推荐方案 优势
编程语言 Python 语法简洁,生态丰富(如Pandas)
数据库引擎 SQLite 零配置,嵌入到应用程序中
ORM框架 原生SQL / peewee库 直接控制SQL或简化对象映射

环境准备与基础架构搭建

安装依赖库

若使用Python开发,需确保已安装sqlite3模块(Python标准库自带),可选装第三方库提升效率:

pip install pandas      # 用于数据分析辅助验证结果
pip install prettytable # 美化终端输出表格展示

设计数据模型

假设我们要管理一本书籍收藏夹,核心字段包括:ID(主键)、书名、作者、出版年份、评分,对应的SQL建表语句如下:

CREATE TABLE IF NOT EXISTS books (
    id INTEGER PRIMARY KEY AUTOINCREMENT,TEXT NOT NULL,
    author TEXT,
    year_published INTEGER,
    rating REAL CHECK(rating >= 0 AND rating <= 10)
);
  • 约束说明NOT NULL确保必填项;CHECK限制评分范围为[0,10]。

核心功能实现代码详解

以下是完整的Python脚本示例,包含连接数据库、执行CRUD操作及异常处理:

import sqlite3
from contextlib import closing
import sys
class BookDatabase:
    def __init__(self, db_name='library.db'):
        self.conn = None
        self.db_path = db_name
        self._initialize_schema()
    def _initialize_schema(self):
        """首次运行时自动创建表结构"""
        with closing(sqlite3.connect(self.db_path)) as conn:
            cursor = conn.cursor()
            cursor.execute('''
                CREATE TABLE IF NOT EXISTS books (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    title TEXT NOT NULL,
                    author TEXT,
                    year_published INTEGER,
                    rating REAL CHECK(rating >= 0 AND rating <= 10)
                );
            ''')
            conn.commit()
    def add_book(self, title, author, year, rating):
        """插入新书记录"""
        try:
            with closing(sqlite3.connect(self.db_path)) as conn:
                cursor = conn.cursor()
                cursor.execute(
                    "INSERT INTO books (title, author, year_published, rating) VALUES (?, ?, ?, ?)",
                    (title, author, year, float(rating))
                )
                conn.commit()
                return cursor.lastrowid  # 返回自增ID
        except ValueError as e:
            print(f"输入错误: {str(e)}", file=sys.stderr)
            return None
        except sqlite3.IntegrityError as e:
            print(f"违反唯一性约束或其他完整性规则: {str(e)}", file=sys.stderr)
            return None
    def delete_book(self, book_id):
        """根据ID删除指定书籍"""
        affected_rows = 0
        with closing(sqlite3.connect(self.db_path)) as conn:
            cursor = conn.cursor()
            affected_rows = cursor.execute(
                "DELETE FROM books WHERE id = ?", (book_id,)
            ).rowcount
            conn.commit()
        return affected_rows > 0
    def update_book(self, book_id, new_title=None, new_author=None, new_year=None, new_rating=None):
        """动态更新部分字段"""
        params = []
        set_clauses = []
        if new_title is not None:
            set_clauses.append("title = ?")
            params.append(new_title)
        if new_author is not None:
            set_clauses.append("author = ?")
            params.append(new_author)
        if new_year is not None:
            set_clauses.append("year_published = ?")
            params.append(new_year)
        if new_rating is not None:
            set_clauses.append("rating = ?")
            params.append(float(new_rating))
        if not set_clauses:
            raise ValueError("至少提供一个可更新的字段")
        sql = f"UPDATE books SET {', '.join(set_clauses)} WHERE id = ?"
        params.append(book_id)
        with closing(sqlite3.connect(self.db_path)) as conn:
            cursor = conn.cursor()
            cursor.execute(sql, params)
            conn.commit()
            return cursor.rowcount == 1
    def list_all_books(self):
        """查询所有书籍并以易读格式返回"""
        result = []
        with closing(sqlite3.connect(self.db_path)) as conn:
            conn.row_factory = sqlite3.Row  # 允许按列名访问行数据
            cursor = conn.cursor()
            for row in cursor.execute("SELECT  FROM books ORDER BY id"):
                result.append({
                    'ID': row['id'],
                    '书名': row['title'],
                    '作者': row['author'],
                    '出版年份': row['year_published'],
                    '评分': round(row['rating'], 1)
                })
        return result
# 测试用例演示
if __name__ == "__main__":
    db = BookDatabase()
    # 添加示例数据
    db.add_book("三体", "刘慈欣", 2006, 9.5)
    db.add_book("百年孤独", "加西亚·马尔克斯", 1967, 9.8)
    # 更新第一条记录的评分
    db.update_book(1, new_rating=9.7)
    # 删除第二条记录
    db.delete_book(2)
    # 打印当前所有书籍
    books = db.list_all_books()
    from prettytable importPrettyTable
    tbl = PrettyTable(["ID", "书名", "作者", "出版年份", "评分"])
    for b in books:
        tbl.add_row([b['ID'], b['书名'], b['作者'], b['出版年份'], b['评分']])
    print(tbl)

代码逐行解析:

  1. 类初始化BookDatabase类封装了所有数据库交互逻辑,构造函数自动调用_initialize_schema()方法确保表存在。
  2. 事务管理:使用with closing()上下文管理器自动提交/回滚事务,避免手动处理连接关闭问题。
  3. 参数化查询:所有SQL语句均使用问号占位符(),防止SQL注入攻击,例如插入操作中的VALUES (?, ?, ?, ?)
  4. 动态更新逻辑update_book()方法允许只修改部分字段,通过条件判断构建SET子句。
  5. 错误处理:捕获类型转换异常(如非数字的评分)、主键冲突等常见错误并给出友好提示。
  6. 结果格式化:利用sqlite3.Row工厂将查询结果转为字典形式,配合prettytable库生成美观的控制台表格。

扩展建议与最佳实践

  1. 索引优化:频繁查询的列应建立索引以提高性能,例如为title添加全文搜索索引:
    CREATE INDEX idx_title ON books(title);
  2. 备份机制:定期导出SQL脚本或复制物理文件进行备份,SQLite可通过命令行工具实现:
    sqlite3 library.db .dump > backup_$(date +%Y%m%d).sql
  3. 迁移工具:生产环境中推荐使用Alembic等版本控制工具管理数据库结构变更。
  4. 安全加固:限制用户权限(如只读账户)、启用WAL模式提升并发写入能力。

FAQs常见问题解答

Q1: 如果运行代码时出现“OperationalError: unable to open database file”,该怎么办?

A: 此错误通常由以下原因导致:①文件路径无写入权限(检查目录是否存在且用户有读写权);②跨设备链接符号链接失效(确保数据库文件与应用程序在同一磁盘分区),解决方案包括:切换到绝对路径指定数据库位置,或手动创建空文件后赋予适当权限,例如在Linux下执行:touch /path/to/library.db && chmod 664 /path/to/library.db

Q2: 如何将现有CSV文件中的数据批量导入到这个数据库中?

A: 可以使用Python的csv模块结合事务批量插入,示例代码如下:

import csv
with open('books.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    with closing(sqlite3.connect(self.db_path)) as conn:
        cursor = conn.cursor()
        for row in reader:
            cursor.execute('''
                INSERT INTO books (title, author, year_published, rating)
                VALUES (?, ?, ?, ?)
            ''', (row['title'], row['author'], int(row['year']), float(row['rating'])))
        conn.commit()

注意需确保CSV列名与数据库字段完全匹配,并对数值类型做显式转换

一个简单的数据库代码怎么写  第1张

0