gpt4 book ai didi

MySQL 模式设计问题 - 规范化

转载 作者:行者123 更新时间:2023-11-29 08:19:43 28 4
gpt4 key购买 nike

我正在使用以下设计为我的网站创建表格

设计1

enter image description here

设计2

enter image description here

由于并非所有注册用户都会尝试挑战,因此设计 1 适合。插入第三个表时,表 2 分数会相应更新。但是 user_id 字段变得多余。

设计 2 中为每个用户设置 0 或 NULL 值,但仍未标准化。最佳设计是什么?标准化或关键在组织中有多重要?

最佳答案

编辑:

对于 future 的人 - 我在理解 OP 的要求时遇到了一些问题,所以如果你有点迷失,请阅读评论。最终,他们希望存储聚合数据,但不知道将其放在哪里或如何实现。解决方案基本上是使用插入触发器,这将在本文末尾处进行解释。

我选择在 user 表中添加另一列来存储 user_problem.score 的累计总和。然而,创建一个新表(包含user_idtotal_sum列)根本不是一个坏选择,尽管它似乎过度使用了标准化。有时,将不断更新的数据与很少更改的数据分开是很好的做法。这样,如果出现问题,您知道您的静态数据将是安全的。

我从未触及的其他问题是与一般存储聚合数据相关的数据并发性完整性问题......所以请注意这一点。

<小时/>

我建议这样:

User Table
User_ID - Email - Name - Password - FB_ID
-- holds all the user information


Problem Table
Problem_ID - Problem_Title - Problem_Descr
-- holds all the info on the individual challenges/problems/whatever


User_Problem Table
User_Problem_ID - User_ID - Problem_ID - Score - Completion_Date
-- Joins the User and Problem tables and has information specific
-- to a user+challenge pair

这假设用户可以接受许多挑战/问题。并且一个问题/挑战可以由多个用户解决。

要查看某个用户的所有问题,您可以执行以下操作:

select  user.user_id, 
user.name,
problem_title,
problem_descr,
user_problem.score,
user_problem.completed_date

from user

join user_problem on user.user_id = user_problem.user_id

join problem on user_problem.problem_id = problem.problem_id

where user.user_id = 123 or user.email = 'stuff@gmail.com'

varchar 字段的长度相当通用......

create table User(
User_ID int unsigned auto_increment primary key,
Email varchar(100),
Name varchar(100),
Password varchar(100),
FB_ID int
);

create table Problem (
Problem_ID int unsigned auto_increment primary key,
Problem_Title varchar(100),
Problem_Descr varchar(500)
);

create table User_Problem (
User_Problem_ID int unsigned auto_increment primary key,
User_ID int unsigned,
Problem_ID int unsigned,
Score int,
Completion_Date datetime,

foreign key (User_ID) references User (User_ID),
foreign key (Problem_ID) references Problem (Problem_ID)
);
<小时/>

在我们在下面的评论中进行对话之后...您将向用户添加一列:

User Table
User_ID - Email - Name - Password - FB_ID - Total_Score

我为该列指定了默认值 0,因为如果此人没有任何相关的问题/挑战,您似乎希望/需要该值。根据其他情况,如果您有一条规则规定永远不会出现负分数,那么将其设置为无符号整数可能会对您有利。

alter table user add column Total_Score int default 0;

然后...您将在 user_problem 表上使用影响 user 表的插入触发器。

CREATE TRIGGER tgr_update_total_score 

AFTER INSERT ON User_Problem
FOR EACH ROW

UPDATE User
SET Total_score = Total_score + New.Score
WHERE User_ID = NEW.User_ID;

所以...将一行添加到 User_Problem 后,您可以将新分数添加到 user.total_score...

mysql> select * from user;
+---------+-------+------+----------+-------+-------------+
| User_ID | Email | Name | Password | FB_ID | Total_Score |
+---------+-------+------+----------+-------+-------------+
| 1 | NULL | kim | NULL | NULL | 0 |
| 2 | NULL | kyle | NULL | NULL | 0 |
+---------+-------+------+----------+-------+-------------+
2 rows in set (0.00 sec)

mysql> insert into user_problem values (null,1,1,10,now());
Query OK, 1 row affected (0.16 sec)

mysql> select * from user;
+---------+-------+------+----------+-------+-------------+
| User_ID | Email | Name | Password | FB_ID | Total_Score |
+---------+-------+------+----------+-------+-------------+
| 1 | NULL | kim | NULL | NULL | 10 |
| 2 | NULL | kyle | NULL | NULL | 0 |
+---------+-------+------+----------+-------+-------------+
2 rows in set (0.00 sec)

mysql> select * from user_problem;
+-----------------+---------+------------+-------+---------------------+
| User_Problem_ID | User_ID | Problem_ID | Score | Completion_Date |
+-----------------+---------+------------+-------+---------------------+
| 1 | 1 | 1 | 10 | 2013-11-03 11:31:53 |
+-----------------+---------+------------+-------+---------------------+
1 row in set (0.00 sec)

关于MySQL 模式设计问题 - 规范化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19755115/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com