sql >> Base de Datos >  >> RDS >> Mysql

Creación de tablas MYSQL con valor predeterminado (expresión) en una columna

¿Qué pasa con un esquema como

CREATE TABLE employee
(
employeeid INT PRIMARY KEY AUTO_INCREMENT,
firstname varchar(255)
);

CREATE INDEX part_of_firstname ON employee (firstname(4));

Eso le permitirá realizar búsquedas con bastante rapidez usando su clave principal natural, mientras le brinda una clave principal artificial y no lo obliga a desnormalizar.

EXPLAIN SELECT * FROM EMPLOYEE WHERE EMPLOYEEID = 1 AND FIRSTNAME LIKE 'john%';

+----+-------------+----------+-------+---------------------------+---------+---------+-------+------+-------+
| id | select_type | table    | type  | possible_keys             | key     | key_len | ref   | rows | Extra |
+----+-------------+----------+-------+---------------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | employee | const | PRIMARY,part_of_firstname | PRIMARY | 4       | const |    1 |       |
+----+-------------+----------+-------+---------------------------+---------+---------+-------+------+-------+

Por supuesto, dado que la parte 0001 de la clave principal es lo suficientemente única para identificar al usuario, no necesita consultar el nombre en absoluto.

Si insiste en precalcular esto debería funcionar

CREATE TABLE employee
(
employeeid INT PRIMARY KEY AUTO_INCREMENT,
specialid VARCHAR(255),
firstname VARCHAR(255)
);

CREATE INDEX employee_specialid ON employee (firstname(4));

DELIMITER ;;
CREATE TRIGGER employeeid_trigger BEFORE insert ON employee
FOR EACH ROW
BEGIN
SET new.specialid = CONCAT(LPAD((SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'employee'), 4, '0'), SUBSTRING(new.firstname, 1, 4));
END
;;
DELIMITER ;

Probándolo:

mysql> insert into employee (firstname) values ('johnathan');
Query OK, 1 row affected (0.04 sec)

mysql> insert into employee (firstname) values ('johnathan');
Query OK, 1 row affected (0.02 sec)

mysql> insert into employee (firstname) values ('johnathan');
Query OK, 1 row affected (0.02 sec)

mysql> select * from employee;
+------------+-----------+-----------+
| employeeid | specialid | firstname |
+------------+-----------+-----------+
|          1 | 0001john  | johnathan |
|          2 | 0002john  | johnathan |
|          3 | 0003john  | johnathan |
+------------+-----------+-----------+
3 rows in set (0.00 sec)

Esto es una especie de truco, e information_schema no estará disponible en algunas bases de datos donde los permisos no están bajo su control.