多对多关系的数据表设计

碰到多对多 的关系,一般都是建立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_id64 ,接着某用户一次借阅了3 本书,则批量插入的3 条借阅记录的batch_no 都是65 。之后另外一个用户租了一套碟,再插入出租记录的rent_id68 。采用这种设计,查询批量借阅的信息时,只需使用一条标准T_SQL 的嵌套查询即可。当然,这种设计不符合3NF ,但是和上面标准的3NF 设计比起来,哪一种更好呢?答案就不用我说了吧。

猜你喜欢

转载自canann.iteye.com/blog/1763712