MySQL包含了一些可能在其他SQL數據庫找不到的擴充要注意如果你使用他們你的代碼把不與其他SQL服務器兼容在一些情況下你可以編寫包括MySQL擴展的代碼但是仍然是可移植的通過使用/*! */形式的注釋在這種情況下MySQL把進行詞法分析並且執行在注釋內的代碼好像它是任何其它MySQL語句但是其他SQL服務器把忽略擴展例如
SELECT /*! STRAIGHT_JOIN */ col_name FROM tabletable WHERE
如果你在!後增加一個版本數字該語法把僅在MySQL版本是等於或比使用的版本數字新時才執行
CREATE /*! TEMPORARY */ TABLE (a int);
上面的意思是如果你有或更新那麼MySQL把使用TEMPORARY關鍵詞
MySQL擴展被列在下面
字段類型MEDIUMINTSETENUM和不同的BLOB和TEXT類型
字段屬性AUTO_INCREMENTBINARYUNSIGNED和ZEROFILL
缺省地所有的字符串比較是忽略大小寫的由當前的字符集決定了(缺省為ISO Latin)排序順序如果你不喜歡這樣你應該用BINARY屬性或使用BINARY強制符聲明列它導致根據MySQL服務器主機的ASCII順序進行排序
MySQL把每個數據庫映射一個MySQL數據目錄下面的目錄把數據庫表映射到數據庫目錄下的數據庫文件名這有個含意
在區分大小寫文件名的操作系統(象大多數 Unix 系統一樣)上的MySQL中數據庫名字和表名是區分大小寫的如果你有困難記得表名接受一個一致的約定例如總是用小寫名字創建數據庫和表
數據庫表索引列或別名可以以數字開始(但是不能僅由數字組成)
你可以使用標准的系統命令備份重命名移動刪除和拷貝表例如重命名一個表重命名MYDMYI和frm文件為相應的表
在SQL語句中你可以用db_nametbl_name語法訪問不同數據庫中的表一些SQL服務器提供同樣的功能但是稱它們為這User space(用戶空間)MySQL不支持類似在create table ralphmy_tableIN my_tablespace中的表空間
LIKE在數字列上被允許
在一SELECT語句裡面使用INTO OUTFILE和STRAIGHT_JOIN見 SELECT句法
在一個SELECT語句中SQL_SMALL_RESULT選項
EXPLAIN SELECT得到怎麼樣聯結表的描述
在一個CREATE TABLE語句裡面使用索引在字段前綴上的索引和使用INDEX或KEY見 CREATE TABLE 句法
CREATE TABLE使用TEMPORARY或IF NOT EXISTS
使用COUNT(DISTINCT list)這裡list超過一個元素
在一個ALTER TABLE語句裡面使用CHANGE col_nameDROP col_name或DROP INDEX見 ALTER TABLE句法
在一個ALTER TABLE裡面語句使用IGNORE
在一個ALTER TABLE語句中使用多重ADDALTERDROP或CHANGE子句
使用帶關鍵詞IF EXISTS的DROP TABLE
你能用單個DROP TABLE語句拋棄多個表
DELETE語句的LIMIT子句
INSERT和REPLACE語句的DELAYED子句
INSERT REPLACE DELETE和UPDATE語句的LOW_PRIORITY子句
使用LOAD DATA INFILE在多數情況下這句法與Oracle的LOAD DATA INFILE兼容見 LOAD DATA INFILE 句法
OPTIMIZE TABLE語句
SHOW語句見 SHOW句法(得到表列等的信息)
字符串可以被或包圍而不只是
使用\轉義字符
SET OPTION語句見 SET OPTION句法
你不需要命名所有在GROUP BY部分的被選擇的列這為一些很特定的情況給出更好的性能而不是一般的查詢
為了方便來自於SQL環境其他為用戶MySQL對許多函數支持別名例如所有的字符串功能都支持ANSI SQL句法和 ODBC句法
MySQL理解||和&&意味著邏輯的OR和AND就像在C程序語言中在MySQL中||和OR是同義詞&&和AND是同義詞正因為這個好的句法MySQL對字符串並置的不支持ANSI SQL ||操作符相反使用CONCAT()因為CONCAT()接受任何數量的參數很容易把||操作符使用變換到MySQL
CREATE DATABASE或DROP DATABASE見 CREATE DATABASE句法
%操作符是MOD()一個同義詞即N % M等價於MOD(NM)%支持C程序員並與PostgreSQL兼容
= <> <=< >=> << >> <=> AND OR或LIKE操作符可以放在SELECT語句的FROM左邊用於比較列例如
mysql> SELECT col= AND col= FROM tbl_name;
LAST_INSERT_ID()函數見 mysql_insert_id()
擴展的正則表達式操作符REGEXP和NOT REGEXP
CONCAT()或CHAR()有一個參數或超過個參數(在MySQL中這些函數可取任何數量的參數)
BIT_COUNT() CASE ELT() FROM_DAYS() FORMAT() IF() PASSWORD() ENCRYPT() md() ENCODE() DECODE() PERIOD_ADD() PERIOD_DIFF() TO_DAYS()或WEEKDAY()函數
使用TRIM()整修子串ANSI SQL 只支持單個字符的刪除
GROUP BY函數STD() BIT_OR()和BIT_AND()
使用REPLACE而不是DELETE+INSERT見 REPLACE句法
FLUSH flush_option語句
在一個語句用:=設置變量的可能性
SELECT @a:=SUM(total)@b=COUNT(*)@a/@b AS avg FROM test_table;
SELECT @t:=(@t:=)+@t:=@t@t@t;
以ANSI模式運行MySQL
如果你用ansi選項啟動mysqldMySQL的下列行為改變
||是字符串並置而不是OR
可在一個函數名字之間與(有任何數量的空格這也使所有的功能名字成為保留詞
把是一個標識符引號字符(象MySQL `引號字符一樣)而不是一個字符串引號字符
REAL把是FLOAT一個同義詞不是DOUBLE一個同義詞
MySQL相比ANSI SQL的差別
我們嘗試使得MySQL遵照ANSI SQL標准和ODBC SQL標准但是在一些情況下MySQL做一些不同的事情
只是一個注釋如果後面跟一個白空字符`作為一個注釋的開始
對於VARCHAR列當值被存儲時拖後的空格被刪除見E MySQL已知的錯誤和設計缺限
在一些情況下CHAR列偷偷地被改變為VARCHAR列平靜的列指定變化
當你刪除一個表時對表的權限不自動地廢除你必須明確地發出一個REVOKE來廢除對一個表的權限見 GRANT和REVOKE句法
MySQL缺乏的功能
下列功能在當前的MySQL版本是沒有的對於一張優先級表指出何時新擴展可以加入MySQL 你應該咨詢在線MySQL TODO 表這是本手冊最新的TODO表版本見F 我們想要在未來加入到MySQL的事情列表(TODO)
子選擇
在MySQL中下列語句還不能工作
SELECT * FROM table WHERE id IN (SELECT id FROM table);
SELECT * FROM table WHERE id NOT IN (SELECT id FROM table);
然而在很多情況下你可以重寫查詢而不用子選擇
SELECT table* FROM tabletable WHERE tableid=tableid;
SELECT table* FROM table LEFT JOIN table ON tableid=tableid where tableid IS NULL
對於更復雜的子查詢通常你可以創建臨時的表保存子查詢然而在一些情況下這種選擇把行不通最經常遇到的情形是DELETE語句對於它標准SQL不支持聯結(join)(除了在子選擇)對於這種情況有個可用選擇直到子選擇被MySQL支持
第一個選擇是使用一種過程化的程序語言(例如Perl或PHP)來提交一個SELECT查詢獲得要被刪除記錄主鍵並然後使用這些值構造DELETE語句(DELETE FROM WHERE IN (key key ))
第二個選擇是使用交互式SQL自動構造一套DELETE語句使用MySQL擴展CONCAT()(代替標准||操作符)例如
SELECT CONCAT(DELETE FROM tab WHERE pkid = tabpkid ;)
FROM tab tab
WHERE tabl;
你可以把這個查詢放在一個腳本文件並且從它重定向輸入到mysql命令行解釋器把其輸出作為管道返回給解釋器的第個實例
prompt> mysql skipcolumnnames mydb < myscriptsql | mysql mydb
MySQL僅支持INSERT SELECT 和REPLACE SELECT 獨立的子選擇把可能在得到然而在其他環境下你現在可以使用函數IN()
SELECT INTO TABLE
MySQL還不支持Oracle SQL的擴展SELECT INTO TABLE 相反MySQL支持ANSI SQL句法INSERT INTO SELECT 基本上他們是一樣的
另外你可使用SELECT INTO OUTFILE或CREATE TABLE SELECT解決你的問題
事務處理
不支持事務處理MySQL把在短時間內支持原子(atomic)操作它象沒有回卷的事務用原子操作你能執行一組INSERT/SELECT/whatever 命令並且保證沒有其他線程介入在本文中你通常不會需要回卷目前你可通過使用LOCK TABLES和UNLOCK TABLES命令阻止其他線程的干擾見 LOCK TABLES/UNLOCK TABLES句法
存儲過程和觸發器
一個存儲過程是能在服務器中編譯並存儲的一套SQL命令一旦這樣做了顧客不需要一直重新發出全部查詢而可以參考存儲過程因為查詢僅需一次詞法分析並且較少的信息需要在服務器和客戶之間傳送因此這提供了更好的性能你與可以通過擁有在服務器中的函數庫提升概念上的層次
From:http://tw.wingwit.com/Article/program/MySQL/201404/30560.html