本文針對同時維護 MySQL 與 SQL Server 的開發者,系統整理兩者在建表、自增欄位、查詢語法、函數、資料型別顯示寬度等方面的核心差異,並附上實測驗證腳本,便於快速切換與避坑。
| SQL Server | MySQL |
|---|---|
DEFAULT(12) | DEFAULT 12(無括號) |
-- SQL Server CREATE TABLE emp ( id INT IDENTITY(1,1) ); -- MySQL:自增欄位必須為索引(主鍵或唯一鍵) CREATE TABLE emp ( id INT PRIMARY KEY AUTO_INCREMENT ) AUTO_INCREMENT = 100;
關鍵差異:
AUTO_INCREMENT = N 設定,非欄位屬性。auto_increment_increment、auto_increment_offset),分全域/會話兩級,無法在表級別指定步長(SQL Server 可用 IDENTITY(1,2))。| 場景 | MyISAM | InnoDB (≤ 5.6) | InnoDB (8.0+) |
|---|---|---|---|
| 插入 10 筆 → 刪除 8,9,10 → 重啟 → 再插入 | 新 ID = 11(最大值寫在檔案) | 新 ID = 8(最大值只在記憶體,重啟丟失) | 新 ID = 11(8.0 持久化自增計數器) |
此為 InnoDB 早期版本已知 Bug (#199),8.0 已修復。
1. SELECT MAX(id) FROM person; -- 特定表,最直觀 2. SELECT LAST_INSERT_ID(); -- 會話級,跨表也可用 3. SELECT @@IDENTITY; -- 會話級,最近一次 INSERT 的自增值 4. SHOW TABLE STATUS LIKE 'person'; -- 查看 Auto_increment 欄位
建議:特定表用 SHOW TABLE STATUS 或 MAX(id);應用層回寫 ID 用 LAST_INSERT_ID()(不受並發影響)。
-- SQL Server EXEC sp_help 'emp'; -- MySQL DESC emp; -- 或 SHOW COLUMNS FROM emp;
-- SQL Server EXEC sp_rename 'emp', 'emp2'; -- MySQL ALTER TABLE emp RENAME emp2;
-- SQL Server ALTER TABLE emp2 ALTER COLUMN id BIGINT; -- MySQL ALTER TABLE emp2 MODIFY id BIGINT;
-- SQL Server EXEC sp_rename 'emp2.id', 'iid', 'COLUMN'; -- MySQL(CHANGE 同時支援改名與改型別) ALTER TABLE emp2 CHANGE id iid BIGINT; -- 改名+改型別 ALTER TABLE emp2 CHANGE id id BIGINT; -- 僅改型別(新舊名相同)
-- 兩者基本語法相同 ALTER TABLE emp2 ADD name VARCHAR(200) NULL; -- MySQL 獨有:指定位置 ALTER TABLE emp2 ADD name VARCHAR(200) NULL FIRST; ALTER TABLE emp2 ADD name VARCHAR(200) NULL AFTER id;
-- SQL Server ALTER TABLE emp2 DROP COLUMN name; -- MySQL(無需 COLUMN 關鍵字) ALTER TABLE emp2 DROP name;
-- SQL Server:統一語法 ALTER TABLE emp2 DROP CONSTRAINT fk_emp_dept; -- MySQL:依約束類型分別指定 ALTER TABLE emp2 DROP FOREIGN KEY fk_emp_dept; ALTER TABLE emp2 DROP PRIMARY KEY;
-- SQL Server:需逐表判斷
IF OBJECT_ID('dbo.emp2') IS NOT NULL DROP TABLE dbo.emp2;
-- MySQL:單條語句多表、自帶存在性檢查
DROP TABLE IF EXISTS emp1, emp2;
MySQL 整數型別可指定顯示寬度(如 INT(11)),僅影響顯示格式(不足補空格),不限制儲存範圍、不影響儲存空間。SQL Server 不支援此語法會報錯。
CREATE TABLE tb_emp ( id BIGINT(1) ); -- 合法,仍佔 8 位元組,最大值仍為 BIGINT 上限
MOD(x,y):支援小數取模TRUNCATE(x,d):直接截斷不四捨五入(ROUND 會四捨五入)HEX()/UNHEX():字串與十六進制互轉CHAR_LENGTH():字元數(多位元組字元算 1)CONCAT_WS(sep, ...):帶分隔符連接,自動跳過 NULLINSERT(str,pos,len,newstr):替換子串(對應 SQL Server STUFF)LPAD/RPAD:左右填充至指定長度TRIM([BOTH|LEADING|TRAILING] remstr FROM str):單指令去除兩側指定字串STRCMP(s1,s2):字串比較回傳 -1/0/1LOCATE/POSITION/INSTR:子串位置(對應 CHARINDEX)ELT(n, ...)/FIELD(str, ...)/FIND_IN_SET/MAKE_SET:集合操作函數族MONTHNAME()/QUARTER()/UTC_DATE()/UTC_TIME():日期時間豐富函數EXTRACT(type FROM date):對應 DATEPARTTIME_TO_SEC()/SEC_TO_TIME():時間↔秒互轉IF(expr, v1, v2)/IFNULL(v1,v2)/CASE:流程控制函數(語法與 SQL Server 不同)PASSWORD()/MD5()/ENCODE()/DECODE():加密函數族FORMAT(x,n):數字格式化含千分位CONV(n, from_base, to_base):進制轉換INET_ATON()/INET_NTOA():IPv4 地址↔整數GET_LOCK()/RELEASE_LOCK():應用層命名鎖BENCHMARK(count, expr):效能基準測試UUID():生成 UUIDCHANGE 改名必須帶型別、DROP 不需 COLUMN、支援 DROP TABLE IF EXISTS a,b。INT(11) 僅顯示用,勿誤以為限制長度。utf8mb4,避免 Emoji 存儲截斷。