2013-02-24 114 views
1

我有4個學期的學生,我很擔心他們出席的每個科目。不同學期的學生分成批次。每個批次都可以選擇36個科目中的一個科目。將考勤存儲在數據庫中

首先我創建了一張表subject,其中我列出了四個批次的主題代碼的所有主題。我有另一張表student,其中我有studentid和6列將有學生選擇的主題代碼。通過加入,我可以知道學生選擇了哪個科目。

現在我無法弄清楚如何以乾淨的方式存儲每日就診。請建議一種方式,因爲我需要存儲365天的數據和1500多名學生。 (星期日不是一些批次的假期)。

我發現幾個相關的主題,包括Storing attendance records in the database和其他一些但我找不到解決方案。

回答

3

我有這樣的事情:

Subjects(SubjectId PK, Name, etc...) 
Classes(ClassId PK, SubjectId, DateTime periodBegin, etc...) 
Students(StudentId PK, Name, etc...) 
StudentAttendance(StudentId PK, ClassId PK) 

Subjects包含每個科目的記錄,Classes包含在校歷安排每個班級的記錄。 Classes表需要用實際的課程組件填充 - 您可以在課程開始時添加它們,也可以在學年開始時批量添加它們。 Students表是不言自明的,StudentAttendance表列出了哪些學生積極參加特定班級。

不要認爲像StudentAttendance這樣的表是不好的設計 - 這是多對多連接表的典型示例。看到一些在連接表中有數十億行的數據庫並不罕見,但是因爲它只包含兩個鍵值(大概是int32或int64),所以它不會在磁盤上佔用太多空間。

下面是發現哪些學生沒有參加具體類的查詢:

SELECT 
    Name 
FROM 
    Students 
WHERE 
    StudentId NOT IN (
     SELECT 
      StudentId 
     FROM 
      StudentAttendance 
      INNER JOIN Classes ON StudentAttendance.ClassId = Classes.ClassId 
     WHERE 
      StudentAttendance.ClassId = @classId 
    ) 

這裏有一個查詢,獲取考勤計數爲每個學生誰參加了一個特定的主題。除以(SELECT Count(*) FROM Clases WHERE Classes.SubjectId = @subject)以獲得每個學生的出勤率。如果學生從未參加任何課程(故意或因爲他們未註冊),則他們將不會出現在列表中。

SELECT 
    Students.Name 
    COUNT(*) As AttendanceCount 
FROM 
    StudentAttendance 
    INNER JOIN Classes ON Classes.ClassId = StudentAttendance.ClassId 
    INNER JOIN Students ON Students.StudentId = StudentAttendance.StudentId 
GROUP BY 
    StudentId 
WHERE 
    Classes.SubjectId = @subjectId 
+0

在我的情況下,每天最少4班,最多6班。那麼'studentAttendance'表每個學生將有6 * 365條記錄和6 * 365 * 1500條記錄總數?它會導致任何性能問題?如果我想存儲日期信息,那麼存儲它的最佳方式是什麼? – NewUser 2013-02-24 09:01:21

+0

謝謝..你剛剛提供了所有的細節,我將試圖找出存儲出席後。我不習慣'@ subjectId'的約定是否意味着它將被嵌入到程序中? – NewUser 2013-02-24 09:07:08

+0

假設每個'StudentAttandance'條目消耗32個字節('StudentId'爲8,'ClassId爲8',內部數據庫使用爲16),假設數據庫中有100%的高效包裝,那麼給出的估計數據庫表不會更大比3.2MB。如果您爲'ClassId'和'StudentId'列添加必要的反向查找索引,那麼您可能需要將其增加到9MB左右 - 您的RDBMS將管理這些索引,因此您不必擔心它們。 – Dai 2013-02-24 09:07:17

0

使用外鍵將連接表創建爲學生和主題以及日期字段,併爲給定日期的特定班級的每個學生存儲一行。通過適當的索引,性能應該是可以接受的。