MySQL 查询以获取所有(附加)症状和疾病
MySQL query to get all (additional) symptoms and diseases
我有一个包含主要症状、附加症状和疾病的数据库。我需要替换 2 个查询,因为我确信我的第一个查询效率不高,而我的第二个查询根本不正确。我希望有人能帮助我,因为我是这个领域的新手..
数据库说明:
医疗应用程序正在使用该数据库:
- 用户选择了特定的身体部位
- 该应用列出了该特定身体部位的所有主要症状
- 用户选择一个主要症状(常见或不常见)
应用程序列出了所选主要症状的所有疾病。还会出现 2 个复选框(附加症状),用户可以选中这些复选框。列出的疾病 (d_weight) 的顺序取决于年龄、性别、选择的主要症状以及用户选中的框。 d_weight
<= 5 的疾病被认为是常见病。 d_weight
> 5 的疾病被认为是 less-common。用户输入的可能性(年龄、性别、身体部位、主要症状)存储在 symptom_disease_combi table.
中
asa_id
是所有适用症状的 ID(用户检查的附加症状)
asc_id
是属于特定主症的附加症状的所有可能的id。例如,asc_id
= 0,以防未选择其他症状。 asc_id
= 1,以防仅选择附加症状 'Insomnia'。 asc_id
= 2,以防同时选择 'Insomnia' 和 'Blowing up'。
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
在疾病和症状中创建以告诉用户他们需要立即去医院,当他们点击疾病或症状时
age
、gender
、bodypart
是id的,所以age
= 1,表示0-5,age
= 2表示6-17 , age
= 3 表示 18-59 并且 age
= 4 表示 60+.
- 请看一下应用程序的设计,这对理解数据库的设计有很大帮助:http://i.imgur.com/p9QP1av.png顺便说一句,在设计中;原因==疾病...
asa_id
指的是adlsymptom_apply 的id
asc_id
指的是adlsymptom_combi 的id
- 'distinct' 只用了 1 次就得到了所有 symptoms/diseases。我确定不需要它,但我不知道如何修复它。
排除 2 个症状 tables,使用一个(症状)和 1 个相交 table (sdc)
我会不会向症状添加一个新列,例如status/level试图增加一个症状
重要的还是次要的,尽管有诱惑,因为这很容易
使其不灵活。
例如,晕倒一次可能看起来很严重disease/condition,但一般来说它可能会扭曲
一般性,因此 1 table 症状,您正确地在 sdcd_weight 中有一个
我喜欢你的sdc.d_weight概念。
例如,昏厥可能与癫痫有关,但与流感无关。整个概念
当流感患者服用 Zarontin 而不是 Tamiflu 时就搞砸了
既然我喜欢你的 sdc.d_weight 概念,我想知道你为什么会出现其他症状 table
在 table sdc 中,您有 keys/indexes 名称以 "FK_" 开头。希望你有实际的 FK 约束
不仅仅是让您认为自己拥有它们的命名约定(FK,您没有)
例如,身体部位、症状和 disease/condition 的真实 FK。
当用户选择症状时,将它们从 GUI 中删除,以便再次添加该症状以进行搜索
这减少了工作并通过放弃辅助 table(我写的和建议的第 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',前列腺癌?
我基于你的 age=xxxxx 行,也许你的意思是 >=。或者对于白血病,<= ...我认为
您的架构需要考虑一下
所以我从下面的查询中排除了年龄
-- 对于下一个查询,我想知道你为什么需要一个不同的?
-- 给定的症状行是否有超过 1 sdc.s_common?只有你会知道
-- 如果不是,放弃 distinct
-- 你的 join on 子句的顺序很重要,让它遵循一个好的索引以便结果快速返回
-- 我并不是说这些是覆盖索引,但你会尽量减少 table 扫描 activity
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."
-- 不是我上面关于年龄的评论
-- 根据需要在计算列中合并权重
这些是我的建议,祝你好运
我有一个包含主要症状、附加症状和疾病的数据库。我需要替换 2 个查询,因为我确信我的第一个查询效率不高,而我的第二个查询根本不正确。我希望有人能帮助我,因为我是这个领域的新手..
数据库说明:
医疗应用程序正在使用该数据库:
- 用户选择了特定的身体部位
- 该应用列出了该特定身体部位的所有主要症状
- 用户选择一个主要症状(常见或不常见)
应用程序列出了所选主要症状的所有疾病。还会出现 2 个复选框(附加症状),用户可以选中这些复选框。列出的疾病 (d_weight) 的顺序取决于年龄、性别、选择的主要症状以及用户选中的框。
中d_weight
<= 5 的疾病被认为是常见病。d_weight
> 5 的疾病被认为是 less-common。用户输入的可能性(年龄、性别、身体部位、主要症状)存储在 symptom_disease_combi table.asa_id
是所有适用症状的 ID(用户检查的附加症状)asc_id
是属于特定主症的附加症状的所有可能的id。例如,asc_id
= 0,以防未选择其他症状。asc_id
= 1,以防仅选择附加症状 'Insomnia'。asc_id
= 2,以防同时选择 'Insomnia' 和 'Blowing up'。
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
在疾病和症状中创建以告诉用户他们需要立即去医院,当他们点击疾病或症状时age
、gender
、bodypart
是id的,所以age
= 1,表示0-5,age
= 2表示6-17 ,age
= 3 表示 18-59 并且age
= 4 表示 60+.- 请看一下应用程序的设计,这对理解数据库的设计有很大帮助:http://i.imgur.com/p9QP1av.png顺便说一句,在设计中;原因==疾病...
asa_id
指的是adlsymptom_apply 的id
asc_id
指的是adlsymptom_combi 的id
- 'distinct' 只用了 1 次就得到了所有 symptoms/diseases。我确定不需要它,但我不知道如何修复它。
排除 2 个症状 tables,使用一个(症状)和 1 个相交 table (sdc)
我会不会向症状添加一个新列,例如status/level试图增加一个症状 重要的还是次要的,尽管有诱惑,因为这很容易 使其不灵活。
例如,晕倒一次可能看起来很严重disease/condition,但一般来说它可能会扭曲
一般性,因此 1 table 症状,您正确地在 sdcd_weight 中有一个
我喜欢你的sdc.d_weight概念。
例如,昏厥可能与癫痫有关,但与流感无关。整个概念 当流感患者服用 Zarontin 而不是 Tamiflu 时就搞砸了
既然我喜欢你的 sdc.d_weight 概念,我想知道你为什么会出现其他症状 table
在 table sdc 中,您有 keys/indexes 名称以 "FK_" 开头。希望你有实际的 FK 约束
不仅仅是让您认为自己拥有它们的命名约定(FK,您没有)
例如,身体部位、症状和 disease/condition 的真实 FK。
当用户选择症状时,将它们从 GUI 中删除,以便再次添加该症状以进行搜索
这减少了工作并通过放弃辅助 table(我写的和建议的第 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',前列腺癌? 我基于你的 age=xxxxx 行,也许你的意思是 >=。或者对于白血病,<= ...我认为 您的架构需要考虑一下
所以我从下面的查询中排除了年龄
-- 对于下一个查询,我想知道你为什么需要一个不同的? -- 给定的症状行是否有超过 1 sdc.s_common?只有你会知道 -- 如果不是,放弃 distinct
-- 你的 join on 子句的顺序很重要,让它遵循一个好的索引以便结果快速返回
-- 我并不是说这些是覆盖索引,但你会尽量减少 table 扫描 activity
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."
-- 不是我上面关于年龄的评论 -- 根据需要在计算列中合并权重
这些是我的建议,祝你好运