首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化用于捕获出勤数据的模式的最佳方法是什么

优化用于捕获出勤数据的模式的最佳方法是什么
EN

Stack Overflow用户
提问于 2010-07-07 16:47:18
回答 4查看 1.4K关注 0票数 3

我们有一个运动训练营,城市中的不同球队定期参加。我们每天的训练时间为2小时(上午9点到11点),不同球队的时间段可能会有所不同。我们想要记录每天参加训练营的人。

我们得出了以下模型来捕获出席率。(id,user_id,date,present)。假设用户每天参加夏令营(比如一个月30天),您将在数据库中看到许多记录。

假设我们只对用户参加夏令营的天数感兴趣,是否有更好的方法来标记特定用户的存在或不存在(可能只有一个月的单行,并将所有单独的日期标记为(P,A,...,A,P)。P=出席,A=缺席

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-07-07 17:18:32

代码语言:javascript
复制
AttMst
  id | date

AttDet
  attdetid | id | userid

这样,您需要将日期存储在AttMst中,而当天的当前用户将存储在AttDet中。

票数 1
EN

Stack Overflow用户

发布于 2010-07-07 20:39:38

你在问题标题中使用了“优化”一词,而没有解释你想要优化的是什么。

如果您谈论的是查询性能,那么您就没有问题。您可以拥有的记录数量取决于您每天拥有的会话数量(因为任何给定的会话只能有一个团队参加)。如果你一天运行10个会话,那么每个月就有300条记录。如果你每天运行100个会话,那么一个月就有3000条记录。这些都不是大数据量。因此,您通过歪曲数据库设计来避免不存在的性能问题,这是一个错误的决定。

您在一条评论中提到了电子表格。这是一个不错的设计。沿着顶行是会话,在边上是团队,单元格显示团队是否出现在会话中。这些映射到三个数据库表:会话、团队和交叉表TEAM_SESSIONS。您只需要在TEAM_SESSIONS中记录团队参加会话时的记录。

作为概念证明,我在Oracle中创建了三个表。

代码语言:javascript
复制
SQL> desc teams
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 NAME                                               VARCHAR2(20 CHAR)

SQL> desc sessions
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 SSN_DAY                                            DATE
 SSN_START                                          NUMBER(4,2)
 SSN_END                                            NUMBER(4,2)

SQL> desc team_sessions
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 TEAM_ID                                   NOT NULL NUMBER
 SESSION_ID                                NOT NULL NUMBER

SQL>

Oracle11g中引入的PIVOT函数使得构建矩阵变得轻而易举(不同风格的DBMS将有不同的方法来实现这一点)。正如你所看到的,今天有三支球队已经预定了训练时间,没有人想在午餐时间训练,贝克联队非常热衷于(或者需要训练)!

代码语言:javascript
复制
SQL> select * from (
  2      select t.name as team_name
  3             , trim(to_char(s.ssn_start))||'-'||trim(to_char(s.ssn_end)) as ssn
  4             , case when ts.team_id is not null then 1 else 0 end as present
  5      from   sessions s
  6             cross join teams t
  7             left outer join team_sessions ts
  8                  on (ts.team_id = t.id
  9                      and ts.session_id = s.id )
 10      where s.ssn_day = trunc(sysdate)
 11      )
 12  pivot
 13      ( sum (present)
 14        for ssn in ( '9-11', '11-13', '13-15', '15-17', '17-19')
 15      )
 16  order by team_name
 17  /

TEAM_NAME                '9-11'    '11-13'    '13-15'    '15-17'    '17-19'
-------------------- ---------- ---------- ---------- ---------- ----------
Balham Blazers                0          1          0          0          0
Bec United                    1          0          0          0          1
Dinamo Tooting                0          0          0          0          0
Melchester Rovers             0          0          0          1          0

SQL>

无论如何,这种数据模型的优点是它是灵活的。我们可以计算一个团队的出席频率,他们参加的时间,他们参加的一周中的哪一天,哪些会议总是被预订的,哪些会议很少被预订,等等。此外,管理数据也很容易。特别是,与只有两个表相比,三表解决方案的优点是更容易防止重复预订和非标准或重叠的时隙。

你看,正常化不仅仅是我们用来蒙骗无辜的空话,它提供了真正的实际好处。有几种情况下,驾驶到至少BCNF不是最好的想法。

票数 3
EN

Stack Overflow用户

发布于 2010-07-07 17:15:46

你应该问问你自己为什么要这么做。

有一些可能性,但您的数据库模式很可能不会完全规范化。

所以首先:你想要实现什么?原因是什么?

一些可能性:

  • 某些数据库管理系统提供了创建用户定义类型的功能,您可以使用按位方法(在
  • 中,最简单的方法是使用mysql

但是再问一次:您当前的问题是什么,因为找出某人出现的天数只不过是连接适当的表,并使用count函数进行聚合

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3193227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档