【Java项目-企悦抽】03-数据库的设计与建立
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🎯 你正在阅读「Java项目-企悦抽」系列文章 🎯
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🔥 弹简特 个人主页
❄️ 个人专栏直通车:
✨ 靠热爱去书写自己,靠勇敢去书写生活!
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌟 博主简介:

一、前言
我们前面借助AI完成的需求的梳理之后,根据需求,本期我们就可以设计出来我们本项目的数据库了
二、数据库表结构总览
1.1 核心表字段说明
1.1.1 user(用户表)
| 字段名 | 数据类型 | 中文释义 | 约束/说明 |
|---|---|---|---|
| id | bigint UNSIGNED | 主键ID | 自增主键,唯一标识用户 |
| gmt_create | datetime | 创建时间 | 记录创建时间,默认当前时间 |
| gmt_modified | datetime | 更新时间 | 记录更新时间,默认当前时间且自动更新 |
| user_name | varchar(255) | 用户姓名 | 非空,存储用户真实姓名 |
| varchar(255) | 邮箱 | 非空,用户登录/联系邮箱,建立唯一索引 | |
| phone_number | varchar(255) | 手机号 | 非空,用户联系方式,建立唯一索引 |
| password | varchar(255) | 登录密码 | 存储加密后的用户密码,允许为空(特殊场景) |
| identity | varchar(255) | 用户身份 | 非空,标识用户角色(如普通用户、管理员) |

1.1.2 activity(活动表)
| 字段名 | 数据类型 | 中文释义 | 约束/说明 |
|---|---|---|---|
| id | bigint UNSIGNED | 主键ID | 自增主键,唯一标识活动 |
| gmt_create | datetime | 创建时间 | 记录创建时间,默认当前时间 |
| gmt_modified | datetime | 更新时间 | 记录更新时间,默认当前时间且自动更新 |
| activity_name | varchar(255) | 活动名称 | 非空,抽奖活动的名称 |
| description | varchar(255) | 活动描述 | 非空,活动规则、详情等说明 |
| status | varchar(255) | 活动状态 | 非空,标识活动状态(如未开始、进行中、已结束) |

1.1.3 prize(奖品表)
| 字段名 | 数据类型 | 中文释义 | 约束/说明 |
|---|---|---|---|
| id | bigint UNSIGNED | 主键ID | 自增主键,唯一标识奖品 |
| gmt_create | datetime | 创建时间 | 记录创建时间,默认当前时间 |
| gmt_modified | datetime | 更新时间 | 记录更新时间,默认当前时间且自动更新 |
| name | varchar(255) | 奖品名称 | 非空,奖品的具体名称 |
| description | varchar(255) | 奖品描述 | 允许为空,奖品详情、规格等说明 |
| price | decimal(10,2) | 奖品价值 | 非空,奖品的市场价值,保留两位小数 |
| image_url | varchar(2048) | 奖品展示图 | 允许为空,奖品图片的存储地址 |

1.1.4 activity_user(活动用户关联表)
| 字段名 | 数据类型 | 中文释义 | 约束/说明 |
|---|---|---|---|
| id | bigint UNSIGNED | 主键ID | 自增主键,唯一标识关联记录 |
| gmt_create | datetime | 创建时间 | 记录创建时间,默认当前时间 |
| gmt_modified | datetime | 更新时间 | 记录更新时间,默认当前时间且自动更新 |
| activity_id | bigint | 活动ID | 非空,关联activity表的活动主键 |
| user_id | bigint | 用户ID | 非空,关联user表的用户主键 |
| user_name | varchar(255) | 用户名 | 非空,参与活动的用户名称(冗余字段,方便查询) |
| status | varchar(255) | 用户状态 | 非空,用户在活动中的状态(如已参与、已中奖) |

1.1.5 activity_prize(活动奖品关联表)
| 字段名 | 数据类型 | 中文释义 | 约束/说明 |
|---|---|---|---|
| id | bigint UNSIGNED | 主键ID | 自增主键,唯一标识关联记录 |
| gmt_create | datetime | 创建时间 | 记录创建时间,默认当前时间 |
| gmt_modified | datetime | 更新时间 | 记录更新时间,默认当前时间且自动更新 |
| activity_id | bigint | 活动ID | 非空,关联activity表的活动主键 |
| prize_id | bigint | 奖品ID | 非空,关联prize表的奖品主键 |
| prize_amount | bigint | 关联奖品数量 | 非空,默认1,活动中该奖品的总发放数量 |
| prize_tiers | varchar(255) | 奖品等级 | 非空,奖品的等级(如一等奖、二等奖、参与奖) |
| status | varchar(255) | 活动奖品状态 | 非空,标识该奖品在活动中的状态(如可用、已兑完) |


1.1.6 winning_record(中奖记录表)
| 字段名 | 数据类型 | 中文释义 | 约束/说明 |
|---|---|---|---|
| id | bigint UNSIGNED | 主键ID | 自增主键,唯一标识中奖记录 |
| gmt_create | datetime | 创建时间 | 记录创建时间,默认当前时间 |
| gmt_modified | datetime | 更新时间 | 记录更新时间,默认当前时间且自动更新 |
| activity_id | bigint | 活动ID | 非空,关联activity表的活动主键 |
| activity_name | varchar(255) | 活动名称 | 非空,中奖所属活动名称(冗余字段) |
| prize_id | bigint | 奖品ID | 非空,关联prize表的奖品主键 |
| prize_name | varchar(255) | 奖品名称 | 非空,中奖奖品名称(冗余字段) |
| prize_tier | varchar(255) | 奖品等级 | 非空,中奖奖品的等级 |
| winner_id | bigint | 中奖人ID | 非空,关联user表的中奖用户主键 |
| winner_name | varchar(255) | 中奖人姓名 | 非空,中奖用户姓名(冗余字段) |
| winner_email | varchar(255) | 中奖人邮箱 | 非空,中奖用户邮箱(冗余字段) |
| winner_phone_number | varchar(255) | 中奖人电话 | 非空,中奖用户电话(冗余字段) |
| winning_time | datetime | 中奖时间 | 非空,用户中奖的具体时间 |

1.2 表依赖关系说明
1.2.1 表关联关系
1). 多对多关联(通过中间表实现)
-
user ↔ activity:多对多关联
一个用户可参与多个活动,一个活动可包含多个用户;
通过中间表 activity_user 实现关联,关联字段:user_id、activity_id。 -
activity ↔ prize:多对多关联
一个活动可配置多个奖品,一个奖品可用于多个活动;
通过中间表 activity_prize 实现关联,关联字段:activity_id、prize_id。
2). 一对多关联(主表 ↔ 子表/记录表)
-
user → winning_record:一对多
一个用户可产生多条中奖记录,通过winner_id关联。 -
activity → winning_record:一对多
一个活动可产生多条中奖记录,通过activity_id关联。 -
prize → winning_record:一对多
一个奖品可被多人中奖,产生多条记录,通过prize_id关联。 -
activity → activity_user:一对多
一个活动对应多条活动用户关联记录,通过activity_id关联。 -
user → activity_user:一对多
一个用户对应多条活动用户关联记录,通过user_id关联。 -
activity → activity_prize:一对多
一个活动对应多条活动奖品关联记录,通过activity_id关联。 -
prize → activity_prize:一对多
一个奖品对应多条活动奖品关联记录,通过prize_id关联。
1.2.2 中间表作用
- activity_user:作为
user和activity的中间关联表,记录用户与活动的参与关系,同时存储用户在活动中的状态,避免直接在主表中频繁修改关联关系。 - activity_prize:作为
activity和prize的中间关联表,记录活动与奖品的绑定关系,同时存储奖品数量、等级等活动专属属性,区分同一奖品在不同活动中的配置。
1.2.3 冗余字段设计
中奖记录表(winning_record)中大量冗余activity_name、prize_name等字段,目的是减少多表联查次数,提升查询效率。例如查询中奖记录时,无需关联activity和prize表即可获取活动/奖品名称,适用于高频查询场景。
三、数据库SQL执行说明
2.1 字符集与外键配置
- 脚本开头通过
SET NAMES utf8mb4;设置客户端与服务器字符集为utf8mb4,支持存储所有Unicode字符(含emoji)。 - 执行
SET FOREIGN_KEY_CHECKS = 0;关闭外键约束,避免创建表时因外键依赖顺序问题导致执行失败;脚本末尾通过SET FOREIGN_KEY_CHECKS = 1;重新开启外键约束校验。
2.2 数据库与表创建
- 脚本先删除名为
lottery_system的数据库(若存在),再创建该数据库并指定字符集为utf8mb4、排序规则为utf8mb4_general_ci。 - 按依赖顺序创建表(先创主表
user/activity/prize,再创中间表activity_user/activity_prize,最后创winning_record),避免外键约束报错。 - 所有表均使用
InnoDB存储引擎,支持事务、行级锁和外键;AUTO_INCREMENT指定主键自增起始值,ROW_FORMAT = DYNAMIC设置动态行格式,适配数据动态增长。
2.3 索引设计
- 主键索引:所有表均通过
PRIMARY KEY (id)创建主键索引,保证数据唯一性。 - 唯一索引:
- 单字段:
user表的email/phone_number、prize表的id等,避免重复数据。 - 联合索引:
activity_user表的uk_a_u_id(activity_id+user_id)、activity_prize表的uk_a_p_id(activity_id+prize_id)、winning_record表的uk_w_a_p_id(winner_id+activity_id+prize_id),保证关联维度的唯一性。
- 单字段:
- 普通索引:
activity_user/activity_prize/winning_record表的idx_activity_id,加速按活动ID的查询操作。
四、业务场景适配说明
- 活动管理:通过
activity表配置活动基础信息,activity_prize表绑定活动奖品及数量/等级,activity_user表圈选参与活动的用户,实现活动全生命周期管理。 - 抽奖流程:用户参与活动时,在
activity_user中生成记录;中奖时,在winning_record中新增记录,同时更新activity_prize中对应奖品的剩余数量,保证数据一致性。 - 数据查询:通过
winning_record表可快速查询用户中奖信息,结合activity/prize/user表可实现多维度统计(如各活动中奖率、各奖品中奖人数等)。
五、sql代码
-- 设置客户端与服务器之间的字符集为utf8mb4,这个字符集可以存储任何Unicode字符。
SET NAMES utf8mb4;
-- 关闭外键约束检查,这通常在创建或修改表结构时使用,以避免由于外键约束而导致的创建失败。
SET FOREIGN_KEY_CHECKS = 0;
drop database IF EXISTS `lottery_system`;
create DATABASE `lottery_system` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `lottery_system`;
-- ----------------------------
-- Table structure for activity
-- 表作用:存储抽奖活动的基础信息,包括活动名称、描述、状态等核心数据
-- ----------------------------
drop table IF EXISTS `activity`;
create TABLE `activity` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT comment '主键',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP comment '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP comment '更新时间',
`activity_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '活动名称',
`description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '活动描述',
`status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '活动状态',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_id`(`id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
-- ENGINE = InnoDB:指定表的存储引擎为InnoDB,这是MySQL的默认存储引擎,支持事务、外键等特性。
-- AUTO_INCREMENT = 24:为自动增长的ID字段设置起始值。
-- ROW_FORMAT = DYNAMIC:设置行的存储格式为动态,允许行随着数据的变化而变化。
-- ----------------------------
-- Table structure for activity_prize
-- 表作用:活动与奖品的关联中间表,记录每个活动绑定的奖品、奖品数量、等级及状态
-- ----------------------------
drop table IF EXISTS `activity_prize`;
create TABLE `activity_prize` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT comment '主键',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP comment '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP comment '更新时间',
`activity_id` bigint NOT NULL comment '活动id',
`prize_id` bigint NOT NULL comment '活动关联的奖品id',
`prize_amount` bigint NOT NULL DEFAULT 1 comment '关联奖品的数量',
`prize_tiers` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '奖品等级',
`status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '活动奖品状态',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_id`(`id` ASC) USING BTREE,
UNIQUE INDEX `uk_a_p_id`(`activity_id` ASC, `prize_id` ASC) USING BTREE,
INDEX `idx_activity_id`(`activity_id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Table structure for activity_user
-- 表作用:活动与用户的关联中间表,记录参与指定活动的用户信息及用户在活动中的状态
-- ----------------------------
drop table IF EXISTS `activity_user`;
create TABLE `activity_user` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT comment '主键',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP comment '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP comment '更新时间',
`activity_id` bigint NOT NULL comment '活动id',
`user_id` bigint NOT NULL comment '圈选的用户id',
`user_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '用户名',
`status` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '用户状态',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_id`(`id` ASC) USING BTREE,
UNIQUE INDEX `uk_a_u_id`(`activity_id` ASC, `user_id` ASC) USING BTREE,
INDEX `idx_activity_id`(`activity_id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Table structure for prize
-- 表作用:奖品基础信息表,存储所有奖品的名称、描述、价值、图片等公共数据
-- ----------------------------
drop table IF EXISTS `prize`;
create TABLE `prize` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT comment '主键',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP comment '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP comment '更新时间',
`name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '奖品名称',
`description` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL comment '奖品描述',
`price` decimal(10, 2) NOT NULL comment '奖品价值',
`image_url` varchar(2048) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL comment '奖品展示图',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_id`(`id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Table structure for user
-- 表作用:系统用户表,存储所有用户的账号、联系方式、身份、密码等信息
-- ----------------------------
drop table IF EXISTS `user`;
create TABLE `user` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT comment '主键',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP comment '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP comment '更新时间',
`user_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '用户姓名',
`email` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '邮箱',
`phone_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '手机号',
`password` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL comment '登录密码',
`identity` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '用户身份',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_id`(`id` ASC) USING BTREE,
UNIQUE INDEX `uk_email`(`email`(30) ASC) USING BTREE,
UNIQUE INDEX `uk_phone_number`(`phone_number`(11) ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 39 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Table structure for winning_record
-- 表作用:中奖记录表,记录用户中奖的所有明细数据,包含活动、奖品、中奖人、中奖时间等信息
-- ----------------------------
drop table IF EXISTS `winning_record`;
create TABLE `winning_record` (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT comment '主键',
`gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP comment '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP comment '更新时间',
`activity_id` bigint NOT NULL comment '活动id',
`activity_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '活动名称',
`prize_id` bigint NOT NULL comment '奖品id',
`prize_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '奖品名称',
`prize_tier` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '奖品等级',
`winner_id` bigint NOT NULL comment '中奖人id',
`winner_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '中奖人姓名',
`winner_email` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '中奖人邮箱',
`winner_phone_number` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL comment '中奖人电话',
`winning_time` datetime NOT NULL comment '中奖时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uk_id`(`id` ASC) USING BTREE,
UNIQUE INDEX `uk_w_a_p_id`(`winner_id` ASC, `activity_id` ASC, `prize_id` ASC) USING BTREE,
INDEX `idx_activity_id`(`activity_id` ASC) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 69 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = DYNAMIC;
-- SET FOREIGN_KEY_CHECKS = 1;:在脚本的最后,重新开启外键约束检查。
SET FOREIGN_KEY_CHECKS = 1;
那么本期的数据库设计完毕了,下一期我们借助AI整理出我们的项目开发接口文档,以及对项目进行演示和项目源码的分享。老铁们,持续关注,后面分享更多的干货(皆手动实现)
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)