# 宁夏智慧养殖监管平台 数据库设计文档

## 版本历史

| 版本 | 日期 | 作者 | 描述 |
|------|------|------|------|
| v1.0 | 2025-01-19 | 开发团队 | 初始版本，完整数据库设计 |

## 1. 数据库概述

### 1.1 设计原则

**数据完整性原则：**
- 实体完整性：每个表都有主键
- 参照完整性：外键约束确保数据一致性
- 域完整性：字段类型和约束确保数据有效性

**性能优化原则：**
- 合理的索引设计
- 分区表设计（大数据量表）
- 查询优化友好的表结构

**扩展性原则：**
- 预留扩展字段
- 模块化表设计
- 支持水平和垂直扩展

### 1.2 技术规范

**数据库引擎：** MySQL 8.0+
**字符集：** utf8mb4
**排序规则：** utf8mb4_unicode_ci
**存储引擎：** InnoDB
**事务支持：** ACID 完整性

## 2. 数据库架构设计

### 2.1 逻辑架构

```
宁夏智慧养殖监管平台数据库
├── 用户权限模块
│   ├── users (用户表)
│   ├── roles (角色表)
│   ├── permissions (权限表)
│   ├── role_permissions (角色权限关联表)
│   └── menu_permissions (菜单权限表)
├── 养殖场管理模块
│   ├── farms (养殖场表)
│   ├── animals (动物信息表)
│   ├── iot_cattle (物联网牛只表)
│   ├── cattle_types (牛只品种表)
│   └── cattle_users (牛只用户表)
├── 设备管理模块
│   ├── devices (设备表)
│   ├── sensor_data (传感器数据表)
│   ├── iot_xq_clients (物联网客户端表)
│   ├── iot_jbq_servers (物联网服务器表)
│   └── iot_jbq_clients (物联网客户端表)
├── 圈舍管理模块
│   ├── pens (圈舍表)
│   ├── cattle_pens (牛只圈舍表)
│   ├── cattle_batches (牛只批次表)
│   └── cattle_batch_animals (批次动物关联表)
├── 电子围栏模块
│   ├── electronic_fences (电子围栏表)
│   └── electronic_fence_points (围栏点表)
├── 业务记录模块
│   ├── cattle_transfer_records (牛只转移记录表)
│   ├── cattle_exit_records (牛只出场记录表)
│   ├── alerts (预警表)
│   └── operation_logs (操作日志表)
├── 商城模块
│   ├── products (产品表)
│   ├── orders (订单表)
│   └── order_items (订单项表)
└── 系统配置模块
    ├── system_configs (系统配置表)
    └── form_logs (表单日志表)
```

### 2.2 物理架构

**主从复制架构：**
- 主库：负责写操作和实时查询
- 从库：负责读操作和数据备份
- 读写分离：提高系统并发能力

**分库分表策略：**
- 按业务模块分库
- 大数据量表按时间分表（如传感器数据表）
- 按养殖场ID分表（如动物信息表）

## 3. 核心数据表设计

### 3.1 用户权限模块

#### 3.1.1 用户表 (users)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 用户ID（主键）|
| username | VARCHAR | 50 | NO | - | 用户名（唯一）|
| email | VARCHAR | 100 | NO | - | 邮箱（唯一）|
| password | VARCHAR | 255 | NO | - | 密码（加密存储）|
| phone | VARCHAR | 20 | YES | NULL | 手机号 |
| avatar | VARCHAR | 255 | YES | NULL | 头像URL |
| roles | INT | - | YES | 2 | 角色ID（外键）|
| status | ENUM | - | NO | 'active' | 状态：active/inactive/suspended |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

**索引设计：**
```sql
PRIMARY KEY (id)
UNIQUE KEY uk_username (username)
UNIQUE KEY uk_email (email)
INDEX idx_roles (roles)
INDEX idx_status (status)
```

#### 3.1.2 角色表 (roles)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 角色ID（主键）|
| name | VARCHAR | 50 | NO | - | 角色名称（唯一）|
| description | TEXT | - | YES | NULL | 角色描述 |
| status | ENUM | - | NO | 'active' | 状态：active/inactive |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

### 3.2 养殖场管理模块

#### 3.2.1 养殖场表 (farms)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 养殖场ID（主键）|
| name | VARCHAR | 100 | NO | - | 养殖场名称 |
| type | VARCHAR | 50 | NO | - | 养殖场类型 |
| location | JSON | - | NO | {} | 地理位置（经纬度）|
| address | VARCHAR | 255 | YES | NULL | 详细地址 |
| contact | VARCHAR | 50 | YES | NULL | 联系人 |
| phone | VARCHAR | 20 | YES | NULL | 联系电话 |
| status | ENUM | - | NO | 'active' | 状态：active/inactive/maintenance |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

**索引设计：**
```sql
PRIMARY KEY (id)
INDEX idx_name (name)
INDEX idx_type (type)
INDEX idx_status (status)
```

#### 3.2.2 动物信息表 (animals)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | BIGINT | - | NO | AUTO_INCREMENT | 动物ID（主键）|
| collar_number | VARCHAR | 50 | NO | - | 项圈编号 |
| ear_tag | VARCHAR | 50 | YES | NULL | 动物耳号 |
| animal_type | INT | - | NO | 1 | 动物类型：1-牛，2-羊，3-猪，4-马 |
| breed | INT | - | NO | 1 | 品种ID |
| category | INT | - | NO | 1 | 品类：1-乳肉兼用，2-肉用，3-乳用，4-种用 |
| source_type | INT | - | NO | 1 | 来源类型：1-合作社，2-农户，3-养殖场，4-进口 |
| birth_date | DATE | - | YES | NULL | 出生日期 |
| birth_weight | DECIMAL | 10,2 | YES | 0.00 | 出生体重 |
| weaning_weight | DECIMAL | 10,2 | YES | 0.00 | 断奶体重 |
| weaning_age | INT | - | YES | 0 | 断奶日龄 |
| entry_date | DATE | - | YES | NULL | 入场日期 |
| calving_count | INT | - | YES | 0 | 历史已产胎次 |
| left_teat_count | INT | - | YES | NULL | 乳头数(左) |
| right_teat_count | INT | - | YES | NULL | 乳头数(右) |
| farm_id | INT | - | YES | NULL | 农场ID（外键）|
| pen_id | INT | - | YES | NULL | 圈舍ID（外键）|
| status | INT | - | NO | 1 | 状态：1-正常，2-生病，3-死亡 |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

**索引设计：**
```sql
PRIMARY KEY (id)
INDEX idx_collar_number (collar_number)
INDEX idx_ear_tag (ear_tag)
INDEX idx_farm_id (farm_id)
INDEX idx_pen_id (pen_id)
INDEX idx_animal_type (animal_type)
INDEX idx_status (status)
```

#### 3.2.3 物联网牛只表 (iot_cattle)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | BIGINT | - | NO | AUTO_INCREMENT | 牛只ID（主键）|
| orgId | INT | - | YES | NULL | 组织ID（外键到farms）|
| penId | INT | - | YES | NULL | 圈舍ID（外键）|
| batchId | INT | - | YES | NULL | 批次ID（外键）|
| varieties | INT | - | YES | NULL | 品种ID（外键）|
| strain | INT | - | YES | NULL | 品系ID（外键）|
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

### 3.3 设备管理模块

#### 3.3.1 设备表 (devices)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 设备ID（主键）|
| name | VARCHAR | 100 | NO | - | 设备名称 |
| type | VARCHAR | 50 | NO | - | 设备类型 |
| model | VARCHAR | 100 | YES | NULL | 设备型号 |
| serial_number | VARCHAR | 100 | YES | NULL | 设备序列号 |
| farm_id | INT | - | YES | NULL | 农场ID（外键）|
| location | JSON | - | YES | NULL | 设备位置 |
| status | ENUM | - | NO | 'active' | 状态：active/inactive/maintenance |
| last_heartbeat | TIMESTAMP | - | YES | NULL | 最后心跳时间 |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

#### 3.3.2 传感器数据表 (sensor_data)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | BIGINT | - | NO | AUTO_INCREMENT | 数据ID（主键）|
| device_id | INT | - | NO | - | 设备ID（外键）|
| farm_id | INT | - | YES | NULL | 农场ID（外键）|
| sensor_type | VARCHAR | 50 | NO | - | 传感器类型 |
| value | DECIMAL | 10,4 | NO | - | 传感器数值 |
| unit | VARCHAR | 20 | YES | NULL | 数值单位 |
| timestamp | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 数据时间戳 |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |

**分表策略：**
- 按月分表：sensor_data_YYYYMM
- 保留最近12个月数据，历史数据归档

### 3.4 圈舍管理模块

#### 3.4.1 牛只圈舍表 (cattle_pens)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 圈舍ID（主键）|
| name | VARCHAR | 100 | NO | - | 圈舍名称 |
| farm_id | INT | - | NO | - | 农场ID（外键）|
| capacity | INT | - | NO | 0 | 容量 |
| current_count | INT | - | NO | 0 | 当前数量 |
| pen_type | VARCHAR | 50 | YES | NULL | 圈舍类型 |
| area | DECIMAL | 10,2 | YES | NULL | 面积（平方米）|
| status | ENUM | - | NO | 'active' | 状态：active/inactive/maintenance |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

#### 3.4.2 牛只批次表 (cattle_batches)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 批次ID（主键）|
| batch_name | VARCHAR | 100 | NO | - | 批次名称 |
| farm_id | INT | - | NO | - | 农场ID（外键）|
| batch_date | DATE | - | NO | - | 批次日期 |
| total_count | INT | - | NO | 0 | 总数量 |
| current_count | INT | - | NO | 0 | 当前数量 |
| status | ENUM | - | NO | 'active' | 状态：active/completed/cancelled |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

### 3.5 电子围栏模块

#### 3.5.1 电子围栏表 (electronic_fences)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 围栏ID（主键）|
| name | VARCHAR | 100 | NO | - | 围栏名称 |
| farm_id | INT | - | NO | - | 农场ID（外键）|
| fence_type | VARCHAR | 50 | NO | - | 围栏类型 |
| status | ENUM | - | NO | 'active' | 状态：active/inactive |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

#### 3.5.2 围栏点表 (electronic_fence_points)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 点ID（主键）|
| fence_id | INT | - | NO | - | 围栏ID（外键）|
| latitude | DECIMAL | 10,8 | NO | - | 纬度 |
| longitude | DECIMAL | 11,8 | NO | - | 经度 |
| point_order | INT | - | NO | - | 点序号 |
| created_by | INT | - | YES | NULL | 创建人（外键）|
| updated_by | INT | - | YES | NULL | 更新人（外键）|
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

### 3.6 业务记录模块

#### 3.6.1 预警表 (alerts)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | INT | - | NO | AUTO_INCREMENT | 预警ID（主键）|
| farm_id | INT | - | YES | NULL | 农场ID（外键）|
| device_id | INT | - | YES | NULL | 设备ID（外键）|
| alert_type | VARCHAR | 50 | NO | - | 预警类型 |
| level | ENUM | - | NO | 'low' | 预警级别：low/medium/high/critical |
| title | VARCHAR | 200 | NO | - | 预警标题 |
| message | TEXT | - | YES | NULL | 预警消息 |
| status | ENUM | - | NO | 'pending' | 状态：pending/acknowledged/resolved |
| acknowledged_at | TIMESTAMP | - | YES | NULL | 确认时间 |
| resolved_at | TIMESTAMP | - | YES | NULL | 解决时间 |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 更新时间 |

#### 3.6.2 操作日志表 (operation_logs)

| 字段名 | 类型 | 长度 | 是否为空 | 默认值 | 说明 |
|--------|------|------|----------|--------|------|
| id | BIGINT | - | NO | AUTO_INCREMENT | 日志ID（主键）|
| user_id | INT | - | YES | NULL | 用户ID（外键）|
| action | VARCHAR | 100 | NO | - | 操作动作 |
| resource | VARCHAR | 100 | NO | - | 操作资源 |
| resource_id | INT | - | YES | NULL | 资源ID |
| details | JSON | - | YES | NULL | 操作详情 |
| ip_address | VARCHAR | 45 | YES | NULL | IP地址 |
| user_agent | TEXT | - | YES | NULL | 用户代理 |
| created_at | TIMESTAMP | - | NO | CURRENT_TIMESTAMP | 创建时间 |

## 4. 数据库优化策略

### 4.1 索引优化

**主键索引：**
- 所有表都使用自增整型主键
- 确保主键的唯一性和非空性

**唯一索引：**
- 用户名、邮箱等唯一字段
- 设备序列号等业务唯一标识

**复合索引：**
```sql
-- 传感器数据查询优化
CREATE INDEX idx_sensor_data_query ON sensor_data (device_id, sensor_type, timestamp);

-- 动物信息查询优化
CREATE INDEX idx_animal_farm_status ON animals (farm_id, status, created_at);

-- 预警查询优化
CREATE INDEX idx_alert_farm_status ON alerts (farm_id, status, level, created_at);
```

### 4.2 分区策略

**时间分区：**
```sql
-- 传感器数据按月分区
CREATE TABLE sensor_data (
    -- 字段定义...
) PARTITION BY RANGE (YEAR(created_at) * 100 + MONTH(created_at)) (
    PARTITION p202501 VALUES LESS THAN (202502),
    PARTITION p202502 VALUES LESS THAN (202503),
    -- 更多分区...
);
```

**哈希分区：**
```sql
-- 操作日志按用户ID哈希分区
CREATE TABLE operation_logs (
    -- 字段定义...
) PARTITION BY HASH(user_id) PARTITIONS 8;
```

### 4.3 查询优化

**慢查询优化：**
- 启用慢查询日志
- 定期分析慢查询
- 优化查询语句和索引

**缓存策略：**
- Redis缓存热点数据
- 查询结果缓存
- 分布式缓存架构

## 5. 数据安全与备份

### 5.1 数据安全

**访问控制：**
- 数据库用户权限最小化
- 应用层数据访问控制
- 敏感数据加密存储

**数据加密：**
```sql
-- 密码字段加密
password VARCHAR(255) NOT NULL COMMENT '密码（bcrypt加密）'

-- 敏感信息加密存储
phone VARCHAR(255) COMMENT '手机号（AES加密）'
```

### 5.2 备份策略

**全量备份：**
- 每日凌晨全量备份
- 备份文件异地存储
- 备份文件加密压缩

**增量备份：**
- 每小时增量备份
- binlog备份和恢复
- 实时数据同步

**备份验证：**
- 定期备份恢复测试
- 备份文件完整性校验
- 灾难恢复演练

## 6. 监控与维护

### 6.1 性能监控

**关键指标：**
- QPS（每秒查询数）
- 连接数和活跃连接
- 慢查询统计
- 表空间使用率

**监控工具：**
- MySQL Performance Schema
- Prometheus + Grafana
- 自定义监控脚本

### 6.2 维护策略

**定期维护：**
- 表结构优化
- 索引重建和优化
- 数据清理和归档
- 统计信息更新

**容量规划：**
- 存储容量预测
- 性能瓶颈分析
- 扩容方案制定

## 7. 数据字典

### 7.1 枚举值定义

**用户状态 (user_status)：**
- active：激活
- inactive：未激活
- suspended：已暂停

**设备状态 (device_status)：**
- active：正常运行
- inactive：离线
- maintenance：维护中

**预警级别 (alert_level)：**
- low：低级
- medium：中级
- high：高级
- critical：严重

**动物类型 (animal_type)：**
- 1：牛
- 2：羊
- 3：猪
- 4：马

### 7.2 业务规则

**数据完整性规则：**
1. 动物必须关联到养殖场
2. 设备必须关联到养殖场
3. 传感器数据必须关联到设备
4. 预警可以关联到设备或养殖场

**业务逻辑规则：**
1. 圈舍当前数量不能超过容量
2. 动物转移需要记录转移记录
3. 批次完成后不能再添加动物
4. 电子围栏至少需要3个点

## 8. 版本升级与迁移

### 8.1 版本控制

**数据库版本管理：**
- 使用数据库迁移工具
- 版本号管理和追踪
- 回滚方案制定

**升级策略：**
- 灰度升级
- 数据迁移验证
- 业务连续性保障

### 8.2 数据迁移

**迁移工具：**
- 自定义迁移脚本
- 数据同步工具
- 数据验证工具

**迁移流程：**
1. 数据备份
2. 结构升级
3. 数据迁移
4. 数据验证
5. 业务切换

## 9. 附录

### 9.1 建表语句示例

```sql
-- 用户表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(255) NOT NULL,
    phone VARCHAR(20),
    avatar VARCHAR(255),
    roles INT DEFAULT 2,
    status ENUM('active', 'inactive', 'suspended') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_roles (roles),
    INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 养殖场表
CREATE TABLE farms (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    type VARCHAR(50) NOT NULL,
    location JSON NOT NULL DEFAULT (JSON_OBJECT()),
    address VARCHAR(255),
    contact VARCHAR(50),
    phone VARCHAR(20),
    status ENUM('active', 'inactive', 'maintenance') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_name (name),
    INDEX idx_type (type),
    INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

### 9.2 常用查询示例

```sql
-- 查询养殖场及其动物数量
SELECT f.id, f.name, COUNT(a.id) as animal_count
FROM farms f
LEFT JOIN animals a ON f.id = a.farm_id AND a.status = 1
WHERE f.status = 'active'
GROUP BY f.id, f.name;

-- 查询最近24小时的预警统计
SELECT alert_type, level, COUNT(*) as count
FROM alerts
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY alert_type, level
ORDER BY count DESC;

-- 查询设备在线状态
SELECT d.id, d.name, d.status,
       CASE 
           WHEN d.last_heartbeat >= DATE_SUB(NOW(), INTERVAL 5 MINUTE) THEN 'online'
           ELSE 'offline'
       END as online_status
FROM devices d
WHERE d.status = 'active';
```

---

**文档维护说明：**
本文档应随着系统功能的增加和数据库结构的变化及时更新。所有数据库结构变更都应该通过版本控制进行管理，确保开发、测试、生产环境的一致性。