MySQL查询以获取所有(附加)症状和疾病

时间:2015-06-13 22:46:08

标签: mysql database database-design relational-database database-schema

我有一个包含主要症状,其他症状和疾病的数据库。我需要替换2个查询,因为我确信我的第一个查询效率不高,而我的第二个查询根本不正确。我希望有人可以帮助我,因为我是这个领域的新手..

数据库说明:

医疗应用程序正在使用该数据库:

  1. 用户选择特定的bodypart
  2. 该应用程序列出了该特定身体部位的所有主要症状
  3. 用户选择主要症状(常见或不太常见)
  4. 该应用程序列出了所选主要症状的所有疾病。还会出现2个可由用户检查的复选框(其他症状)。列出的疾病(d_weight)的顺序取决于年龄,性别,选择的主要症状以及用户检查的框。 d_weight <= 5的疾病被认为是常见疾病。患有d_weight&gt;的疾病。 5被认为不太常见。用户输入的可能性(年龄,性别,身体部位,主要症状)存储在symptom_disease_combi表中。

    • asa_id是适用的所有症状的ID(由用户检查的附加症状)
    • asc_id是属于特定主要症状的其他症状的所有可能性的ID。例如,asc_id = 0,以防没有选择其他症状。 asc_id = 1,如果仅选择其他症状'失眠'。 asc_id = 2,如果选择“失眠”和“爆炸”。
  5. 1。查询以获取特定身体部位的所有症状(可以改进):

    SELECT DISTINCT s.name
                  , s.id
                  , sdc.s_common 
               FROM symptom as s
                  , symptom_disease_combi as sdc 
              WHERE sdc.age = ".$age." 
                AND sdc.gender = ".$gender." 
                AND sdc.bodypart = ".$bodypart." 
                AND sdc.s_id = s.id
    

    2。查询以获取所选症状的所有疾病和其他症状(不起作用):

    SELECT DISTINCT d.name
                  , d.id
                  , sdc.d_weight
                  , adls.id
                  , adls.name 
               FROM disease as d 
                  , symptom_disease_combi as sdc
                  , symptom as s
                  , adlsymptom as adls 
              WHERE sdc.age = ".$age." 
                AND sdc.gender = ".$gender." 
                AND sdc.bodypart = ".$bodypart." 
                AND s.id = ".$sid." 
                AND sdc.s_id = s.id
    

    第3。数据库结构(如果我的设计可以改进,请告诉我)

    CREATE TABLE symptom
    (id INT NOT NULL AUTO INCREMENT
    ,name VARCHAR(100) DEFAULT NULL
    ,critical INT NOT NULL
    ,PRIMARY KEY (id)
    ) ENGINE=MyISAM;
    
    id name                    critical
     1 Behavioral disturbances        1
     2 Ear pressure                   0
     3 Elevated temperature           0
     4 Fainting                       0
     5 Head pain                      0
    
    CREATE TABLE disease (
    id int(11) NOT NULL AUTO_INCREMENT,
    name varchar(100) DEFAULT NULL,
    critical int(11) NOT NULL,
    description text NOT NULL,
    tests text NOT NULL,
    treatment text NOT NULL,
    PRIMARY KEY (id)
    ) ENGINE=MyISAM AUTO_INCREMENT=19 DEFAULT CHARSET=latin1
    
    id name                critical    description    tests       treatment
     1 Adjustment disorder 0           lorem ipsum    lorem ipsum lorem ipsum
     2 ADHD                0           lorem ipsum    lorem ipsum lorem ipsum
     3 Drug reaction       0           lorem ipsum    lorem ipsum lorem ipsum
     4 Seizure (epilepsy)  1           lorem ipsum    lorem ipsum lorem ipsum        
    
    CREATE TABLE adlsymptom (
    id int(11) NOT NULL AUTO_INCREMENT,
    name varchar(100) NOT NULL,
    PRIMARY KEY (id)
    ) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
    
    id name
     1 Insomnia
     2 Blowing up
     3 Depressed
     4 Drug abuse
    
    CREATE TABLE adlsymptom_apply (
    id int(11) NOT NULL,
    as_id int(11) NOT NULL,
    PRIMARY KEY (id,as_id),
    KEY FK_additional_symptom_that_apply (as_id)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1
    
    id as_id
     1 1
     1 2
    
    CREATE TABLE adlsymptom_combi (
    id int(11) NOT NULL,
    as_id int(11) NOT NULL,
    PRIMARY KEY (id,as_id),
    KEY FK_additional_symptom_combination (as_id)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1
    
    id as_id
     1 1
     2 2
     3 1
     3 2
    
    CREATE TABLE symptom_disease_combi (
    id int(11) NOT NULL AUTO_INCREMENT,
    age int(11) NOT NULL,
    gender int(11) NOT NULL,
    bodypart int(11) NOT NULL,
    s_id int(11) NOT NULL,
    s_common int(11) NOT NULL,
    asc_id int(11) NOT NULL,
    asa_id int(11) NOT NULL,
    d_id int(11) NOT NULL,
    d_weight int(11) NOT NULL,
    PRIMARY KEY (id),
    KEY FK_symptom (s_id),
    KEY FK_additional_symptom_combination (asc_id),
    KEY FK_additional_symptom_that_apply (asa_id),
    KEY FK_disease (d_id)
    ) ENGINE=MyISAM AUTO_INCREMENT=65 DEFAULT CHARSET=latin1
    
    id age gender bodypart s_id s_common asc_id asa_id d_id d_weight
     1 1   1      1        1    1        0      1      1    1
     2 1   1      1        1    1        0      1      2    2  
     3 1   1      1        1    1        0      1      3    3
     4 1   1      1        1    1        0      1      11   4
    

    更新1:

      创建疾病和症状的
    • critical告诉用户他们需要立即去医院,当他们点击疾病或症状时
    • agegenderbodypart是id,因此age = 1,表示0-5,age = 2表示6-17,{ {1}} = 3表示18-59,age = 4表示60 +。
    • 请看一下应用程序的设计,它将有助于理解数据库的设计:http://i.imgur.com/p9QP1av.png顺便说一句,在设计中;原因==疾病......
    • age指的是adlsymptom_apply的ID
    • asa_id是指adlsymptom_combi的身份证明
    • 'distinct'用于获得所有症状/疾病一次。我确信这不是必需的,但我不知道如何解决它。

1 个答案:

答案 0 :(得分:1)

沟渠2个症状表,一个(症状)和一个交叉表(sdc)

我会在症状中添加新列,例如状态/级别试图填补症状 尽管存在诱惑,但对于主要或次要的重要性,因为这很容易 使它不灵活。

例如,昏厥可能看起来主要是因为一旦疾病/病情,但它可能会扭曲它

寻求一般性,因此有1个症状表,你在sdc中正确拥有d_weight

我喜欢你的sdc.d_weight概念。

例如,晕厥可能对癫痫有一定的影响,但不是流感。整个概念 当患有流感的人被处方Zarontin而不是Tamiflu时被搞砸了

因为我喜欢你的sdc.d_weight概念,我想知道为什么你选择了额外的症状表

在表sdc中,您有名称以“FK_”开头的键/索引。希望你有实际的FK约束

而不只是让你认为你拥有它们的命名约定(FK,你没有它们)

例如,真实的FK用于身体部位,症状和疾病/状况。

当用户选择症状时,将其从GUI再次为搜索添加该症状的能力中删除

这减少了工作并通过抛弃次要表简化了查询(我编写和建议的第1行)

再次注意,您使用KEY(它是索引的同义词,而不是外键约束),只是创建 索引...

create table symptom
(
    id int not null auto_increment primary key,
    name varchar(100) not null, -- if you can't put a name to it, don't have it
    critical int not null
)ENGINE=MyISAM default charset=latin1;

create table disease
(
    id int not null auto_increment primary key, -- don't mix and match int with int(11)
    name varchar(100) not null, -- if you can't put a name to it, don't have it
    critical int not null,
    -- etc columns, text
)ENGINE=MyISAM default charset=latin1;

create table symptom_disease_combi
(   -- a.k.a. sdc
    id int not null auto_increment primary key, -- don't mix and match int with int(11)
    age int not null,
    gender char(1) not null,    -- int(11) is overkill
    bodypart int not null,
    s_id int not null,
    s_common int not null,
    asc_id int not null,
    asa_id int not null,
    d_id int not null,
    d_weight int not null,

    -- additional indexes (note pk above, so it is there and happy)

    -- note that some of your indexes (your KEYS) are worthless for the queries in question
    -- however they may be useful for other queries in your system
    -- for instance your asc and asa indexes will not be useful as they won't be picked up
    -- in relation to the question posed
    --
    -- you will need to find the proper balance of index bloat based on system needs

    INDEX idx_sdc_siddid (s_id,d_id,bodypart),  -- composite, general purpose
    INDEX idx_sdc_didsid (d_id,s_id,bodypart),  -- ditto but reverse
    INDEX idx_sdc_ascid (asc_id),
    INDEX idx_sdc_asaid (asa_id),
    -- put constraints here:
    CONSTRAINT `fk_sdc_bodypart` FOREIGN KEY (bodypart) REFERENCES bodypart(id),
    CONSTRAINT `fk_sdc_sid` FOREIGN KEY (s_id) REFERENCES symptom(id), -- don't mix and match int and int(11)
    CONSTRAINT `fk_sdc_did` FOREIGN KEY (d_id) REFERENCES disease(id)
    -- are there others, such as asc asa tables ??
)ENGINE=MyISAM default charset=latin1;

我认为你需要仔细思考年龄栏 是sdc将装载一个新行,每个年龄一个,50到120,性别='M',前列腺癌? 我基于你的年龄= xxxxx行,也许你的意思是&gt; =。或者对于白血病,&lt; = ...我想 您的架构需要一些思考

所以我从下面的查询中排除年龄

- 对于下一个查询,我想知道为什么你需要一个独特的? - 对于给定的症状行,是否有超过1个sdc.s_common?只有你会知道 - 如果没有,抛弃不同的

- 你的加入条款的顺序很重要,让它遵循一个好的索引,以便结果快速回来

- 我不建议这些是覆盖的索引,但您将最小化表扫描活动

select distinct s.name, s.id, sdc.s_common
from symptom s
join symptom_disease_combi sdc
on sdc.s_id=s.id and sdc.bodypart=".$bodypart." and sdc.gender= ".$gender."

- 不是我上面关于年龄的评论 - 根据需要在计算列中加入权重

这些是我的建议,祝你好运