MySQL数据库基础练习系列目标
很多学生或者说是初学者在学习完成数据库的基础增删改查后就自认为在数据库这里就很熟悉了,但是不接触项目根本部知道需求,我这里准备了50个项目的基本需求来让大家来熟练各类项目的列信息,让大家更好的深入项目进行实战式的练习,可以让大家在后面面试的时候有更多更丰富的资历让大家可以与面试官侃侃而谈。
数据库环境
MySQL版本:5.7.31-log
数据库字符集,所有数据库通用字符集与排序规则,支持中文数据。
字符集:utf8 排序规则:utf8_general_ci
使用工具:Navicat Premium 15,可以在下面的连接中下载
https://download.csdn.net/download/feng8403000/89403778
项目名称与项目简介
积分管理系统是一个旨在管理和跟踪用户积分活动的系统。它允许用户通过完成各种任务或活动来赚取积分,并可以在未来的某些场景中使用这些积分。主要功能包括用户管理、积分赚取规则定义、积分交易记录以及积分使用记录等。
数据库DDL(注意创建顺序)
为了直接运行DDL语句并创建表,我们需要确保在创建含有外键约束的表之前,相关的被引用表(即外键指向的表)已经存在。所以我们在创建表的时候一定要按照一定的顺序来创建,否则就会出现没有外键关系导致的创建异常。
代码语言:javascript复制-- 用户表
CREATE TABLE Users (
user_id INT AUTO_INCREMENT PRIMARY KEY, -- 用户ID
username VARCHAR(50) NOT NULL, -- 用户名
password VARCHAR(255) NOT NULL, -- 密码
name VARCHAR(100) NOT NULL, -- 姓名
email VARCHAR(100), -- 邮箱
gender ENUM('男', '女') NOT NULL, -- 性别
phone VARCHAR(20), -- 电话号码
integral INT DEFAULT 0 NOT NULL COMMENT '用户当前积分' -- 用户当前积分
);
-- 积分类型表
CREATE TABLE IntegralTypes (
type_id INT AUTO_INCREMENT PRIMARY KEY, -- 积分类型ID
type_name VARCHAR(50) NOT NULL, -- 积分类型名称
description VARCHAR(255) COMMENT '积分类型描述' -- 积分类型描述
);
-- 积分赚取规则表
CREATE TABLE EarningRules (
rule_id INT AUTO_INCREMENT PRIMARY KEY, -- 赚取规则ID
type_id INT NOT NULL, -- 积分类型ID
action_name VARCHAR(100) NOT NULL, -- 赚取行为名称
integral_amount INT NOT NULL, -- 赚取积分数量
FOREIGN KEY (type_id) REFERENCES IntegralTypes(type_id)
);
-- 积分交易记录表
CREATE TABLE Transactions (
transaction_id INT AUTO_INCREMENT PRIMARY KEY, -- 交易记录ID
user_id INT NOT NULL, -- 用户ID
type_id INT NOT NULL, -- 积分类型ID
transaction_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 交易日期
integral_change INT NOT NULL COMMENT '积分变化量', -- 积分变化量,可以为正数(增加)或负数(减少)
description VARCHAR(255) COMMENT '交易描述', -- 交易描述
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (type_id) REFERENCES IntegralTypes(type_id)
);
-- 积分使用记录表(可选,记录用户具体如何使用积分)
CREATE TABLE UsageRecords (
record_id INT AUTO_INCREMENT PRIMARY KEY, -- 使用记录ID
transaction_id INT NOT NULL, -- 交易记录ID
usage_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 使用日期
usage_details VARCHAR(255) COMMENT '使用详情', -- 使用详情
FOREIGN KEY (transaction_id) REFERENCES Transactions(transaction_id)
);
-- 积分兑换商品表(可选,如果有商品兑换功能)
CREATE TABLE ExchangeItems (
item_id INT AUTO_INCREMENT PRIMARY KEY, -- 商品ID
item_name VARCHAR(100) NOT NULL, -- 商品名称
description VARCHAR(255) COMMENT '商品描述', -- 商品描述
price_in_integral INT NOT NULL COMMENT '兑换所需积分' -- 兑换所需积分
);
-- 积分兑换记录表(可选,记录用户兑换商品的记录)
CREATE TABLE ExchangeRecords (
record_id INT AUTO_INCREMENT PRIMARY KEY, -- 兑换记录ID
user_id INT NOT NULL, -- 用户ID
item_id INT NOT NULL, -- 商品ID
exchange_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 兑换日期
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (item_id) REFERENCES ExchangeItems(item_id)
);
插入数据DML(注意插入数据顺序)
插入数据的时候也要注意主外键关系,如果没有外检的情况下是没有办法插入从表数据的。
代码语言:javascript复制-- 用户表
INSERT INTO Users (username, password, name, email, gender, phone, integral) VALUES
('孙悟空', '123', '孙悟空', 'sunwukong@example.com', '男', '13800138001', 1000),
('诸葛亮', '123', '诸葛亮', 'zhugeliang@example.com', '男', '13900139002', 1500),
('林黛玉', '123', '林黛玉', 'lindaiyu@example.com', '女', '13700137003', 800);
-- 积分类型表
INSERT INTO IntegralTypes (type_name, description) VALUES
('日常签到', '每天签到获得的积分'),
('任务完成', '完成指定任务获得的积分'),
('活动奖励', '参与活动获得的额外积分');
-- 积分赚取规则表
INSERT INTO EarningRules (type_id, action_name, integral_amount) VALUES
(1, '每日签到', 10), -- 假设日常签到每天赚取10积分
(2, '完成新手任务', 50), -- 假设完成新手任务赚取50积分
(2, '完成日常任务', 20), -- 假设完成日常任务赚取20积分
(3, '参与春节活动', 100); -- 假设参与春节活动赚取100积分
-- 积分交易记录表
INSERT INTO Transactions (user_id, type_id, transaction_date, integral_change, description) VALUES
(1, 1, NOW(), 10, '日常签到积分'), -- 孙悟空日常签到获得10积分
(2, 2, NOW(), 20, '完成日常任务积分'), -- 诸葛亮完成日常任务获得20积分
(3, 3, NOW(), 100, '春节活动奖励积分'); -- 林黛玉参与春节活动获得100积分
-- 积分使用记录表(可选)
-- 假设第一条交易记录是孙悟空使用积分购买虚拟商品
INSERT INTO UsageRecords (transaction_id, usage_date, usage_details) VALUES
(1, NOW(), '购买虚拟商品');
-- 积分兑换商品表(可选)
INSERT INTO ExchangeItems (item_name, description, price_in_integral) VALUES
('虚拟道具A', '游戏中的道具', 50),
('会员月卡', '网站会员权益', 200);
-- 积分兑换记录表(可选)
-- 假设诸葛亮使用积分兑换了虚拟道具A
INSERT INTO ExchangeRecords (user_id, item_id, exchange_date) VALUES
(2, 1, NOW());
遵循的数据库三范式
数据库建表的三范式(3NF,Third Normal Form)是关系型数据库设计的基本原则,用于确保数据库结构的逻辑性和减少数据冗余。这三个范式是逐步细化的,每一个范式都是在前一个范式的基础上建立的。下面我将详细解释这三个范式:
第一范式(1NF, First Normal Form)
定义:
- 列不可分割,即数据库表的每一列都是不可分割的原子数据项。
- 每一列都是不可再分的最小数据单元(也称为最小的原子单元)。
解释:
- 在第一范式中,主要关注的是列的原子性。也就是说,表中的每一列都应该只包含一个值,而不能包含集合、数组或其他复合数据类型。
- 例如,如果有一个“地址”列,它包含了街道、城市、省份和国家等信息,那么这就违反了第一范式。应该将这个“地址”列拆分成多个独立的列,如“街道”、“城市”、“省份”和“国家”。
第二范式(2NF, Second Normal Form)
定义:
- 满足1NF。
- 非主键列必须完全依赖于主键,而不能只依赖于主键的一部分(针对复合主键而言)。
解释:
- 第二范式建立在第一范式的基础上,主要关注于主键与非主键列之间的依赖关系。
- 在第二范式中,一个表只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
- 如果表中的某一列只与复合主键的一部分有关,那么它就不应该存在于这个表中,而应该被分离出去形成另外一张新表。
第三范式(3NF, Third Normal Form)
定义:
- 满足2NF。
- 非主键列必须直接依赖于主键,不能存在传递依赖。即非主键列必须直接依赖于整个主键,而不能依赖于主键的一部分。
解释:
- 第三范式是在第二范式的基础上进一步细化的。它主要关注于消除传递依赖,即非主键列不应该依赖于主键的某一部分,而应该直接依赖于整个主键。
- 如果存在传递依赖,那么应该考虑将这个非主键列分离出去,形成新的表,并通过主键或外键与原表进行关联。