准备对一个化验室信息系统做数据库设计,这方面一点不懂,求教大家:
需求如下:
一个样品,需经过多组检测,每组检测不同的项目;
不同种类的样品,部分组别检测的项目相同,部分组别检测的项目不相同;
目前设计方案两种如下:方案一:
样品基本信息表      组别1检测 组别2检测 组别3检测        组别4检测
--样品名称 ---项目1 ---项目31 ---项目51 ...
--样品种类 ---项目2 ---项目32 ---项目52
--采样时间 ---项目3 ---项目33 ---项目53
--等等 ..... ...... ....
---项目30 ---项目50 --项目60
这种设计,每组的检测项目是最大化的,有些样品可能只检测其中7,8种项目。
方案二:
样品类别1 样品类别2 样品类别3 样品类别4
---项目1 ---项目1 ---项目1
---项目2 ---项目2 ---项目2
---项目3 ---项目3 ---项目3
--- ... ...
--项目40
这种设计,不同的样品类别会造成很多检测项目是相同的,是否太过冗余了。
求教:相对来说哪种方案合适点,或者有更好的设计方案,便于存储查询和今后的扩展(比如多增加一个检测项目)?谢谢大家。

解决方案 »

  1.   

    对单一的样品来说,不同样品的检测项目是不同(不固定)的。
    对同一种类的样品来说,检测项目是相同(固定)的。
    设计是这样的?:
    样品表
    --样品编号(主)
    --样品种类(外)
    --采样人
    ---等等
    样品检测项目表
    --项目id
    --项目名称
    样品-检测项目关联表
    --id
    --项目id
    --样品种类那样品检测值,放哪里?样品表里面?
      

  2.   

    1、样品表(Sample)
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Sample]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[Sample]
    GOCREATE TABLE [dbo].[Sample] (
    [id] [int] NOT NULL ,
    [TypeId] [int] NULL ,
    [SampleName] [char] (30) COLLATE Chinese_PRC_CI_AS NULL 
    ) ON [PRIMARY]
    GO2、样品种类表(Kinds)
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[SampleType]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[SampleType]
    GOCREATE TABLE [dbo].[SampleType] (
    [id] [int] NOT NULL ,
    [TypeName] [char] (30) COLLATE Chinese_PRC_CI_AS NULL 
    ) ON [PRIMARY]
    GO3、检测项目表(TestItems)
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TestItems]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[TestItems]
    GOCREATE TABLE [dbo].[TestItems] (
    [id] [int] NOT NULL ,
    [TestName] [char] (30) COLLATE Chinese_PRC_CI_AS NULL 
    ) ON [PRIMARY]
    GO4、取样人表(SampleOfPeople)
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[SampleOfPeople]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[SampleOfPeople]
    GOCREATE TABLE [dbo].[SampleOfPeople] (
    [id] [int] NULL ,
    [name] [char] (10) COLLATE Chinese_PRC_CI_AS NULL 
    ) ON [PRIMARY]
    GO5、样品种类——检测项目表(Kind_Test)
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Kind_Test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[Kind_Test]
    GOCREATE TABLE [dbo].[Kind_Test] (
    [KindID] [int] NOT NULL ,
    [TestID] [int] NOT NULL 
    ) ON [PRIMARY]
    GO
    6、检测结果表(TestResults)(重点)
    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[TestResults]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[TestResults]
    GOCREATE TABLE [dbo].[TestResults] (
    [ID] [char] (10) COLLATE Chinese_PRC_CI_AS NOT NULL ,
    [SampleId] [int] NOT NULL ,
    [PeopleId] [int] NOT NULL ,
    [KindId] [int] NOT NULL ,
    [Result] [char] (30) COLLATE Chinese_PRC_CI_AS NULL 
    ) ON [PRIMARY]
    GO关于最终检测结果的显示调用:
    在网上找一下数据表的行列转换方法,对表TestResults进行行列转换就可以实现了。如果感觉转换速度太慢,可以考虑做个表专门存贮转换后的结果。PS:上面发了条垃圾信息,不好意思。
      

  3.   

    谢谢详细回帖,也谢谢大家的意见。有些疑问还是不懂:样品种类表:
    1 种类1
    2 种类2样品表:
    1 1 种类1   样品1
    2 2 种类2 样品2
    检测项目表:(100项)
    1 检验项目1
    2 检验项目2
    3 检验项目3
    ...
    100 检验项目100中间表:
    id kindid testid 值
    1 1 1  10
    2 1 2 20
    3 1 3 30
    4 2 1 11
    5 2 3 12结果表:(如果存在)
    id Result SampleID KINDID
    1 10 1 1
    2 20 1 1
    3 30 1 1我知道一个多对多关系,一般转换为两个一对多来处理,主要是样品种类,样品,检测项目的关系。(检测项目是分组的,其中有两组检测项目固定,其余根据样品类别有所变化)
    疑问:
    1. 如果采用结果表,一个样品检测过后,如何将值存储到结果表中,好像也查询不出什么检测项目?2.值直接存储在中间表中,一个样品检测项目估计有40个左右,如何插入值?这样查询起来有没有问题?3.一个样品的所有检测项目,对应范围都要有所限制,如设定上下限之类,这个表又如何设计,和哪些需要关联?如下
    检测数据范围表:
    样品名 检测项目 上限 下限
    样品1 项目1 100 1
    样品2 项目2 200 2
      

  4.   

    不要用存储表了,你这样,无疑就是增加了查询时间。你可以用视图将几个表连接起来,插入数据,你可以用SQL Server2K的触发,