签入版本

This commit is contained in:
2026-09-12 23:12:15 +08:00
commit 91998056ca
1841 changed files with 341325 additions and 0 deletions
@@ -0,0 +1,308 @@
# 第四章 架构设计 - 数据库设计
## 4.1 数据库设计概述
项目使用 MySQL 8.0 作为主数据库,通过 Django ORM 进行数据访问。所有业务表继承 BaseModel 抽象基类,自动获得 6 个通用字段。
## 4.2 通用字段规范
### BaseModel 字段定义
所有业务表继承 `BaseModel`(`application/models.py`),自动包含以下字段:
```python
class BaseModel(models.Model):
"""基础模型抽象类"""
id = models.AutoField(
auto_created=True, primary_key=True, serialize=False,
verbose_name='主键ID', db_comment='主键ID'
)
create_user = models.CharField(
null=True, max_length=50, default=None, db_default=None,
verbose_name='创建人', db_comment='创建人'
)
create_time = models.DateTimeField(
null=True, auto_now_add=True,
verbose_name="创建时间", db_comment='创建时间'
)
update_user = models.CharField(
null=True, max_length=50, default=None, db_default=None,
verbose_name='更新人', db_comment='更新人'
)
update_time = models.DateTimeField(
null=True, auto_now=True,
verbose_name="更新时间", db_comment='更新时间'
)
is_delete = models.BooleanField(
default=0, db_default=0,
verbose_name="逻辑删除",
db_comment='逻辑删除:0-正常 1-已删除'
)
class Meta:
abstract = True
```
### 字段说明
| 字段 | 类型 | 约束 | 默认值 | 说明 |
|------|------|------|--------|------|
| `id` | AutoField | PK, 自增 | - | 主键ID |
| `create_user` | CharField(50) | NULL | None | 创建人用户名 |
| `create_time` | DateTimeField | NULL | auto_now_add | 创建时间,自动填充 |
| `update_user` | CharField(50) | NULL | None | 更新人用户名 |
| `update_time` | DateTimeField | NULL | auto_now | 更新时间,自动刷新 |
| `is_delete` | BooleanField | NOT NULL | 0 | 逻辑删除标识 |
### 字段自动管理
- `create_time`:使用 `auto_now_add=True`,仅在创建时自动设置当前时间
- `update_time`:使用 `auto_now=True`,每次保存时自动更新为当前时间
- `create_user` 和 `update_user`:需要业务代码手动赋值
## 4.3 表名命名规范
### 表前缀配置
所有业务表使用统一的前缀,通过 `config/env.py` 配置:
```python
DATABASE_PREFIX = os.getenv('DATABASE_PREFIX', "django_")
```
### 表名生成函数
使用 `get_table_name()` 函数自动生成带前缀的表名:
```python
# utils/common.py
def get_table_name(name):
"""获取带前缀的表名"""
from config.env import DATABASE_PREFIX
return f"{DATABASE_PREFIX}{name}"
```
### 表名示例
| 模块 | 配置的表名 | 实际表名 |
|------|-----------|----------|
| 案例 | `get_table_name('example')` | `django_example` |
| 用户 | `get_table_name('user')` | `django_user` |
| 角色 | `get_table_name('role')` | `django_role` |
| 菜单 | `get_table_name('menu')` | `django_menu` |
| 部门 | `get_table_name('dept')` | `django_dept` |
| 字典 | `get_table_name('dict')` | `django_dict` |
## 4.4 软删除设计
### 设计原理
系统采用软删除策略,所有业务表包含 `is_delete` 字段:
- `is_delete = 0`:正常记录(默认值)
- `is_delete = 1`:已删除记录
### 软删除实现
```python
# Service层删除操作
def delete_examples(instance_ids):
"""删除案例(批量删除)"""
id_list = [int(id_str.strip())
for id_str in instance_ids.split(',') if id_str.strip()]
# 批量更新删除标识(逻辑删除)
updated_count = Example.objects.filter(
id__in=id_list, is_delete=False
).update(is_delete=True)
return R.ok(msg=f"本次共删除{updated_count}条数据")
```
### 查询过滤
所有查询都需要过滤已删除的记录:
```python
# 分页查询
query = Example.objects.filter(is_delete=False)
# 详情查询
instance = Example.objects.filter(id=id, is_delete=False).first()
# 列表查询
queryset = Example.objects.filter(is_delete=False, status=1)
```
### 软删除优势
| 优势 | 说明 |
|------|------|
| 数据可恢复 | 误删除的数据可以恢复 |
| 审计追踪 | 保留删除记录的历史 |
| 关联完整 | 不破坏外键关联关系 |
| 操作安全 | 避免物理删除造成的数据丢失 |
## 4.5 字段顺序重排
### 设计目标
通过 Django 的 `class_prepared` 信号,自动将 BaseModel 的公共字段移到业务字段之后,使数据库表结构更清晰。
### 实现代码
```python
# application/models.py
BASE_FIELD_NAMES = ['id', 'create_user', 'create_time',
'update_user', 'update_time', 'is_delete']
def _reorder_fields(sender, **kwargs):
"""信号处理函数:重排模型字段顺序"""
if not hasattr(sender, '_meta') or sender._meta.abstract:
return
# 检查是否有公共字段
has_base_fields = any(
f.name in BASE_FIELD_NAMES for f in sender._meta.local_fields
)
if not has_base_fields:
return
# 分离公共字段和业务字段
base_fields = []
business_fields = []
for field in sender._meta.local_fields:
if field.name in BASE_FIELD_NAMES:
base_fields.append(field)
else:
business_fields.append(field)
# 重新排列:业务字段在前,公共字段在后
sender._meta.local_fields = business_fields + base_fields
# 注册信号处理器
class_prepared.connect(_reorder_fields)
```
### 重排效果
```
重排前:id, create_user, create_time, name, status, sort, update_user, update_time, is_delete
重排后:name, status, sort, id, create_user, create_time, update_user, update_time, is_delete
```
## 4.6 数据库表结构示例
### 案例表 (django_example)
```sql
CREATE TABLE `django_example` (
`name` varchar(100) NOT NULL COMMENT '案例名称',
`avatar` varchar(255) DEFAULT NULL COMMENT '案例图片',
`type` int NOT NULL COMMENT '案例类型:1-类型1 2-类型2 3-类型3 4-类型4',
`status` int NOT NULL COMMENT '案例状态:1-正常 2-禁用',
`sort` int NOT NULL COMMENT '排序',
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`create_user` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime(6) DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime(6) DEFAULT NULL COMMENT '更新时间',
`is_delete` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-正常 1-已删除',
PRIMARY KEY (`id`),
KEY `idx_example_name` (`name`)
) ENGINE=InnoDB COMMENT='案例表';
```
### 用户表 (django_user)
```sql
CREATE TABLE `django_user` (
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(128) NOT NULL COMMENT '密码',
`realname` varchar(50) DEFAULT NULL COMMENT '真实姓名',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`status` int NOT NULL DEFAULT 1 COMMENT '状态:1-正常 2-禁用',
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`create_user` varchar(50) DEFAULT NULL COMMENT '创建人',
`create_time` datetime(6) DEFAULT NULL COMMENT '创建时间',
`update_user` varchar(50) DEFAULT NULL COMMENT '更新人',
`update_time` datetime(6) DEFAULT NULL COMMENT '更新时间',
`is_delete` tinyint(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-正常 1-已删除',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_user_username` (`username`)
) ENGINE=InnoDB COMMENT='用户表';
```
## 4.7 字段类型映射
| Django 字段 | MySQL 类型 | 说明 |
|-------------|-----------|------|
| `AutoField` | `INT AUTO_INCREMENT` | 自增主键 |
| `CharField` | `VARCHAR(n)` | 变长字符串 |
| `TextField` | `LONGTEXT` | 长文本 |
| `IntegerField` | `INT` | 整数 |
| `BooleanField` | `TINYINT(1)` | 布尔值 |
| `DateTimeField` | `DATETIME(6)` | 日期时间 |
| `DecimalField` | `DECIMAL(p,s)` | 精确小数 |
| `ImageField` | `VARCHAR(255)` | 图片路径 |
| `ForeignKey` | `INT` + 外键约束 | 外键关联 |
## 4.8 索引设计规范
### 自动索引
- 主键 `id` 自动创建主键索引
- 唯一约束字段自动创建唯一索引
### 手动索引
在模型定义中使用 `db_index=True` 为常用查询字段创建索引:
```python
name = models.CharField(
max_length=100,
db_index=True, # 创建索引
verbose_name="案例名称"
)
```
### 索引命名规范
```
idx_<表名>_<字段名>
```
示例:`idx_example_name`、`idx_user_username`
## 4.9 数据库迁移
### 生成迁移文件
```bash
python manage.py makemigrations <app_name>
```
### 执行迁移
```bash
python manage.py migrate
```
### 代码生成器自动迁移
代码生成器在生成新模块时会自动执行迁移:
```python
# generator_config.py
os.system('python manage.py makemigrations')
os.system('python manage.py migrate')
```