多用户网络应用程序 - 数据库设计
Multi-user web app - Database design
我打算开发一个多用户网络应用程序,用户每天都会记录他们是否完成了各种任务。任务每天重复,例如:每天XYZ需要完成。
并非所有用户每天都要完成相同的任务。可能会有一个数据库 table 包含所有可能的任务。当新用户在网络上注册时,他们将通过为自己创建配置文件来 select 适用于他们的任务。
每天用户都会记录他们是否完成了各自的任务。之后,将有深入的报告和历史统计数据,不仅是关于用户自己的任务历史记录,...还有全球范围内的趋势。
我只是在寻找有关如何设计数据库的任何建议(一般而言)。有一个包含所有任务的任务 table 可以吗?然后,当新用户在线创建自己的个人资料时,会创建一个全新的 table,其中包含他们的个人资料信息和他们 select 编辑的任务。每个唯一的用户配置文件 table 将包含每天完成的任务的持续历史记录。
或者有更好的设计方法吗?
编辑:或者更好的想法是拥有如下内容:
任务历史记录table:
PersonID | Date | Task1 | Task2 | Task3 | Task 4
001 | 24Jan15 | Complete | Complete | |
002 | 24Jan15 | | Complete | Complete | Not Complete
003 | 24Jan15 | Not Complete | | |
所以会有一个 table 包含所有用户(以及他们选择的任务),另一个 table 包含所有可能的任务,最后是上面的 table 记录每天的任务历史。
这里唯一的问题是并非每个任务都适用于每个人。所以会有空格。不确定这是否重要。
正如您所知道的,我是初学者。因此,我们将不胜感激任何建议。
动态创建新的 table 来保存数据子集几乎不是一个好主意。不同用户的数据应该放在同一组 table 中,其中一些字段可以标识用户。没有充分的理由让数百个 table 完全相同,除了一个用于某个键值 A,下一个用于键值 B,等等。只需将键字段添加到 table.
正如 a_horse_with_no_name 所说,带编号的列是一个强烈的信号,表明您做错了。这是一个坏主意的原因有很多。其中:如果每个任务都有一个列,那么添加新任务时会发生什么情况?现在您不仅要添加新记录,还必须向 table 添加新列,并更新所有现有记录。此外,它使查询变得非常复杂。像 "what tasks were done today" 这样的查询需要对每一列进行单独的测试,而不是对单个 "task" 列进行一次测试。
根据你所说的,这是我对它应该是什么样子的第一个想法:
Task table
(task_id, task_name)
这列出了所有感兴趣的任务。
User table
(user_id, user_name)
这会列出所有用户。
Assigned_Task table
(user_id, task_id)
这将用户与任务相关联。每个用户的每个任务都会在这个 table 中有一条记录。也就是说,如果 Alice 是用户 1,她应该执行任务 1、2 和 3; Bob 是用户 2,他应该做 2 和 4,那么会有记录 (1,1)、(1,2)、(1,3)、(2, 2) 和 (2,4) .
(注意:你可能有一个 assigned_task_id 字段让这个 table 成为主键,或者 PK 可以是 user_id + task_id,因为必须是唯一的。)
Task_Status table
(user_id, task_id, task_date, completed)
每天每个 user/task 组合都有一个记录。所以 30 天后,如果爱丽丝有 3 个任务,她将有 3 x 30 = 90 条记录,每天 3 条乘以 30 天。
(您可能有一个 task_status_id 作为 PK,或者您可能使用 user_id + task_id + task_date。具有超过 2 个字段的键往往是很痛苦,所以我可能会创建一个 task_status_id。随便吧。)
如果您需要其他信息,这些 table 中的任何一个都可能有其他字段。就像用户 table 可能有员工编号、phone 编号、部门等
然后像 "What tasks were not completed yesterday?" 这样的问题很容易用这个查询来回答:
select user.name, task.name
from task_status
join user on user.user_id=task_status.user_id
join task on task.task_id=task_status.task_id
where task_date=@date
and completed=0
今天完成了多少任务?
select count(*)
from task_status
where date=@date and completed=1
等等
我打算开发一个多用户网络应用程序,用户每天都会记录他们是否完成了各种任务。任务每天重复,例如:每天XYZ需要完成。
并非所有用户每天都要完成相同的任务。可能会有一个数据库 table 包含所有可能的任务。当新用户在网络上注册时,他们将通过为自己创建配置文件来 select 适用于他们的任务。
每天用户都会记录他们是否完成了各自的任务。之后,将有深入的报告和历史统计数据,不仅是关于用户自己的任务历史记录,...还有全球范围内的趋势。
我只是在寻找有关如何设计数据库的任何建议(一般而言)。有一个包含所有任务的任务 table 可以吗?然后,当新用户在线创建自己的个人资料时,会创建一个全新的 table,其中包含他们的个人资料信息和他们 select 编辑的任务。每个唯一的用户配置文件 table 将包含每天完成的任务的持续历史记录。
或者有更好的设计方法吗?
编辑:或者更好的想法是拥有如下内容:
任务历史记录table:
PersonID | Date | Task1 | Task2 | Task3 | Task 4
001 | 24Jan15 | Complete | Complete | |
002 | 24Jan15 | | Complete | Complete | Not Complete
003 | 24Jan15 | Not Complete | | |
所以会有一个 table 包含所有用户(以及他们选择的任务),另一个 table 包含所有可能的任务,最后是上面的 table 记录每天的任务历史。
这里唯一的问题是并非每个任务都适用于每个人。所以会有空格。不确定这是否重要。
正如您所知道的,我是初学者。因此,我们将不胜感激任何建议。
动态创建新的 table 来保存数据子集几乎不是一个好主意。不同用户的数据应该放在同一组 table 中,其中一些字段可以标识用户。没有充分的理由让数百个 table 完全相同,除了一个用于某个键值 A,下一个用于键值 B,等等。只需将键字段添加到 table.
正如 a_horse_with_no_name 所说,带编号的列是一个强烈的信号,表明您做错了。这是一个坏主意的原因有很多。其中:如果每个任务都有一个列,那么添加新任务时会发生什么情况?现在您不仅要添加新记录,还必须向 table 添加新列,并更新所有现有记录。此外,它使查询变得非常复杂。像 "what tasks were done today" 这样的查询需要对每一列进行单独的测试,而不是对单个 "task" 列进行一次测试。
根据你所说的,这是我对它应该是什么样子的第一个想法:
Task table
(task_id, task_name)
这列出了所有感兴趣的任务。
User table
(user_id, user_name)
这会列出所有用户。
Assigned_Task table
(user_id, task_id)
这将用户与任务相关联。每个用户的每个任务都会在这个 table 中有一条记录。也就是说,如果 Alice 是用户 1,她应该执行任务 1、2 和 3; Bob 是用户 2,他应该做 2 和 4,那么会有记录 (1,1)、(1,2)、(1,3)、(2, 2) 和 (2,4) .
(注意:你可能有一个 assigned_task_id 字段让这个 table 成为主键,或者 PK 可以是 user_id + task_id,因为必须是唯一的。)
Task_Status table
(user_id, task_id, task_date, completed)
每天每个 user/task 组合都有一个记录。所以 30 天后,如果爱丽丝有 3 个任务,她将有 3 x 30 = 90 条记录,每天 3 条乘以 30 天。
(您可能有一个 task_status_id 作为 PK,或者您可能使用 user_id + task_id + task_date。具有超过 2 个字段的键往往是很痛苦,所以我可能会创建一个 task_status_id。随便吧。)
如果您需要其他信息,这些 table 中的任何一个都可能有其他字段。就像用户 table 可能有员工编号、phone 编号、部门等
然后像 "What tasks were not completed yesterday?" 这样的问题很容易用这个查询来回答:
select user.name, task.name
from task_status
join user on user.user_id=task_status.user_id
join task on task.task_id=task_status.task_id
where task_date=@date
and completed=0
今天完成了多少任务?
select count(*)
from task_status
where date=@date and completed=1
等等