Mysql быстрее использовать числа в предложении where по сравнению со строками? - PullRequest
3 голосов
/ 28 августа 2010

Допустим, у вас есть 4 типа оценок: Тест, Викторина, MiniQuiz и FinalExam

и мы храним записи в базе данных примерно так

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

быстрее и лучший способ присвоения номеров каждому типу, скажем:

тест = 1 викторина = 2 miniquiz = 3 окончательный = 4

И используйте это вместо того, чтобы вести учет.

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

Что я действительно хочу спросить, стоит ли это делать? преимущества и т. д.? поскольку при этом становится немного сложнее писать код на выбранном серверном языке.

Спасибо =)

Ответы [ 3 ]

2 голосов
/ 28 августа 2010

Да, числовые сравнения выполняются быстрее, чем сравнения строк. Строки также занимают намного больше места, а дублирование данных означает, что если вам придется переименовать «miniquiz» в «microquiz», вам придется обновить все строки. Наконец, и, возможно, самое главное, ваша база данных не сможет отклонить недопустимые строки: вы сказали, что существует четыре типа оценок, но ваша база данных с радостью примет любую передаваемую вами строку.

Как правило, вы хотите создать другую таблицу, возможно, назвав ее assesTypes, с полями id и name, и сохранить в ней все приемлемые типы. Затем в основной таблице укажите в поле assesType внешний ключ , который ссылается на атрибут id новой таблицы assesTypes. Пример:

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 JOIN таблица assessments с таблицей 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)

Теперь давайте попробуем вставить неверный assesType в таблицу assessments:

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

Мы не можем. MySQL сообщит:

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

Внешние ключи не обязательно должны иметь рабочую реляционную базу данных, но они необходимы, чтобы избежать разрыва отношений и потерянных строк (т.е. ссылочная целостность ). Способность обеспечить ссылочную целостность на уровне базы данных требуется для C в ACID , чтобы стоять.

2 голосов
/ 28 августа 2010

Да, гораздо эффективнее использовать числа, и это стандартное соглашение.

SQL и реляционные базы данных созданы для этого типа хранилища.

Например:

select students.studentid, assessments.assesName AS assesType
from students
  inner join assessments on (students.assesType = assesments.assesType)
0 голосов
/ 28 августа 2010

Вы должны использовать второй подход.Основное преимущество, однако, заключается не в производительности, а в возможности обслуживания ваших данных.

Храня assesType в отдельной таблице и ссылаясь на эту таблицу по идентификатору, вы уверены, что не получите разное написание для разных assesTypes, вы можете легко переименовать assesType без необходимости обновления всей вашей базы данных.Вы также получаете выгоду от отдельного обслуживания assesTypes, вы не можете случайно создать новый assesType при назначении ученика assesType.Вы также получаете возможность быстро спросить, какие типы assesTypes у вас есть при создании списка в GUI для доступных assesTypes.

Вы можете посмотреть нормализация базы данных длябольше "правил" о том, как структурировать ваши данные.

...