1、MySQL 數據類型
MySQL中定義數據字段的類型對你數據庫的優化是非常重要的。
MySQL支持多種類型,大致可以分爲三類:數值、日期/時間和字符串(字符)類型。
1.1、數值類型
MySQL支持所有標準SQL數值數據類型。
這些類型包括嚴格數值數據類型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似數值數據類型(FLOAT、REAL和DOUBLE PRECISION)。
關鍵字INT是INTEGER的同義詞,關鍵字DEC是DECIMAL的同義詞。
BIT數據類型保存位字段值,並且支持MyISAM、MEMORY、InnoDB和BDB表。
作爲SQL標準的擴展,MySQL也支持整數類型TINYINT、MEDIUMINT和BIGINT。下面的表顯示了需要的每個整數類型的存儲和範圍。
類型 | 大小 | 範圍(有符號) | 範圍(無符號) | 用途 |
---|---|---|---|---|
TINYINT | 1 字節 | (-128,127) | (0,255) | 小整數值 |
SMALLINT | 2 字節 | (-32 768,32 767) | (0,65 535) | 大整數值 |
MEDIUMINT | 3 字節 | (-8 388 608,8 388 607) | (0,16 777 215) | 大整數值 |
INT或INTEGER | 4 字節 | (-2 147 483 648,2 147 483 647) | (0,4 294 967 295) | 大整數值 |
BIGINT | 8 字節 | (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) | (0,18 446 744 073 709 551 615) | 極大整數值 |
FLOAT | 4 字節 | (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) | 0,(1.175 494 351 E-38,3.402 823 466 E+38) | 單精度浮點數值 |
DOUBLE | 8 字節 | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 雙精度浮點數值 |
DECIMAL | 對DECIMAL(M,D) ,如果M>D,爲M+2否則爲D+2 | 依賴於M和D的值 | 依賴於M和D的值 | 小數值 |
1.2、日期和時間類型
表示時間值的日期和時間類型爲DATETIME、DATE、TIMESTAMP、TIME和YEAR。
每個時間類型有一個有效值範圍和一個"零"值,當指定不合法的MySQL不能表示的值時使用"零"值。
TIMESTAMP類型有專有的自動更新特性,將在後面描述。
類型 | 大小(字節) | 範圍 | 格式 | 用途 |
---|---|---|---|---|
DATE | 3 | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | ‘-838:59:59’/‘838:59:59’ | HH:MM:SS | 時間值或持續時間 |
YEAR | 1 | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和時間值 |
TIMESTAMP | 4 | 1970-01-01 00:00:00/2038結束時間是第 2147483647 秒,北京時間 2038-1-19 11:14:07,格林尼治時間 2038年1月19日 凌晨 03:14:07 | YYYYMMDD HHMMSS | 混合日期和時間值,時間戳 |
1.3、字符串類型
字符串類型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。該節描述了這些類型如何工作以及如何在查詢中使用這些類型。
類型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字節 | 定長字符串 |
VARCHAR | 0-65535 字節 | 變長字符串 |
TINYBLOB | 0-255字節 | 不超過 255 個字符的二進制字符串 |
TINYTEXT | 0-255字節 | 短文本字符串 |
BLOB | 0-65 535字節 | 二進制形式的長文本數據 |
TEXT | 0-65 535字節 | 長文本數據 |
MEDIUMBLOB | 0-16 777 215字節 | 二進制形式的中等長度文本數據 |
MEDIUMTEXT | 0-16 777 215字節 | 中等長度文本數據 |
LONGBLOB | 0-4 294 967 295字節 | 二進制形式的極大文本數據 |
LONGTEXT | 0-4 294 967 295字節 | 極大文本數據 |
CHAR 和 VARCHAR 類型類似,但它們保存和檢索的方式不同。它們的最大長度和是否尾部空格被保留等方面也不同。在存儲或檢索過程中不進行大小寫轉換。
BINARY 和 VARBINARY 類似於 CHAR 和 VARCHAR,不同的是它們包含二進制字符串而不要非二進制字符串。也就是說,它們包含字節字符串而不是字符字符串。這說明它們沒有字符集,並且排序和比較基於列值字節的數值值。
BLOB 是一個二進制大對象,可以容納可變數量的數據。有 4 種 BLOB 類型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它們區別在於可容納存儲範圍不同。
有 4 種 TEXT 類型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。對應的這 4 種 BLOB 類型,可存儲的最大長度不同,可根據實際情況選擇。
MySQL 5.0 以上的版本:
1、一個漢字佔多少長度與編碼有關:
UTF-8:一個漢字=3個字節
GBK:一個漢字=2個字節
2、varchar(n) 表示 n 個字符,無論漢字和英文,Mysql 都能存入 n 個字符,僅是實際字節長度有所區別
3、MySQL 檢查長度,可用 SQL 語言來查看:
select LENGTH(fieldname) from tablename
1、整型
MySQL數據類型 | 含義(有符號) |
---|---|
tinyint(m) | 1個字節 範圍(-128~127) |
smallint(m) | 2個字節 範圍(-32768~32767) |
mediumint(m) | 3個字節 範圍(-8388608~8388607) |
int(m) | 4個字節 範圍(-2147483648~2147483647) |
bigint(m) | 8個字節 範圍(±9.22*10的18次方) |
取值範圍如果加了 unsigned,則最大值翻倍,如 tinyint unsigned 的取值範圍爲(0~256)。
int(m) 裏的 m 是表示 SELECT 查詢結果集中的顯示寬度,並不影響實際的取值範圍,沒有影響到顯示的寬度,不知道這個 m 有什麼用。
2、浮點型(float 和 double)
MySQL數據類型 | 含義 |
---|---|
float(m,d) | 單精度浮點型 8位精度(4字節) m總個數,d小數位 |
double(m,d) | 雙精度浮點型 16位精度(8字節) m總個數,d小數位 |
設一個字段定義爲 float(5,3),如果插入一個數 123.45678,實際數據庫裏存的是 123.457,但總個數還以實際爲準,即 6 位。
3、定點數
浮點型在數據庫中存放的是近似值,而定點類型在數據庫中存放的是精確值。
decimal(m,d) 參數 m<65 是總個數,d<30 且 d<m 是小數位。
4、字符串(char,varchar,_text)
MySQL數據類型 | 含義 |
---|---|
char(n) | 固定長度,最多255個字符 |
varchar(n) | 固定長度,最多65535個字符 |
tinytext | 可變長度,最多255個字符 |
text | 可變長度,最多65535個字符 |
mediumtext | 可變長度,最多2的24次方-1個字符 |
longtext | 可變長度,最多2的32次方-1個字符 |
char 和 varchar:
- ** 1.char(n) 若存入字符數小於n,則以空格補於其後,查詢之時再將空格去掉。所以 char 類型存儲的字符串末尾不能有空格,varchar 不限於此。
- ** 2.char(n) 固定長度,char(4) 不管是存入幾個字符,都將佔用 4 個字節,varchar 是存入的實際字符數 +1 個字節(n<=255)或2個字節(n>255),所以 varchar(4),存入 3 個字符將佔用 4 個字節。
- ** 3.char 類型的字符串檢索速度要比 varchar 類型的快。
varchar 和 text:
- ** 1.varchar 可指定 n,text 不能指定,內部存儲 varchar 是存入的實際字符數 +1 個字節(n<=255)或 2 個字節(n>255),text 是實際字符數 +2 個字節。
- ** 2.text 類型不能有默認值。
- ** 3.varchar 可直接創建索引,text 創建索引要指定前多少個字符。varchar 查詢速度快於 text, 在都創建索引的情況下,text 的索引似乎不起作用。
5.二進制數據(_Blob)
- ** 1._BLOB和_text存儲方式不同,_TEXT以文本方式存儲,英文存儲區分大小寫,而_Blob是以二進制方式存儲,不分大小寫。
- ** 2._BLOB存儲的數據只能整體讀出。
- ** 3._TEXT可以指定字符集,_BLOB不用指定字符集。
6.日期時間類型
MySQL數據類型 | 含義 |
---|---|
date | 日期 ‘2008-12-2’ |
time | 時間 ‘12:25:36’ |
datetime | 日期時間 ‘2008-12-2 22:06:44’ |
timestamp | 自動存儲記錄修改時間 |
若定義一個字段爲timestamp,這個字段裏的時間數據會隨其他字段修改的時候自動刷新,所以這個數據類型的字段可以存放這條記錄最後被修改的時間。
數據類型的屬性
MySQL關鍵字 | 含義 |
---|---|
NULL | 數據列可包含NULL值 |
NOT NULL | 數據列不允許包含NULL值 |
DEFAULT | 默認值 |
PRIMARY KEY | 主鍵 |
AUTO_INCREMENT | 自動遞增,適用於整數類型 |
UNSIGNED | 無符號 |
CHARACTER SET name | 指定一個字符集 |
2、MySQL GROUP BY 語句
GROUP BY 語句根據一個或多個列對結果集進行分組。
在分組的列上我們可以使用 COUNT, SUM, AVG,等函數。
語法結構:
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
準備數據:
CREATE TABLE `employee_tbl` (
`id` int(11) NOT NULL,
`name` char(10) NOT NULL DEFAULT '',
`date` datetime NOT NULL,
`singin` tinyint(4) NOT NULL DEFAULT '0' COMMENT '登錄次數',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
INSERT INTO `employee_tbl` VALUES ('1', '小明', '2016-04-22 15:25:33', '1'), ('2', '小王', '2016-04-20 15:25:47', '3'), ('3', '小麗', '2016-04-19 15:26:02', '2'), ('4', '小王', '2016-04-07 15:26:14', '4'), ('5', '小明', '2016-04-11 15:26:40', '4'), ('6', '小明', '2016-04-04 15:26:54', '2');
mysql> SELECT name, COUNT(*) FROM employee_tbl GROUP BY name;
+--------+----------+
| name | COUNT(*) |
+--------+----------+
| 小麗 | 1 |
| 小明 | 3 |
| 小王 | 2 |
+--------+----------+
mysql> select * from employee_tbl;
+----+------+---------------------+--------+
| id | name | date | singin |
+----+------+---------------------+--------+
| 1 | ?? | 2016-04-22 15:25:33 | 1 |
| 2 | ?? | 2016-04-20 15:25:47 | 3 |
| 3 | ?? | 2016-04-19 15:26:02 | 2 |
| 4 | ?? | 2016-04-07 15:26:14 | 4 |
| 5 | ?? | 2016-04-11 15:26:40 | 4 |
| 6 | ?? | 2016-04-04 15:26:54 | 2 |
+----+------+---------------------+--------+
mysql> select * from employee_tbl group by singin;
+----+------+---------------------+--------+
| id | name | date | singin |
+----+------+---------------------+--------+
| 1 | ?? | 2016-04-22 15:25:33 | 1 |
| 3 | ?? | 2016-04-19 15:26:02 | 2 |
| 2 | ?? | 2016-04-20 15:25:47 | 3 |
| 4 | ?? | 2016-04-07 15:26:14 | 4 |
+----+------+---------------------+--------+
注意:
1、group by 可以實現一個最簡單的去重查詢,假設想看下有哪些員工,除了用 distinct,還可以用:
SELECT name FROM employee_tbl GROUP BY name;
返回的結果集就是所有員工的名字。
2、分組後的條件使用 HAVING 來限定,WHERE 是對原始數據進行條件限制。幾個關鍵字的使用順序爲 where 、group by 、having、order by ,例如:
SELECT name ,sum(*) FROM employee_tbl WHERE id<>1 GROUP BY name HAVING sum(*)>5 ORDER BY sum(*) DESC;
3、MySQL LIKE 子句
我們知道在 MySQL 中使用 SQL SELECT 命令來讀取數據, 同時我們可以在 SELECT 語句中使用 WHERE 子句來獲取指定的記錄。
WHERE 子句中可以使用等號 = 來設定獲取數據的條件,如 “company = 'itcast”。
但是有時候我們需要獲取 company 字段含有 “it” 字符的所有記錄,這時我們就需要在 WHERE 子句中使用 SQL LIKE 子句。
SQL LIKE 子句中使用百分號 %字符來表示任意字符,類似於UNIX或正則表達式中的星號 *。
如果沒有使用百分號 %, LIKE 子句與等號 = 的效果是一樣的。
語法:
以下是 SQL SELECT 語句使用 LIKE 子句從數據表中讀取數據的通用語法:
SELECT field1, field2,...fieldN
FROM table_name
WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
- 你可以在 WHERE 子句中指定任何條件。
- 你可以在 WHERE 子句中使用LIKE子句。
- 你可以使用LIKE子句代替等號 =。
- LIKE 通常與 % 一同使用,類似於一個元字符的搜索。
- 你可以使用 AND 或者 OR 指定一個或多個條件。
- 你可以在 DELETE 或 UPDATE 命令中使用 WHERE…LIKE 子句來指定條件。
mysql> select * from pet where species like '%d%';
+----------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Fang | Benny | dog | m | 1990-08-27 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+--------+---------+------+------------+------------+
4、MySQL NULL 值處理
我們已經知道 MySQL 使用 SQL SELECT 命令及 WHERE 子句來讀取數據表中的數據,但是當提供的查詢條件字段爲 NULL 時,該命令可能就無法正常工作。
爲了處理這種情況,MySQL提供了三大運算符:
- IS NULL: 當列的值是 NULL,此運算符返回 true。
- IS NOT NULL: 當列的值不爲 NULL, 運算符返回 true。
- <=>: 比較操作符(不同於=運算符),當比較的的兩個值爲 NULL 時返回 true。
關於 NULL 的條件比較運算是比較特殊的。你不能使用 = NULL 或 != NULL 在列中查找 NULL 值 。
在 MySQL 中,NULL 值與任何其它值的比較(即使是 NULL)永遠返回 false,即 NULL = NULL 返回false 。
MySQL 中處理 NULL 使用 IS NULL 和 IS NOT NULL 運算符。
5、MySQL 元數據
你可能想知道MySQL以下三種信息:
- 查詢結果信息: SELECT, UPDATE 或 DELETE語句影響的記錄數。
- 數據庫和數據表的信息: 包含了數據庫及數據表的結構信息。
- MySQL服務器信息: 包含了數據庫服務器的當前狀態,版本號等。
在MySQL的命令提示符中,我們可以很容易的獲取以上服務器信息。
獲取服務器元數據
以下命令語句可以在 MySQL 的命令提示符使用,也可以在腳本中 使用,如PHP腳本。
命令 | 描述 |
---|---|
SELECT VERSION( ) | 服務器版本信息 |
SELECT DATABASE( ) | 當前數據庫名 (或者返回空) |
SELECT USER( ) | 當前用戶名 |
SHOW STATUS | 服務器狀態 |
SHOW VARIABLES | 服務器配置變量 |
6、MySQL ALTER命令
當我們需要修改數據表名或者修改數據表字段時,就需要使用到MySQL ALTER命令。
6.1、刪除、添加或修改表字段
如下命令使用了 ALTER 命令及 DROP 子句來刪除以上創建表的 i 字段:
mysql> ALTER TABLE testalter_tbl DROP i;
如果數據表中只剩餘一個字段則無法使用DROP來刪除字段。
MySQL 中使用 ADD 子句來向數據表中添加列,如下實例在表 testalter_tbl 中添加 i 字段,並定義數據類型:
mysql> ALTER TABLE testalter_tbl ADD i INT;
執行以上命令後,i 字段會自動添加到數據表字段的末尾
6.2、修改字段類型及名稱
如果需要修改字段類型及名稱, 你可以在ALTER命令中使用 MODIFY 或 CHANGE 子句 。
例如,把字段 c 的類型從 CHAR(1) 改爲 CHAR(10),可以執行以下命令:
mysql> ALTER TABLE testalter_tbl MODIFY c CHAR(10);
6.3、修改表名
如果需要修改數據表的名稱,可以在 ALTER TABLE 語句中使用 RENAME 子句來實現。
嘗試以下實例將數據表 testalter_tbl 重命名爲 alter_tbl:
mysql> ALTER TABLE testalter_tbl RENAME TO alter_tbl;
7、MySQL 函數
MySQL 有很多內置的函數,以下列出了這些函數的說明。
7.1、MySQL 字符串函數
函數 | 描述 | 實例 |
---|---|---|
ASCII(s) | 返回字符串 s 的第一個字符的 ASCII 碼。 | 返回 CustomerName 字段第一個字母的 ASCII 碼:SELECT ASCII(CustomerName) AS NumCodeOfFirstCharFROM Customers; |
CHAR_LENGTH(s) | 返回字符串 s 的字符數 | 返回字符串 itcast 的字符數SELECT CHAR_LENGTH("itcast") AS LengthOfString; |
CHARACTER_LENGTH(s) | 返回字符串 s 的字符數 | 返回字符串 itcast 的字符數SELECT CHARACTER_LENGTH("itcast") AS LengthOfString; |
CONCAT(s1,s2…sn) | 字符串 s1,s2 等多個字符串合併爲一個字符串 | 合併多個字符串SELECT CONCAT("SQL ", "itcast ", "Gooogle ", "Facebook") AS ConcatenatedString; |
CONCAT_WS(x, s1,s2…sn) | 同 CONCAT(s1,s2,…) 函數,但是每個字符串直接要加上 x,x 可以是分隔符 | 合併多個字符串,並添加分隔符:SELECT CONCAT_WS("-", "SQL", "Tutorial", "is", "fun!")AS ConcatenatedString; |
FIELD(s,s1,s2…) | 返回第一個字符串 s 在字符串列表(s1,s2…)中的位置 | 返回字符串 c 在列表值中的位置:SELECT FIELD("c", "a", "b", "c", "d", "e"); |
FIND_IN_SET(s1,s2) | 返回在字符串s2中與s1匹配的字符串的位置 | 返回字符串 c 在指定字符串中的位置:SELECT FIND_IN_SET("c", "a,b,c,d,e"); |
FORMAT(x,n) | 函數可以將數字 x 進行格式化 “#,###.##”, 將 x 保留到小數點後 n 位,最後一位四捨五入。 | 格式化數字 “#,###.##” 形式:SELECT FORMAT(250500.5634, 2); -- 輸出 250,500.56 |
INSERT(s1,x,len,s2) | 字符串 s2 替換 s1 的 x 位置開始長度爲 len 的字符串 | 從字符串第一個位置開始的 6 個字符替換爲 itcast:SELECT INSERT("google.com", 1, 6, "runnob"); -- 輸出:itcast.com |
LOCATE(s1,s) | 從字符串 s 中獲取 s1 的開始位置 | 獲取 b 在字符串 abc 中的位置:SELECT INSTR('abc','b') -- 2 |
LCASE(s) | 將字符串 s 的所有字母變成小寫字母 | 字符串 itcast 轉換爲小寫:SELECT LOWER('itcast') -- itcast |
LEFT(s,n) | 返回字符串 s 的前 n 個字符 | 返回字符串 itcast 中的前兩個字符:SELECT LEFT('itcast',2) -- it |
LEFT(s,n) | 返回字符串 s 的前 n 個字符 | 返回字符串 abcde 的前兩個字符:SELECT LEFT('abcde',2) -- ab |
LOCATE(s1,s) | 從字符串 s 中獲取 s1 的開始位置 | 返回字符串 abc 中 b 的位置:SELECT LOCATE('b', 'abc') -- 2 |
LOWER(s) | 將字符串 s 的所有字母變成小寫字母 | 字符串 itcast 轉換爲小寫:SELECT LOWER('itcast') -- itcast |
LPAD(s1,len,s2) | 在字符串 s1 的開始處填充字符串 s2,使字符串長度達到 len | 將字符串 xx 填充到 abc 字符串的開始處:SELECT LPAD('abc',5,'xx') -- xxabc |
LTRIM(s) | 去掉字符串 s 開始處的空格 | 去掉字符串 itcast開始處的空格:SELECT LTRIM(" itcast") AS LeftTrimmedString;-- itcast |
MID(s,n,len) | 從字符串 s 的 start 位置截取長度爲 length 的子字符串,同 SUBSTRING(s,n,len) | 從字符串 itcast 中的第 2 個位置截取 3個 字符:SELECT MID("itcast", 2, 3) AS ExtractString; -- UNO |
POSITION(s1 IN s) | 從字符串 s 中獲取 s1 的開始位置 | 返回字符串 abc 中 b 的位置:SELECT POSITION('b' in 'abc') -- 2 |
REPEAT(s,n) | 將字符串 s 重複 n 次 | 將字符串 itcast 重複三次:SELECT REPEAT('itcast',3) -- itcastitcastitcast |
REPLACE(s,s1,s2) | 將字符串 s2 替代字符串 s 中的字符串 s1 | 將字符串 abc 中的字符 a 替換爲字符 x:SELECT REPLACE('abc','a','x') --xbc |
REVERSE(s) | 將字符串s的順序反過來 | 將字符串 abc 的順序反過來:SELECT REVERSE('abc') -- cba |
RIGHT(s,n) | 返回字符串 s 的後 n 個字符 | 返回字符串 itcast 的後兩個字符:SELECT RIGHT('itcast',2) -- ob |
RPAD(s1,len,s2) | 在字符串 s1 的結尾處添加字符串 s1,使字符串的長度達到 len | 將字符串 xx 填充到 abc 字符串的結尾處:SELECT RPAD('abc',5,'xx') -- abcxx |
RTRIM(s) | 去掉字符串 s 結尾處的空格 | 去掉字符串 itcast 的末尾空格:SELECT RTRIM("itcast ") AS RightTrimmedString; -- itcast |
SPACE(n) | 返回 n 個空格 | 返回 10 個空格:SELECT SPACE(10); |
STRCMP(s1,s2) | 比較字符串 s1 和 s2,如果 s1 與 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1<s2 返回 -1 | 比較字符串:SELECT STRCMP("itcast", "itcast"); -- 0 |
SUBSTR(s, start, length) | 從字符串 s 的 start 位置截取長度爲 length 的子字符串 | 從字符串 itcast 中的第 2 個位置截取 3個 字符:SELECT SUBSTR("itcast", 2, 3) AS ExtractString; -- UNO |
SUBSTRING(s, start, length) | 從字符串 s 的 start 位置截取長度爲 length 的子字符串 | 從字符串 itcast 中的第 2 個位置截取 3個 字符:SELECT SUBSTRING("itcast", 2, 3) AS ExtractString; -- UNO |
SUBSTRING_INDEX(s, delimiter, number) | 返回從字符串 s 的第 number 個出現的分隔符 delimiter 之後的子串。如果 number 是正數,返回第 number 個字符左邊的字符串。如果 number 是負數,返回第(number 的絕對值(從右邊數))個字符右邊的字符串。 | SELECT SUBSTRING_INDEX('a*b','*',1) -- aSELECT SUBSTRING_INDEX('a*b','*',-1) -- bSELECT SUBSTRING_INDEX(SUBSTRING_INDEX('a*b*c*d*e','*',3),'*',-1) -- c |
TRIM(s) | 去掉字符串 s 開始和結尾處的空格 | 去掉字符串 itcast 的首尾空格:SELECT TRIM(' itcast ') AS TrimmedString; |
UCASE(s) | 將字符串轉換爲大寫 | 將字符串 itcast 轉換爲大寫:SELECT UCASE("itcast"); -- itcast |
UPPER(s) | 將字符串轉換爲大寫 | 將字符串 itcast 轉換爲大寫:SELECT UPPER("itcast"); -- itcast |
7.2、MySQL 數字函數
函數名 | 描述 | 實例 |
---|---|---|
ABS(x) | 返回 x 的絕對值 | 返回 -1 的絕對值:SELECT ABS(-1) -- 返回1 |
ACOS(x) | 求 x 的反餘弦值(參數是弧度) | SELECT ACOS(0.25); |
ASIN(x) | 求反正弦值(參數是弧度) | SELECT ASIN(0.25); |
ATAN(x) | 求反正切值(參數是弧度) | SELECT ATAN(2.5); |
ATAN2(n, m) | 求反正切值(參數是弧度) | SELECT ATAN2(-0.8, 2); |
AVG(expression) | 返回一個表達式的平均值,expression 是一個字段 | 返回 Products 表中Price 字段的平均值:SELECT AVG(Price) AS AveragePrice FROM Products; |
CEIL(x) | 返回大於或等於 x 的最小整數 | SELECT CEIL(1.5) -- 返回2 |
CEILING(x) | 返回大於或等於 x 的最小整數 | SELECT CEIL(1.5) -- 返回2 |
COS(x) | 求餘弦值(參數是弧度) | SELECT COS(2); |
COT(x) | 求餘切值(參數是弧度) | SELECT COT(6); |
COUNT(expression) | 返回查詢的記錄總數,expression 參數是一個字段或者 * 號 | 返回 Products 表中 products 字段總共有多少條記錄:SELECT COUNT(ProductID) AS NumberOfProducts FROM Products; |
DEGREES(x) | 將弧度轉換爲角度 | SELECT DEGREES(3.1415926535898) -- 180 |
n DIV m | 整除,n 爲被除數,m 爲除數 | 計算 10 除於 5:SELECT 10 DIV 5; -- 2 |
EXP(x) | 返回 e 的 x 次方 | 計算 e 的三次方:SELECT EXP(3) -- 20.085536923188 |
FLOOR(x) | 返回小於或等於 x 的最大整數 | 小於或等於 1.5 的整數:SELECT FLOOR(1.5) -- 返回1 |
GREATEST(expr1, expr2, expr3, …) | 返回列表中的最大值 | 返回以下數字列表中的最大值:SELECT GREATEST(3, 12, 34, 8, 25); -- 34 返回以下字符串列表中的最大值:SELECT GREATEST("Google", "itcast", "Apple"); -- itcast |
LEAST(expr1, expr2, expr3, …) | 返回列表中的最小值 | 返回以下數字列表中的最小值:SELECT LEAST(3, 12, 34, 8, 25); -- 3 返回以下字符串列表中的最小值:SELECT LEAST("Google", "itcast", "Apple"); -- Apple |
LN | 返回數字的自然對數 | 返回 2 的自然對數:SELECT LN(2); -- 0.6931471805599453 |
LOG(x) | 返回自然對數(以 e 爲底的對數) | SELECT LOG(20.085536923188) -- 3 |
LOG10(x) | 返回以 10 爲底的對數 | SELECT LOG10(100) -- 2 |
LOG2(x) | 返回以 2 爲底的對數 | 返回以 2 爲底 6 的對數:SELECT LOG2(6); -- 2.584962500721156 |
MAX(expression) | 返回字段 expression 中的最大值 | 返回數據表 Products 中字段 Price 的最大值:SELECT MAX(Price) AS LargestPrice FROM Products; |
MIN(expression) | 返回字段 expression 中的最小值 | 返回數據表 Products 中字段 Price 的最小值:SELECT MIN(Price) AS LargestPrice FROM Products; |
MOD(x,y) | 返回 x 除以 y 以後的餘數 | 5 除於 2 的餘數:SELECT MOD(5,2) -- 1 |
PI() | 返回圓周率(3.141593) | SELECT PI() --3.141593 |
POW(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POW(2,3) -- 8 |
POWER(x,y) | 返回 x 的 y 次方 | 2 的 3 次方:SELECT POWER(2,3) -- 8 |
RADIANS(x) | 將角度轉換爲弧度 | 180 度轉換爲弧度:SELECT RADIANS(180) -- 3.1415926535898 |
RAND() | 返回 0 到 1 的隨機數 | SELECT RAND() --0.93099315644334 |
ROUND(x) | 返回離 x 最近的整數 | SELECT ROUND(1.23456) --1 |
SIGN(x) | 返回 x 的符號,x 是負數、0、正數分別返回 -1、0 和 1 | SELECT SIGN(-10) -- (-1) |
SIN(x) | 求正弦值(參數是弧度) | SELECT SIN(RADIANS(30)) -- 0.5 |
SQRT(x) | 返回x的平方根 | 25 的平方根:SELECT SQRT(25) -- 5 |
SUM(expression) | 返回指定字段的總和 | 計算 OrderDetails 表中字段 Quantity 的總和:SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails; |
TAN(x) | 求正切值(參數是弧度) | SELECT TAN(1.75); -- -5.52037992250933 |
TRUNCATE(x,y) | 返回數值 x 保留到小數點後 y 位的值(與 ROUND 最大的區別是不會進行四捨五入) | SELECT TRUNCATE(1.23456,3) -- 1.234 |
7.3、MySQL 日期函數
函數名 | 描述 | 實例 |
---|---|---|
ADDDATE(d,n) | 計算其實日期 d 加上 n 天的日期 | SELECT ADDDATE("2017-06-15", INTERVAL 10 DAY);->2017-06-25 |
ADDTIME(t,n) | 時間 t 加上 n 秒的時間 | SELECT ADDTIME('2011-11-11 11:11:11', 5)->2011-11-11 11:11:16 (秒) |
CURDATE() | 返回當前日期 | SELECT CURDATE();-> 2018-09-19 |
CURRENT_DATE() | 返回當前日期 | SELECT CURRENT_DATE();-> 2018-09-19 |
CURRENT_TIME | 返回當前時間 | SELECT CURRENT_TIME();-> 19:59:02 |
CURRENT_TIMESTAMP() | 返回當前日期和時間 | SELECT CURRENT_TIMESTAMP()-> 2018-09-19 20:57:43 |
CURTIME() | 返回當前時間 | SELECT CURTIME();-> 19:59:02 |
DATE() | 從日期或日期時間表達式中提取日期值 | SELECT DATE("2017-06-15"); -> 2017-06-15 |
DATEDIFF(d1,d2) | 計算日期 d1->d2 之間相隔的天數 | SELECT DATEDIFF('2001-01-01','2001-02-02')-> -32 |
DATE_ADD(d,INTERVAL expr type) | 計算起始日期 d 加上一個時間段後的日期 | SELECT ADDDATE('2011-11-11 11:11:11',1)-> 2011-11-12 11:11:11 (默認是天)SELECT ADDDATE('2011-11-11 11:11:11', INTERVAL 5 MINUTE)-> 2011-11-11 11:16:11 (TYPE的取值與上面那個列出來的函數類似) |
DATE_FORMAT(d,f) | 按表達式 f的要求顯示日期 d | SELECT DATE_FORMAT('2011-11-11 11:11:11','%Y-%m-%d %r')-> 2011-11-11 11:11:11 AM |
DATE_SUB(date,INTERVAL expr type) | 函數從日期減去指定的時間間隔。 | Orders 表中 OrderDate 字段減去 2 天:SELECT OrderId,DATE_SUB(OrderDate,INTERVAL 2 DAY) AS OrderPayDateFROM Orders |
DAY(d) | 返回日期值 d 的日期部分 | SELECT DAY("2017-06-15"); -> 15 |
DAYNAME(d) | 返回日期 d 是星期幾,如 Monday,Tuesday | SELECT DAYNAME('2011-11-11 11:11:11')->Friday |
DAYOFMONTH(d) | 計算日期 d 是本月的第幾天 | SELECT DAYOFMONTH('2011-11-11 11:11:11')->11 |
DAYOFWEEK(d) | 日期 d 今天是星期幾,1 星期日,2 星期一,以此類推 | SELECT DAYOFWEEK('2011-11-11 11:11:11')->6 |
DAYOFYEAR(d) | 計算日期 d 是本年的第幾天 | SELECT DAYOFYEAR('2011-11-11 11:11:11')->315 |
EXTRACT(type FROM d) | 從日期 d 中獲取指定的值,type 指定返回的值。 | SELECT EXTRACT(MINUTE FROM '2011-11-11 11:11:11') -> 11 |
ROM_DAYS(n) | 計算從 0000 年 1 月 1 日開始 n 天后的日期 | SELECT FROM_DAYS(1111)-> 0003-01-16 |
HOUR(t) | 返回 t 中的小時值 | SELECT HOUR('1:2:3')-> 1 |
LAST_DAY(d) | 返回給給定日期的那一月份的最後一天 | SELECT LAST_DAY("2017-06-20");-> 2017-06-30 |
LOCALTIME() | 返回當前日期和時間 | SELECT LOCALTIME()-> 2018-09-19 20:57:43 |
LOCALTIMESTAMP() | 返回當前日期和時間 | SELECT LOCALTIMESTAMP()-> 2018-09-19 20:57:43 |
MAKEDATE(year, day-of-year) | 基於給定參數年份 year 和所在年中的天數序號 day-of-year 返回一個日期 | SELECT MAKEDATE(2017, 3);-> 2017-01-03 |
MAKETIME(hour, minute, second) | 組合時間,參數分別爲小時、分鐘、秒 | SELECT MAKETIME(11, 35, 4);-> 11:35:04 |
MICROSECOND(date) | 返回日期參數所對應的毫秒數 | SELECT MICROSECOND("2017-06-20 09:34:00.000023");-> 23 |
MINUTE(t) | 返回 t 中的分鐘值 | SELECT MINUTE('1:2:3')-> 2 |
MONTHNAME(d) | 返回日期當中的月份名稱,如 Janyary | SELECT MONTHNAME('2011-11-11 11:11:11')-> November |
MONTH(d) | 返回日期d中的月份值,1 到 12 | SELECT MONTH('2011-11-11 11:11:11')->11 |
NOW() | 返回當前日期和時間 | SELECT NOW()-> 2018-09-19 20:57:43 |
PERIOD_ADD(period, number) | 爲 年-月 組合日期添加一個時段 | SELECT PERIOD_ADD(201703, 5); -> 201708 |
PERIOD_DIFF(period1, period2) | 返回兩個時段之間的月份差值 | SELECT PERIOD_DIFF(201710, 201703);-> 7 |
QUARTER(d) | 返回日期d是第幾季節,返回 1 到 4 | SELECT QUARTER('2011-11-11 11:11:11')-> 4 |
SECOND(t) | 返回 t 中的秒鐘值 | SELECT SECOND('1:2:3')-> 3 |
SEC_TO_TIME(s) | 將以秒爲單位的時間 s 轉換爲時分秒的格式 | SELECT SEC_TO_TIME(4320)-> 01:12:00 |
STR_TO_DATE(string, format_mask) | 將字符串轉變爲日期 | SELECT STR_TO_DATE("August 10 2017", "%M %d %Y");-> 2017-08-10 |
SUBDATE(d,n) | 日期 d 減去 n 天后的日期 | SELECT SUBDATE('2011-11-11 11:11:11', 1)->2011-11-10 11:11:11 (默認是天) |
SUBTIME(t,n) | 時間 t 減去 n 秒的時間 | SELECT SUBTIME('2011-11-11 11:11:11', 5)->2011-11-11 11:11:06 (秒) |
SYSDATE() | 返回當前日期和時間 | SELECT SYSDATE()-> 2018-09-19 20:57:43 |
TIME(expression) | 提取傳入表達式的時間部分 | SELECT TIME("19:30:10");-> 19:30:10 |
TIME_FORMAT(t,f) | 按表達式 f 的要求顯示時間 t | SELECT TIME_FORMAT('11:11:11','%r')11:11:11 AM |
TIME_TO_SEC(t) | 將時間 t 轉換爲秒 | SELECT TIME_TO_SEC('1:12:00')-> 4320 |
TIMEDIFF(time1, time2) | 計算時間差值 | SELECT TIMEDIFF("13:10:11", "13:10:10");-> 00:00:01 |
TIMESTAMP(expression, interval) | 單個參數時,函數返回日期或日期時間表達式;有2個參數時,將參數加和 | SELECT TIMESTAMP("2017-07-23", "13:10:11");-> 2017-07-23 13:10:11 |
TO_DAYS(d) | 計算日期 d 距離 0000 年 1 月 1 日的天數 | SELECT TO_DAYS('0001-01-01 01:01:01')-> 366 |
WEEK(d) | 計算日期 d 是本年的第幾個星期,範圍是 0 到 53 | SELECT WEEK('2011-11-11 11:11:11')-> 45 |
WEEKDAY(d) | 日期 d 是星期幾,0 表示星期一,1 表示星期二 | SELECT WEEKDAY("2017-06-15");-> 3 |
WEEKOFYEAR(d) | 計算日期 d 是本年的第幾個星期,範圍是 0 到 53 | SELECT WEEKOFYEAR('2011-11-11 11:11:11')-> 45 |
YEAR(d) | 返回年份 | SELECT YEAR("2017-06-15");-> 2017 |
YEARWEEK(date, mode) | 返回年份及第幾周(0到53),mode 中 0 表示周天,1表示週一,以此類推 | SELECT YEARWEEK("2017-06-15");-> 201724 |
7.4、MySQL 高級函數
函數名 | 描述 | 實例 |
---|---|---|
BIN(x) | 返回 x 的二進制編碼 | 15 的 2 進制編碼:SELECT BIN(15); -- 1111 |
BINARY(s) | 將字符串 s 轉換爲二進制字符串 | SELECT BINARY "itcast";-> itcast |
CASE expression WHEN condition1 THEN result1 WHEN condition2 THEN result2 ... WHEN conditionN THEN resultN ELSE resultEND |
CASE 表示函數開始,END 表示函數結束。如果 condition1 成立,則返回 result1, 如果 condition2 成立,則返回 result2,當全部不成立則返回 result,而當有一個成立之後,後面的就不執行了。 | SELECT CASE WHEN 1 > 0 THEN '1 > 0' WHEN 2 > 0 THEN '2 > 0' ELSE '3 > 0' END->1 > 0 |
CAST(x AS type) | 轉換數據類型 | 字符串日期轉換爲日期:SELECT CAST("2017-08-29" AS DATE);-> 2017-08-29 |
COALESCE(expr1, expr2, …, expr_n) | 返回參數中的第一個非空表達式(從左向右) | SELECT COALESCE(NULL, NULL, NULL, 'itcast.com', NULL, 'google.com');-> itcast.com |
CONNECTION_ID() | 返回服務器的連接數 | SELECT CONNECTION_ID();-> 4292835 |
CONV(x,f1,f2) | 返回 f1 進制數變成 f2 進制數 | SELECT CONV(15, 10, 2);-> 1111 |
CONVERT(s USING cs) | 函數將字符串 s 的字符集變成 cs | SELECT CHARSET('ABC')->utf-8 SELECT CHARSET(CONVERT('ABC' USING gbk))->gbk |
CURRENT_USER() | 返回當前用戶 | SELECT CURRENT_USER();-> guest@% |
DATABASE() | 返回當前數據庫名 | SELECT DATABASE(); -> itcast |
IF(expr,v1,v2) | 如果表達式 expr 成立,返回結果 v1;否則,返回結果 v2。 | SELECT IF(1 > 0,'正確','錯誤') ->正確 |
IFNULL(v1,v2) | 如果 v1 的值不爲 NULL,則返回 v1,否則返回 v2。 | SELECT IFNULL(null,'Hello Word')->Hello Word |
ISNULL(expression) | 判斷表達式是否爲空 | SELECT ISNULL(NULL);->1 |
LAST_INSERT_ID() | 返回最近生成的 AUTO_INCREMENT 值 | SELECT LAST_INSERT_ID();->6 |
NULLIF(expr1, expr2) | 比較兩個字符串,如果字符串 expr1 與 expr2 相等 返回 NULL,否則返回 expr1 | SELECT NULLIF(25, 25);-> |
SESSION_USER() | 返回當前用戶 | SELECT SESSION_USER();-> guest@% |
SYSTEM_USER() | 返回當前用戶 | SELECT SYSTEM_USER();-> guest@% |
USER() | 返回當前用戶 | SELECT USER();-> guest@% |
VERSION() | 返回數據庫的版本號 | SELECT VERSION()-> 5.6.34 |
8、MySQL 索引
MySQL索引的建立對於MySQL的高效運行是很重要的,索引可以大大提高MySQL的檢索速度。
索引分單列索引和組合索引。單列索引,即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引。組合索引,即一個索引包含多個列。
創建索引時,你需要確保該索引是應用在SQL 查詢語句的條件(一般作爲 WHERE 子句的條件)。
實際上,索引也是一張表,該表保存了主鍵與索引字段,並指向實體表的記錄。
上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和DELETE。因爲更新表時,MySQL不僅要保存數據,還要保存一下索引文件。
建立索引會佔用磁盤空間的索引文件。
9.1、普通索引
9.1.1、創建索引
這是最基本的索引,它沒有任何限制。它有以下幾種創建方式:
CREATE INDEX indexName ON mytable(username(length));
//創建索引
create index id on B(A_ID);
如果是CHAR,VARCHAR類型,length可以小於字段實際長度;如果是BLOB和TEXT類型,必須指定 length。
9.1.2、修改表結構(添加索引)
ALTER table tableName ADD INDEX indexName(columnName)
9.1.3、創建表的時候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length))
);
9.1.4、刪除索引的語法
DROP INDEX [indexName] ON mytable;
9.2、唯一索引
它與前面的普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。它有以下幾種創建方式:
9.2.1、創建索引
CREATE UNIQUE INDEX indexName ON mytable(username(length))
9.2.2、修改表結構
ALTER table mytable ADD UNIQUE [indexName] (username(length))
9.2.3、創建表的時候直接指定
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length))
);
9.3、使用ALTER 命令添加和刪除索引
有四種方式來添加數據表的索引:
- ALTER TABLE tbl_name ADD PRIMARY KEY (column_list): 該語句添加一個主鍵,這意味着索引值必須是唯一的,且不能爲NULL。
- ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 這條語句創建索引的值必須是唯一的(除了NULL外,NULL可能會出現多次)。
- ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出現多次。
- **ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list)?*該語句指定了索引爲 FULLTEXT ,用於全文索引。
以下實例爲在表中添加索引。
mysql> ALTER TABLE testalter_tbl ADD INDEX (c);
你還可以在 ALTER 命令中使用 DROP 子句來刪除索引。嘗試以下實例刪除索引:
mysql> ALTER TABLE testalter_tbl DROP INDEX c;
9.4、使用 ALTER 命令添加和刪除主鍵
主鍵只能作用於一個列上,添加主鍵索引時,你需要確保該主鍵默認不爲空(NOT NULL)。實例如下:
mysql> ALTER TABLE testalter_tbl MODIFY itcast INT NOT NULL;
mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (itcast);
你也可以使用 ALTER 命令刪除主鍵:
mysql> ALTER TABLE testalter_tbl DROP PRIMARY KEY;
刪除主鍵時只需指定PRIMARY KEY,但在刪除索引時,你必須知道索引名。
9.5、顯示索引信息
你可以使用 SHOW INDEX 命令來列出表中的相關的索引信息。可以通過添加 \G 來格式化輸出信息。
嘗試以下實例:
mysql> SHOW INDEX FROM table_name; \G
mysql> show index from B;
±------±-----------±---------±-------------±------------±----------±------------±---------±-------±-----±-----------±--------±--------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
±------±-----------±---------±-------------±------------±----------±------------±---------±-------±-----±-----------±--------±--------------+
| B | 0 | PRIMARY | 1 | A_ID | A | 3 | NULL | NULL | | BTREE | | |
±------±-----------±---------±-------------±------------±----------±------------±---------±-------±-----±-----------±--------±--------------+
10、MySQL 事務
MySQL 事務主要用於處理操作量大,複雜度高的數據。比如說,在人員管理系統中,你刪除一個人員,你即需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數據庫操作語句就構成一個事務!
- 在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。
- 事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要麼全部執行,要麼全部不執行。
- 事務用來管理 insert,update,delete 語句
一般來說,事務是必須滿足4個條件(ACID)::原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)。
- **原子性:**一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,在中間某個環節不會結束。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
- **一致性:**在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續數據庫可以自發性地完成預定的工作。
- **隔離性:**數據庫允許多個併發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致數據的不一致。事務隔離分爲不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和串行化(Serializable)。
- **持久性:**事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。
10.1、事務控制語句:
- BEGIN或START TRANSACTION;顯式地開啓一個事務;
- COMMIT;也可以使用COMMIT WORK,不過二者是等價的。COMMIT會提交事務,並使已對數據庫進行的所有修改成爲永久性的;
- ROLLBACK;有可以使用ROLLBACK WORK,不過二者是等價的。回滾會結束用戶的事務,並撤銷正在進行的所有未提交的修改;
- SAVEPOINT identifier;SAVEPOINT允許在事務中創建一個保存點,一個事務中可以有多個SAVEPOINT;
- RELEASE SAVEPOINT identifier;刪除一個事務的保存點,當沒有指定的保存點時,執行該語句會拋出一個異常;
- ROLLBACK TO identifier;把事務回滾到標記點;
- SET TRANSACTION;用來設置事務的隔離級別。InnoDB存儲引擎提供事務的隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。
10.2、MYSQL 事務處理主要有兩種方法:
1、用 BEGIN, ROLLBACK, COMMIT來實現
- BEGIN 開始一個事務
- ROLLBACK 事務回滾
- COMMIT 事務確認
2、直接用 SET 來改變 MySQL 的自動提交模式:
- SET AUTOCOMMIT=0 禁止自動提交
- SET AUTOCOMMIT=1 開啓自動提交