您在问题标题中使用“优化”一词,而不解释您想优化什么。
如果你在谈论查询性能,那么你没有问题。您可以拥有的记录数由您每天的会话数决定(因为只有一个团队可以参加任何特定会话)。如果你每天运行十个会话,每月有三百个记录。如果每天运行一百次,每月有三千条记录。这些数据量不大。因此,您通过歪曲数据库设计来做出一个糟糕的决定,以避免出现不存在的性能问题。
您在其中一条评论中提到了电子表格。这不是一个糟糕的设计。沿着第一排有一些会议,一边是团队,另一边是细胞显示一个团队是否出席了会议。这些映射到三个数据库表:SESSIONS,TEAMS和相交表TEAM_SESSIONS。团队出席会议时,您只需要TEAM_SESSIONS中的记录。
作为一个概念证明,我在Oracle中敲了三张表。
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>
在Oracle 11g中引入的PIVOT功能使它成为不在话下敲了一个矩阵(DBMS的不同口味都会有不同的方法可以解决这个)。正如你所看到的,今天有三支球队已经预定了会议,没有人希望在午餐时间训练,并且Bec United非常热衷于芥末(或者需要训练)!
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不是最好的主意。
来源
2010-07-07 12:39:38
APC
正在转向这种模式。你如何查询一个月的所有用户出勤记录?你将如何加入AttMst表? – Sam 2010-07-07 09:24:03
'select date,userid from AttMst am,AttDet ad where am.id = ad.id group by date'这将显示日期现在的用户。但它是未经测试的查询请检查它。 – Himadri 2010-07-07 09:39:42