2、数据库设计与建模:客户信息表结构设计
好,咱们直接进入正题。这一章聊的是数据库设计,说白了就是给客户数据「安个家」。我见过太多项目,前期表结构没想清楚,后期改得想哭。所以这一块,咱们一次搞定。
2.1 客户信息表:字段、类型与约束
先问个问题:客户信息表里到底该存什么?
我个人习惯,先把「必须有的」和「可能会有的」分开。必须有的,比如客户ID、姓名、联系方式。可能会有的,比如客户等级、备注信息。别一上来就搞几十个字段,后面维护起来头疼。
下面这张表,是我在多个项目中沉淀下来的核心结构。你直接拿去用,基本不会踩坑。
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | INTEGER | PRIMARY KEY, AUTO INCREMENT | 客户唯一标识,自增主键 |
| name | VARCHAR(100) | NOT NULL | 客户姓名,不能为空 |
| phone | VARCHAR(20) | UNIQUE, NOT NULL | 手机号,唯一且必填 |
| VARCHAR(100) | UNIQUE | 邮箱,可选但唯一 | |
| level | ENUM('普通','VIP','SVIP') | DEFAULT '普通' | 客户等级,默认普通 |
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP | 创建时间,自动生成 |
| updated_at | DATETIME | ON UPDATE CURRENT_TIMESTAMP | 更新时间,自动更新 |
2.2 使用 SQLAlchemy 进行 ORM 建模
表结构定好了,接下来用代码把它「翻译」出来。我用的是 SQLAlchemy,Python 生态里最成熟的 ORM 框架。你想想看,如果每次操作数据库都要写原生 SQL,那得多累?ORM 就是帮你把表变成类,把行变成对象。
下面是我常用的建模方式:
from sqlalchemy import Column, Integer, String, Enum, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import func
import enum
Base = declarative_base()
class CustomerLevel(enum.Enum):
NORMAL = "普通"
VIP = "VIP"
SVIP = "SVIP"
class Customer(Base):
__tablename__ = "customers"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(100), nullable=False, comment="客户姓名")
phone = Column(String(20), unique=True, nullable=False, comment="手机号")
email = Column(String(100), unique=True, comment="邮箱")
level = Column(Enum(CustomerLevel), default=CustomerLevel.NORMAL, comment="客户等级")
created_at = Column(DateTime, server_default=func.now(), comment="创建时间")
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now(), comment="更新时间")
def __repr__(self):
return f"<Customer(id={self.id}, name={self.name}, level={self.level})>"
这里有个细节:server_default 和 default 的区别。前者是在数据库层面设置默认值,后者是在 Python 层面。我建议时间字段用 server_default,这样即使你忘了传值,数据库也会自动补上。
2.3 数据库迁移与初始化
模型写好了,怎么把它变成真实的数据库表?手动建表?别闹了。我们用 Alembic,它是 SQLAlchemy 的官方迁移工具。
为什么要用迁移?因为项目是活的。今天加个字段,明天改个类型,总不能每次都删表重建吧?迁移工具能帮你记录每一次变更,还能回滚。
初始化步骤很简单:
- 安装 Alembic:
pip install alembic - 初始化:
alembic init alembic - 配置
alembic.ini中的数据库连接字符串 - 在
env.py中导入你的模型:from your_model import Base - 生成迁移脚本:
alembic revision --autogenerate -m "init" - 执行迁移:
alembic upgrade head
嗯,这里要注意一点:--autogenerate 虽然方便,但它不是万能的。比如字段重命名,它可能会识别成「删除旧字段 + 新增新字段」,导致数据丢失。我曾经就因为这个,把生产环境的一个字段名改错了,还好有备份。
upgrade。养成这个习惯,能省去很多麻烦。
最后,如果你只是想快速测试,也可以直接用 Base.metadata.create_all(engine) 来建表。但记住,这只适合开发环境。生产环境一定要用迁移工具。
好了,这一章的内容就这些。表结构设计、ORM 建模、迁移初始化,三步走完。下一章咱们聊聊如何用 Flask 把这些数据暴露成 API,到时候你就知道 ORM 有多香了。