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

Mysql在where子句中使用数字比字符串快吗?,sql,mysql,query-optimization,Sql,Mysql,Query Optimization,假设你有4种评估,测试,小测验,小测验和期末考试 我们在数据库中存储记录,就像这样 studentid ----- assesType 1 test 2 quiz 3 quiz 4 quiz 5 miniquiz 6 miniquiz 7 final 8 fi

假设你有4种评估,测试,小测验,小测验和期末考试

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

studentid ----- assesType 1 test 2 quiz 3 quiz 4 quiz 5 miniquiz 6 miniquiz 7 final 8 final 学生ID------资产负债表 1试验 2小测验 3小测验 4小测验 5小测验 6小测验 7决赛 8决赛 为每种类型分配数字是否更快更好让我们说:

测试=1 测验=2 小测验=3 最终=4

用它来做记录

studentid ----- assesType 1 1 2 2 3 2 4 2 5 3 6 3 7 4 8 5 学生ID------资产负债表 1 1 2 2 3 2 4 2 5 3 6 3 7 4 8 5 我真正想问的是,这样做值得吗?优势等?因为这样做时,用服务器端语言编写代码会变得有点困难


谢谢=)

是的,使用数字更有效,这是标准惯例

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

例如:

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

是的,数字比较比字符串比较快。字符串也占用了更多的空间,而且数据重复意味着如果必须将“miniquick”重命名为“microquick”,则必须更新所有行。最后,也可能是最重要的一点,您的数据库将无法拒绝不可接受的字符串:您说过有四种类型的评估,但您的数据库将乐于接受您通过的任何字符串

通常,您希望创建另一个表,可能将其称为
assesTypes
,其中只包含
id
name
字段,并将所有可接受的类型保留在其中。然后在主表中,使
assesType
字段a引用新
assesType
表的
id
属性。例如:

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');
INSERT INTO assessments VALUES (1, 1, 55);
INSERT INTO assessments VALUES (1, 2, 65);
INSERT INTO assessments VALUES (1, 3, 75);
INSERT INTO assessments VALUES (1, 5, 75);
现在,让我们将一些评估数据插入
assessments
表中:

INSERT INTO assesTypes VALUES (1, 'Test');
INSERT INTO assesTypes VALUES (2, 'Quiz');
INSERT INTO assesTypes VALUES (3, 'MiniQuiz');
INSERT INTO assesTypes VALUES (4, 'FinalExam');
INSERT INTO assessments VALUES (1, 1, 55);
INSERT INTO assessments VALUES (1, 2, 65);
INSERT INTO assessments VALUES (1, 3, 75);
INSERT INTO assessments VALUES (1, 5, 75);
那很好。现在,我们可以将
评估
表与
评估类型
表进行内部连接,如下所示:

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)
现在,让我们尝试在
评估
表中插入一个无效的
assessype

INSERT INTO assesTypes VALUES (1, 'Test');
INSERT INTO assesTypes VALUES (2, 'Quiz');
INSERT INTO assesTypes VALUES (3, 'MiniQuiz');
INSERT INTO assesTypes VALUES (4, 'FinalExam');
INSERT INTO assessments VALUES (1, 1, 55);
INSERT INTO assessments VALUES (1, 2, 65);
INSERT INTO assessments VALUES (1, 3, 75);
INSERT INTO assessments VALUES (1, 5, 75);
我们不能。MySQL将报告:

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

外键不需要有一个工作的关系数据库,但它们对于避免关系中断和孤立行(即)是必不可少的。在数据库级别强制执行引用完整性的能力是使C-in得以存在的必要条件。

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

通过将assesType存储在单独的表中并按ID引用该表,您可以确保不同assesType不会有不同的拼写,您可以轻松地重命名assesType,而无需更新整个数据库。您还可以获得单独维护assesType的好处,在将学生分配给assesType时,您不会意外地创建新assesType。在GUI中创建可用Assestype列表时,您还可以通过快速方式询问您拥有哪种Assestype


您可以查看更多有关数据结构的“规则”。

Hmmm谢谢您的回答,您能否详细说明“您的数据库将乐于接受您传递的任何字符串”的含义。为什么这不适用于数字?哦,好的,我明白了。。如果列设置为varchar(15)。。它可以接受任何15个字符的字符串,包括数字,=)谢谢你的帮助,希望这就是你的意思。@Akay:是的,你明白了。其思想是对数据库应该期望的数据进行约束,以使无效数据永远不会出现在数据库中。这是SQL数据库最重要的特性之一。