Mysql在where子句中与字符串相比使用数字更快吗?

问题描述:

比方说你有4种类型的评估,测试,测验,MiniQuiz和FinalExamMysql在where子句中与字符串相比使用数字更快吗?

,我们在数据库中存储的记录,像这样

 
studentid ----- assesType 
1    test 
2    quiz 
3    quiz 
4    quiz 
5    miniquiz 
6    miniquiz 
7    final 
8    final 

是更快,更好的方法来编号分配给各型可以说:

测试= 1个 测验= 2 miniquiz = 3 最终= 4

,并使用此而不是为REC或保持。

 
studentid ----- assesType 
1    1 
2    2 
3    2 
4    2 
5    3 
6    3 
7    4 
8    5 

我真的很想问,这是值得吗?优点等?因为在执行此操作时,以服务器端语言编写代码变得有点困难。

谢谢=)

是,数字比较比字符串比较快。字符串也需要更多的空间,数据重复意味着如果你必须重命名“miniquiz”为“microquiz”,你必须更新所有的行。最后,也可能是最重要的一点,你的数据库将无法拒绝不可接受的字符串:你说有四种类型的评估,但是你的数据库会高兴地接受你传递的任何字符串。

一般而言,您希望创建另一个表,可能会调用它assesTypes,只有idname字段,并保留所有可接受的类型。然后在主表中,使assesType字段为foreign key,该字段引用新表assesTypesid属性。例如:

CREATE TABLE assesTypes (
    id int, 
    name varchar(15), 
    PRIMARY KEY (id) 
) ENGINE=INNODB; 

CREATE TABLE assessments (
    student_id int, 
    assesType  int, 
    mark   int, 
    PRIMARY KEY (student_id, assesType), 
    FOREIGN KEY (assesType) REFERENCES assesTypes (id) 
) ENGINE=INNODB; 

现在我们可以填写我们的assesTypes表:

INSERT INTO assesTypes VALUES (1, 'Test'); 
INSERT INTO assesTypes VALUES (2, 'Quiz'); 
INSERT INTO assesTypes VALUES (3, 'MiniQuiz'); 
INSERT INTO assesTypes VALUES (4, 'FinalExam'); 

现在让我们插入一些评估数据为assessments表:

INSERT INTO assessments VALUES (1, 1, 55); 
INSERT INTO assessments VALUES (1, 2, 65); 
INSERT INTO assessments VALUES (1, 3, 75); 

这一切都很好。现在,我们可以INNER JOINassessments表与assessTypes表是这样的:

SELECT a.student_id, at.name, a.mark 
FROM assessments a 
JOIN assesTypes at ON (at.id = a.assesType); 

对于这个结果:

+------------+----------+------+ 
| student_id | name  | mark | 
+------------+----------+------+ 
|   1 | Test  | 55 | 
|   1 | Quiz  | 65 | 
|   1 | MiniQuiz | 75 | 
+------------+----------+------+ 
3 rows in set (0.00 sec) 

现在,让我们尝试在assessments表中插入无效assesType

INSERT INTO assessments VALUES (1, 5, 75); 

我们不能。 MySQL会报告:

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails 

外键不需要有一个工作的关系型数据库,但他们必须避免关系破裂和孤儿行(即referential integrity)。要求在ACID中的C能够在数据库级别强制执行参照完整性。

+0

嗯谢谢你的回答,请你详细说明你的意思是“你的数据库会高兴地接受你传递的任何字符串。”为什么这不适用于数字? – 2010-08-28 08:00:42

+0

@Akay:让我用一个例子更新我的答案。 – 2010-08-28 08:06:03

+0

噢好吧,我明白了..如果列设置为varchar(15)..它会接受任何可以是15个字符串,包括数字,=)感谢您的帮助希望这就是你的意思。 – 2010-08-28 08:11:28

是的,这是更有效使用数字,那就是标准的约定。

SQL和关系数据库是为这种存储构建的。

例如:

select students.studentid, assessments.assesName AS assesType 
from students 
    inner join assessments on (students.assesType = assesments.assesType) 

您应该使用第二种方法。主要优点不在于性能,而在于数据的可维护性。

通过将assesType存储在单独的表格中,并通过ID引用该表格,您确定没有针对不同的assesTypes获得不同的拼写,可以轻松地重命名assesType而无需更新整个数据库。您还可以获得单独维护assesTypes的好处,您不能在将学生分配给assesType时意外创建新的assesType。在GUI中为可用的assesTypes创建列表时,您也可以通过快速的方式询问您有什么样的assesTypes。

有关如何构建数据的更多“规则”,您可以查看database normalization