Bueno, estuve haciendo unas pruebasL, y al parecer usar foreign keys como texto cuando se trata de un sólo campo es más óptimo, ya que no se hace necesario involucrar más tablas en la consulta.
Dejo un SQL con las pruebas que hice.
(Las pruebas fueron hechas en PostgreSQL y afirma que las relaciones con números para un sólo campo es más costoso que con texto, al menos con pocos registros).
Código MySQL :
BEGIN;
----------------------------------------------
--
-- SIN ID
--
----------------------------------------------
CREATE TABLE USUARIO_TIPO (
NOMBRE VARCHAR(32) NOT NULL PRIMARY KEY
);
INSERT INTO USUARIO_TIPO VALUES ('ADMIN');
INSERT INTO USUARIO_TIPO VALUES ('SUPERVISOR');
INSERT INTO USUARIO_TIPO VALUES ('DIRECTOR');
INSERT INTO USUARIO_TIPO VALUES ('USUARIO');
CREATE TABLE USUARIO (
ID BIGSERIAL NOT NULL PRIMARY KEY,
NOMBRE VARCHAR(16) NOT NULL,
TIPO VARCHAR(32) NOT NULL REFERENCES USUARIO_TIPO(NOMBRE) ON DELETE CASCADE
);
INSERT INTO USUARIO (NOMBRE, TIPO) VALUES('admin','ADMIN');
INSERT INTO USUARIO (NOMBRE, TIPO) VALUES('w00p','ADMIN');
INSERT INTO USUARIO (NOMBRE, TIPO) VALUES('juan','SUPERVISOR');
INSERT INTO USUARIO (NOMBRE, TIPO) VALUES('jose','DIRECTOR');
INSERT INTO USUARIO (NOMBRE, TIPO) VALUES('francisco','USUARIO');
INSERT INTO USUARIO (NOMBRE, TIPO) VALUES('felipe','USUARIO');
----------------------------------------------
--
-- CON ID
--
----------------------------------------------
CREATE TABLE _USUARIO_TIPO (
ID BIGSERIAL NOT NULL PRIMARY KEY,
NOMBRE VARCHAR(32) NOT NULL
);
INSERT INTO _USUARIO_TIPO (NOMBRE) VALUES ('ADMIN');
INSERT INTO _USUARIO_TIPO (NOMBRE) VALUES ('SUPERVISOR');
INSERT INTO _USUARIO_TIPO (NOMBRE) VALUES ('DIRECTOR');
INSERT INTO _USUARIO_TIPO (NOMBRE) VALUES ('USUARIO');
CREATE TABLE _USUARIO (
ID BIGSERIAL NOT NULL PRIMARY KEY,
NOMBRE VARCHAR(16) NOT NULL,
TIPO BIGINT NOT NULL REFERENCES _USUARIO_TIPO(ID) ON DELETE CASCADE
);
INSERT INTO _USUARIO (NOMBRE, TIPO) VALUES('admin',1);
INSERT INTO _USUARIO (NOMBRE, TIPO) VALUES('w00p',1);
INSERT INTO _USUARIO (NOMBRE, TIPO) VALUES('juan',2);
INSERT INTO _USUARIO (NOMBRE, TIPO) VALUES('jose',3);
INSERT INTO _USUARIO (NOMBRE, TIPO) VALUES('francisco',4);
INSERT INTO _USUARIO (NOMBRE, TIPO) VALUES('felipe',4);
COMMIT;
---------------------------------------------------
--
-- Obtener todos los usuario y tipo
--
---------------------------------------------------
-- Mayor costo
SELECT * FROM USUARIO,USUARIO_TIPO WHERE USUARIO.TIPO=USUARIO_TIPO.NOMBRE;
EXPLAIN(SELECT * FROM USUARIO,USUARIO_TIPO WHERE USUARIO.TIPO=USUARIO_TIPO.NOMBRE);
-- Menor costo
SELECT * FROM _USUARIO,_USUARIO_TIPO WHERE _USUARIO.TIPO=_USUARIO_TIPO.ID;
EXPLAIN(SELECT * FROM _USUARIO,_USUARIO_TIPO WHERE _USUARIO.TIPO=_USUARIO_TIPO.ID);
-- Menor costo
SELECT * FROM USUARIO
EXPLAIN(SELECT * FROM USUARIO);
---------------------------------------------------
--
-- Obtener usuario y tipo, codicionando el tipo
--
---------------------------------------------------
-- Mayor costo
SELECT * FROM _USUARIO,_USUARIO_TIPO WHERE _USUARIO.TIPO=_USUARIO_TIPO.ID AND _USUARIO_TIPO.NOMBRE='ADMIN';
EXPLAIN(SELECT * FROM _USUARIO,_USUARIO_TIPO WHERE _USUARIO.TIPO=_USUARIO_TIPO.ID AND _USUARIO_TIPO.NOMBRE='ADMIN');
-- Menos costo
SELECT * FROM USUARIO WHERE TIPO = 'ADMIN'
EXPLAIN(SELECT * FROM USUARIO WHERE TIPO = 'ADMIN');