碰到多对多 的关系,一般都是建立3 个表,m 一个,n 一个,m:n 一个。但是,m:n 有时会遇到批量处理的情况,例如到图书馆借书,一般都是允许用户同时借阅n 本书,如果要求按批查询借阅记录,即列出某个用户某次借阅的所有书籍,该如何设计呢?让我们建好必须的3
书籍表(Book_table)
名称 类型 约束条件 说明
book_id int 无重复 书籍标识,主键
book_no char(20) 无重复 书籍编号
book_name char(100) 不允许为空 书籍名称
……
借阅用户表(Renter_table)
名称 类型 约束条件 说明
renter_id int 无重复 用户标识,主键
renter_name char(20) 不允许为空 用户姓名
……
借阅记录表(Rent_log)
名称 类型 约束条件 说明
rent_id int 无重复 借阅记录标识,主键
r_id int 不允许为空 用户标识,和Renter_table.renter_id 关联
b_id int 不允许为空 书籍标识,和Book_table.book_id 关联
rent_date datetime 不允许为空 借阅时间
……
为了实现按批查询借阅记录,我们可以再建一个表来保存批量借阅的信息,例如:
批量借阅表(Batch_rent)
名称 类型 约束条件 说明
batch_id int 无重复 批量借阅标识,主键
batch_no int 不允许为空 批量借阅编号,同一批借阅的batch_no 相同
rent_id int 不允许为空 借阅记录标识,和Rent_log.rent_id 关联
batch_date datetime 不允许为空
这样的设计好吗?我们来看看为了列出某个用户某次借阅的所有书籍,需要如何查询?首先检索批量借阅表(Batch_rent) ,把符合条件的的所有记录的rent_id 字段的数据保存起来,再用这些数据作为查询条件带入到借阅记录表(Rent_log) 中去查询。那么,有没有什么办法改进呢?下面给出一种简洁的批量设计方案,不需添加新表,只需修改一下借阅记录表(Rent_log) 即可。修改后的记录表(Rent_log)
借阅记录表(Rent_log)
名称 类型 约束条件 说明
rent_id int 无重复 借阅记录标识,主键
r_id int 不允许为空 用户标识,和Renter_table.renter_id 关联
b_id int 不允许为空 书籍标识,和Book_table.book_id 关联
batch_no int 不允许为空 批量借阅编号,同一批借阅的batch_no 相同
rent_date datetime 不允许为空 借阅时间
……
其中,同一次借阅的batch_no 和该批第一条入库的rent_id 相同。举例:假设当前最大rent_id 是64 ,接着某用户一次借阅了3 本书,则批量插入的3 条借阅记录的batch_no 都是65 。之后另外一个用户租了一套碟,再插入出租记录的rent_id 是68 。采用这种设计,查询批量借阅的信息时,只需使用一条标准T_SQL 的嵌套查询即可。当然,这种设计不符合3NF ,但是和上面标准的3NF 设计比起来,哪一种更好呢?答案就不用我说了吧。