Hvad med et skema som
CREATE TABLE employee
(
employeeid INT PRIMARY KEY AUTO_INCREMENT,
firstname varchar(255)
);
CREATE INDEX part_of_firstname ON employee (firstname(4));
Det vil lade dig udføre opslag ret hurtigt med din naturlige primærnøgle, samtidig med at du får en kunstig primærnøgle og ikke tvinger til at denormalisere.
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 | |
+----+-------------+----------+-------+---------------------------+---------+---------+-------+------+-------+
Da 0001-delen af den primære nøgle er unik nok til at identificere brugeren, behøver du naturligvis slet ikke forespørge på navnet.
Hvis du insisterer på at forudberegne, burde dette virke
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 ;
Tester det:
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)
Dette er en slags hack, og informationsskema vil ikke være tilgængeligt på nogle DB'er, hvor tilladelserne ikke er under din kontrol.