我有一个学生表和一个课程表,通过中间表连接创建多对多关系(即学生可以注册多个课程,一个课程可以有多个学生)。问题是客户希望每门课程都有一个唯一的学生ID。例如:
rowid Course Student ID (calculated)
1 A Ben 1
2 A Alex 2
3 A Luis 3
4 B Alex 1
5 B Gail 2
6 B Steve 3
ID应该从1开始编号,并且学生可以为不同的课程使用不同的ID(例如,Alex对于课程A具有ID = 2,但对于课程B,ID = 1)。一旦分配了ID,它就是固定的,不能改变。我通过对表格“SELECT Student from table WHERE Course = A ORDER BY rowid”的rowid进行排序,然后根据结果的顺序返回一个数字来实现解决方案。
这个解决方案的问题在于,如果学生离开课程(从表中删除),其他学生的数字将会改变。有人可以推荐更好的方法吗?如果重要,我正在使用PostgreSQL和Django。这就是我的想法:
我认为第一种解决方案更好,但是有更多“以数据库为中心的方式”,数据库可以自动为我计算吗?
答案 0 :(得分:2)
如果你想拥有稳定的ID
,你需要将它们存储在表格中。
您需要为每个加入课程的学生分配一个新的顺序ID
,如果学生离开,只需将其删除,而不会触及其他人。
如果您有对表的并发访问权限,请不要使用MAX(id)
,因为两个查询可以在将其插入表格之前选择相同的MAX(id)
。
相反,创建一个单独的表用作sequence
,用SELECT FOR UPDATE
锁定每个课程的行,然后插入新学生的ID
并使用新的{{更新行1}}在单个事务中,如下所示:
Courses: Name NextID ------- --------- Math 101 Physics 201 Attendants: Student Course Id ------- ------ ---- Smith Math 99 Jones Math 100 Smith Physics 200
ID
答案 1 :(得分:0)
您的第一个建议似乎很好:在课程表中有一个last_id字段,只要您在该课程中注册学生,就会增加1。
答案 2 :(得分:0)
为ID创建一列 计算它。当一个新的 建立关系分配 ID基于最大(id)+1 课程中的学生
我是怎么做的。没有必要计算它。并且id不应该因为某人退出而改变。
添加“已禁用”列并进行设置 当学生离开时,这是真的 课程。
是的,这是个好主意。另一个是创建另一个具有相同结构的表,您将存储掉落的学生。当然,你必须从这两个表的联合中选择max(id)。
答案 3 :(得分:0)
我认为您需要两个概念来帮助您。
从快速谷歌看起来Django可以处理序列而不是复合键,所以你需要以某种方式模拟它。但是,您可以同样拥有两个外键和课程/学生关系的序列
至于如何处理删除,这取决于您的应用程序需要什么,您可能会发现状态字段可以帮助您,因为您可能想要区分离开的学生和被踢出的学生,或获取统计数据有多少学生留下不同的课程。