2013-10-30 95 views
1

我想创建一个存储医生的表。我的问题是如何存储医生的专业,因为医生可以有多个(口腔医师,皮肤科医生)。到目前为止,我已经使用了varchar类型,并以逗号分隔的格式存储了值。MySQL - 我应该使用什么数据类型来存储一组字符串

CREATE TABLE IF NOT EXISTS `doctors` (
    `doctor_id` int(11) NOT NULL AUTO_INCREMENT, 
    `email` varchar(50) NOT NULL, 
    `password` varchar(30) NOT NULL, 
    `firstname` varchar(30) NOT NULL, 
    `lastname` varchar(30) NOT NULL, 
    `speciality` varchar(254) NOT NULL, 
    `lat` decimal(10,8) NOT NULL, 
    `lng` decimal(10,8) NOT NULL, 
    `phone` char(10) NOT NULL, 
    `mobile` char(10) NOT NULL, 
    PRIMARY KEY (`doctor_id`) 
); 

但我的问题是当查询表时。如果我想找到有专业的“阿尔法”医生,我这样做

select * from doctors where speciality='alfa' 

有两个专业(阿尔法,β),医生将不包括在结果中。我唯一想到的是使用LIKE而不是WHERE,但我认为必须有更好的方法。什么是最好的方式来实现这个(也许从varchar不同的数据类型)?

+1

使用foriegn键 – karthikr

+0

@karthikr事实上,最好的*数据类型*,以避免问一个常见的问题:'我怎样才能过滤逗号分隔的一组ID?' –

回答

2

这是一个多对多的关系。每个医生都可能有多种专业,而且许多医生都有各自的专业。

Doctors >--------< Specialties 

在关系数据库中表示多对多关系的方式不是用逗号分隔的列表,而是用另一个表格。

Doctors ----<HasSpecialty>---- Specialties 

下面是一个例子:

CREATE TABLE HasSpecialty (
    specialty_id INT, 
    doctor_id INT, 
    PRIMARY KEY (specialty_id, doctor_id), 
    KEY (doctor_id, specialty_id), 
    FOREIGN KEY (doctor_id) REFERENCES Doctors(doctor_id), 
    FOREIGN KEY (specialty_id) REFERENCES Specialties(specialty_id) 
); 

查询与给定的专科医生,做一个JOIN:

SELECT d.* FROM Doctors AS d 
INNER JOIN HasSpecialty AS hs USING (doctor_id) 
INNER JOIN Specialties AS s USING (specialty_id) 
WHERE s.specialty = 'alfa'; 

有些人不喜欢的JOIN,因为他们认为他们是缓慢的。他们竭尽全力避免JOIN,例如使用依赖子查询,其可能是更差。有了适当的索引,联接并不慢。

+0

谢谢!这似乎是正确的。特别是因为SET不适合我的情况。 –

0

你可以使用类型SET http://dev.mysql.com/doc/refman/5.5/en/set.html然后你甚至可以使用位字段映射找到数据。但要小心这种类型有一些限制。看看文档。

+1

其中一个限制是你只能拥有SET中64个不同的值。对于医生的所有专业来说这可能是不够的。 –

+0

@BillKarwin通过SET中64个不同的值,你的意思是记录中的SET,对吧?我不认为会有超过64个专业的医生...... –

+0

对,任何医生都不会有64个专业,但*所有*医生都有各种各样的专业。 SET必须定义列定义中可能值的枚举。因此,所有行都从同一组值中进行选择,并且您仅限于其中的64个。 –

0

这些列上创建的doctor_specialties表:

doctor_id int not null 
specialty varchar(254) not null 

doctor_id应该是一个外键doctors,并考虑在两列2列主键。

在此表中插入记录,引用医生及其专业。如果医生有多个专业,你会有多个记录。

然后,查询有一定的专业医生,你可以这样做:

select * from doctors d 
where exists (select * from doctor_specialties 
       where doctor_id = d.doctor_id 
        and specialty = 'alfa'); 

有许多的方式来写这个查询,包括子选择或连接。当我不需要返回另一个表中的信息时,我使用EXISTS。

相关问题