Дилемма производительности запросов MySQL: перечисление против таблиц
В настоящее время у меня есть эта схема:
CREATE TABLE `users` (
`users_id` int(11) NOT NULL AUTO_INCREMENT,
`users_name` varchar(50),
`users_lastname` varchar(50),
`users_dob` date,
`users_type` int(11) NOT NULL default 0,
`users_access` int(11) NOT NULL default 0,
`users_level` int(11) NOT NULL default 0,
/* etc...*/
PRIMARY KEY (`users_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `users_types` (
`types_id` int(11) NOT NULL AUTO_INCREMENT,
`types_name` varchar(50),
PRIMARY KEY (`types_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/* etc..*/
Query:
SELECT
types_name AS user_type,
/* all other fields*/
users.*
FROM users
INNER JOIN users_types ON (users.users_type=types_id);
/* INNER JOIN for all other tables*/
/* Rest of query */
Мое новое решение:
CREATE TABLE `users` (
`users_id` int(11) NOT NULL AUTO_INCREMENT,
`users_name` varchar(50),
`users_lastname` varchar(50),
`users_dob` date,
`users_type` ENUM('type1', 'type2', 'type3'),
`users_access` ENUM('access1', 'access2', 'access3'),
`users_level` ENUM('level1', 'level2', 'level3'),
/* etc...*/
PRIMARY KEY (`users_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Query:
SELECT
*
FROM users
Из того, что я вижу, использование ENUM очень просто и может быть очень быстрым для выполнения.
- Я прав? Было бы быстрее, если MySQL Engine обработает поле типа ENUM вместо LEFT JOINs?
- Использует ENUM хорошую практику?
Спасибо
Ответы
Ответ 1
Лично я считаю, что должен использоваться тип данных int, а ENUM-идентификация этих данных должна выполняться на другом уровне.
Определение таблицы является плохим местом для хранения вашей гаммы значений перечисления. Трудно получить легко и дать вашему приложению возможность изменять определения таблиц - проблема безопасности (возможно).
Вместо этого я бы рекомендовал использовать тип INT, а затем в вашем программном обеспечении, создав модель, которая взаимодействует с базой данных ниже, чтобы создать внешний вид ENUM.
При таком выборе дизайна программное обеспечение для коммутации баз данных тривиально, вам не нужно предоставлять привилегии "ALTER TABLE" в ваше производственное приложение, и продление вашего перечисления легко. Кроме того, тогда вы уменьшаете количество раз, которое программа должна выполнять для перевода из ENUM → integer, - это можно сделать во время компиляции, а не с каждым запросом SQL базы данных.
Ответ 2
1) Да, это было бы быстрее, поскольку тип данных ENUM индексируется в самой таблице (т.е. нет необходимости читать другую таблицу для каждой записи)
2) Да, если вы не хотите использовать эти поля в любой другой таблице. Как только вы захотите использовать заданное поле в нескольких таблицах, вы должны создать отдельную таблицу поиска для этого поля. Кроме того, если вы хотите, чтобы в поле были определяемые пользователем значения (и они не требуют изменения базы данных непосредственно для их изменения), вы должны использовать отдельную таблицу.