2011-03-07 101 views
3

我有一個表Employee(id,name,dept_name)。我希望id將字母數字[dddddaaaaa]與前5位數字自動增加id和其餘4個字符將是前4個字符員工姓名。用默認值(表達式)將MYSQL表創建爲列

例如,對於第一個員工姓名= John Todd,Id的自動遞增部分將爲00001.因此,ID將爲00001JOHN

是否可以將默認表達式設置爲列Id = (concat(autoincrement,substring(name,4))

我也在想,如果我可以在插入Employee後創建觸發器,觸發器將更新Employee.Id。但MySql不允許從觸發器觸發的同一個表中更新。

請幫忙。

回答

3

什麼樣

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

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

這會讓您使用自然主鍵相當快速地執行查找,同時爲您提供人爲主鍵並且不會強制非規範化。

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 |  | 
+----+-------------+----------+-------+---------------------------+---------+---------+-------+------+-------+ 

當然,由於主鍵的0001部分是唯一足以識別用戶,所以您根本不需要查詢名稱。

如果您堅持預先計算這應該工作

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 ; 

測試它:

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) 

這是怎樣的一個黑客,和INFORMATION_SCHEMA將無法使用一些數據塊,其中的權限AREN」在你的控制之下。

+0

感謝您的答案。考慮到性能,此架構相當令人印象深刻。但按照我的要求,我需要將該字母數字標識存儲在數據庫中。不同的其他應用程序可以訪問同一個表,我希望將選擇查詢保持爲簡單儘可能。 – Sourabh 2011-03-07 19:28:53

+0

我已經爲您的問題添加了特定的解決方案,但我建議您不要這樣做。 – Novikov 2011-03-08 02:47:51

0

你可以嘗試在你的SELECT語句串聯它,而不是存儲的自動遞增列和ID列,

SELECT CONCAT(id, substring(name,4) FROM tbl_employee 

這樣你就不需要觸發

+0

感謝您的回答。其實我簡化了我的要求。這個id的表達式更復雜。該表有數百萬的數據。因此,在select中添加表達式可能會降低性能。因此,我正在考慮預先生成Id。 – Sourabh 2011-03-07 19:07:15