【问题标题】:improve database table design depending on a value of a type in a column根据列中类型的值改进数据库表设计
【发布时间】:2013-08-06 05:52:05
【问题描述】:

我有以下:
1. 我存储患者数据的表“患者”
2. 一个表“测试”,我在其中存储对每个患者进行的测试数据。

现在问题来了,因为我有两种类型的测试 "tests_1""tests_2" 因此,对于对特定患者进行的每项测试,我都会存储测试类型的类型和 ID:

CREATE TABLE IF NOT EXISTS patients
(
    id_patient   INTEGER PRIMARY KEY,
    name_patient VARCHAR(30) NOT NULL,
    sex_patient VARCHAR(6) NOT NULL,
    date_patient DATE
);

INSERT INTO patients values 
(1,'Joe',  'Male'  ,'2000-01-23');
INSERT INTO patients values 
(2,'Marge','Female','1950-11-25');
INSERT INTO patients values 
(3,'Diana','Female','1985-08-13');
INSERT INTO patients values 
(4,'Laura','Female','1984-12-29');

CREATE TABLE IF NOT EXISTS tests
(
    id_test         INTEGER PRIMARY KEY,
    id_patient      INTEGER,
    type_test       VARCHAR(15) NOT NULL,
    id_type_test    INTEGER,
    date_test   DATE,
    FOREIGN KEY (id_patient) REFERENCES patients(id_patient)
);
INSERT INTO tests values
(1,4,'test_1',10,'2004-05-29');
INSERT INTO tests values
(2,4,'test_2',45,'2005-01-29');
INSERT INTO tests values
(3,4,'test_2',55,'2006-04-12');


CREATE TABLE IF NOT EXISTS tests_1
(
    id_test_1  INTEGER PRIMARY KEY,
    id_patient INTEGER,
    data1         REAL,
    data2         REAL,
    data3         REAL,
    data4         REAL,
    data5         REAL,
    FOREIGN KEY (id_patient) REFERENCES patients(id_patient)
);
INSERT INTO tests_1 values
(10,4,100.7,1.8,10.89,20.04,5.29);

CREATE TABLE IF NOT EXISTS tests_2
(
    id_test_2   INTEGER PRIMARY KEY,
    id_patient INTEGER,
    data1         REAL,
    data2         REAL,
    data3         REAL,
    FOREIGN KEY (id_patient) REFERENCES patients(id_patient)

);
INSERT INTO tests_2 values
(45,4,10.07,18.9,1.8);
INSERT INTO tests_2 values
(55,4,17.6,1.8,18.89);

现在我认为这种方法是多余的或不好的......

所以我想改进像

这样的查询
select * from tests WHERE id_patient=4;
select * from tests_1 WHERE id_patient=4;
select * from tests_2 WHERE id_patient=4;

有没有更好的方法?

在此示例中,我为 id=4 的患者进行了 1 个 tests_1 类型的测试和 2 个 tests_2 类型的测试。

Here is a fiddle

【问题讨论】:

    标签: sql database database-design


    【解决方案1】:

    添加一个表 testtype (id_test,name_test) 并将其用作 tests 表中的 id_type_test 字段的 FK。不要为test_1test_2 创建单独的表

    【讨论】:

    • 另外,从测试中删除列 type_test。
    • 使用该表的查询看起来像使用 testtype 吗?我必须加入那些表?
    • 是的,您必须加入这些表,但testtype 表会非常小,会在 PK 上有索引,并且对查询性能的影响最小。 (您还应该在 tests 表中索引 FK 字段。
    • 你说“不要为 test_1 和 test2 创建表”我已经完成了这个小提琴,但仍然不明白如何根据测试类型添加值INSERT INTO tests_1 values (10,4,100.7,1.8,10.89,20.04,5.29); INSERT INTO tests_2 values (45,4,10.07,18.9,1.8); INSERT INTO tests_2 values (55,4,17.6,1.8,18.89); 这是小提琴sqlfiddle.com/#!7/a2925
    • 在您的小提琴中,您在 id_type_test 列中插入值 10,45,55,这些不是有效的测试类型 ID。测试类型只能是1或2。我认为您需要tests表中的test_result列来保存测试结果的实际值。
    【解决方案2】:

    这取决于需求

    对于 OLTP,我会执行以下操作

    员工:

    ID | FORENAME | SURNAME | DATE_OF_BIRTH | JOB_TITLE   | ... 
    -------------------------------------------------------------
     1 | harry    | potter  | 2001-01-01    | consultant  | ...
     2 | ron      | weasley | 2001-02-01    | pathologist | ...
    

    患者:

    ID | FORENAME | SURNAME | DATE_OF_BIRTH | ...
    -----------------------------------------------
     1 | hermiony | granger | 2013-01-01    | ...
    

    TEST_TYPE:

     ID | CATEGORY    | NAME | DESCRIPTION           | ...
    --------------------------------------------------------
      1 | haematology | abg  | arterial blood gasses | ...
    

    请求:

    ID | TEST_TYPE_ID | PATIENT_ID | DATE_REQUESTED | REQUESTED_BY | ...
    ----------------------------------------------------------------------
     1 | 1            | 1          | 2013-01-02     | 1            | ...
    

    RESULT_TYPE:

    ID | TEST_TYPE_ID | NAME | UNIT | ...
    ---------------------------------------
     1 | 1            | co2  | kPa  | ...
     2 | 1            | o2   | kPa  | ...
    

    结果:

    ID | REQUEST_ID | RESULT_TYPE_ID | DATE_RESULTED | RESULTED_BY | RESULT | ...
    -------------------------------------------------------------------------------
     1 | 1          | 1              | 2013-01-02    | 2           | 5      | ...
     2 | 1          | 2              | 2013-01-02    | 2           | 5      | ...
    

    我对上述问题的担忧是测试结果的unit,这些有时(不经常)会发生变化。将unit 放在结果表中可能会更好。

    还可以考虑将它们分成主要的测试类别,因为我的理解是它们可能完全不同,例如组织病理学和 X 射线的结果与血液学和微生物学不同。

    对于 OLAP,我会将请求和结果合并到一个表中,添加派生列,例如 REQUEST_TO_RESULT_MINS,并从 RESULT_TYPETEST_TYPE 等创建一个维度。

    【讨论】:

      【解决方案3】:

      您可以通过几种方式做到这一点。不知道您需要处理的所有不同类型的案件。

      最简单的就是 5 张桌子

      • 患者(如您所描述)
      • 测试(就像你描述的那样)
      • TestType(如建议的 Declan_K)
      • 测试结果代码
      • 测试结果

      TestRsultCode 描述为每个测试存储的每个值。 TestResults 是一个透视表,可以存储每个测试的任意数量的测试结果:

      Create table TestResultCode
      (
        idTestResultCode int
      , Code varchar(10)
      , Description varchar(200)
      , DataType int -- 1= Real, 2 = Varchar, 3 = int, etc.
      );
      
      Create Table TestResults
      (
        idPatent int -- FK
      , idTest   int -- FK
      , idTestType int -- FK
      , idTestResultCode int -- FK
      , ResultsI real
      , ResultsV varchar(100)
      , Resultsb int
      , Created datetime
      )
      

      所以,基本上您可以将想要添加的结果放入“tests_1”和“tests_2”表以及您能想到的任何其他测试中。

      读取此表的应用程序可以加载每个测试及其所有值。当然,应用程序需要知道如何处理每种情况,但是您可以在此结构中存储任何类型的测试。


      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-03
        • 2013-12-09
        • 1970-01-01
        • 2021-12-21
        • 2014-04-17
        • 2019-04-29
        • 1970-01-01
        相关资源
        最近更新 更多