MySQL 是一種關係型數據庫,說到關係,那麼就離不開表與表之間的關係,而最能體現這種關係的其實就是咱們接下來須要介紹的主角 SQL
,SQL 的全稱是 Structure Query Language
,結構化的查詢語言,它是一種針對表關聯關係所設計的一門語言,也就是說,學好 MySQL,SQL 是基礎和重中之重。SQL 不僅是 MySQL 中特有的一門語言,大多數關係型數據庫都支持這門語言。html
下面咱們就來一塊兒學習一下這門很是重要的語言。mysql
在瞭解 SQL 以前咱們須要知道下面這幾個概念面試
DDL
(Data Definition Language),用來定義數據庫對象:數據庫、表、列等;DML
(Data Manipulation Language),用來對數據庫中表的記錄進行更新。關鍵字: insert、update、delete等DCL
(Data Control Language),用來定義數據庫訪問權限和安全級別,建立用戶等。關鍵字: grant等DQL
(Data Query Language),用來查詢數據庫中表的記錄,關鍵字: select from where等下面就開始咱們的 SQL 語句學習之旅,首先你須要啓動 MySQL 服務,我這裏是 mac 電腦,因此我直接能夠啓動正則表達式
而後咱們使用命令行的方式鏈接數據庫,打開 iterm
,輸入下面sql
MacBook:~ mr.l$ mysql -uroot -p
複製代碼
就能夠鏈接到數據庫了數據庫
在上面命令中,mysql
表明客戶端命令,- u
表示後面須要鏈接的用戶,-p
表示須要輸入此用戶的密碼。在你輸入用戶名和密碼後,若是成功登錄,會顯示一個歡迎界面(如上圖 )和 mysql>
提示符。安全
歡迎界面主要描述了這些東西服務器
;
或者 \g
來表示每一行的結束help
或者 \h
命令來顯示幫助內容,經過 \c
命令來清除命令行 buffer。而後須要作的事情是什麼?咱們最終想要學習 SQL 語句,SQL 語句確定是要查詢數據,經過數據來體現出來表的關聯關係,因此咱們須要數據,那麼數據存在哪裏呢?數據存儲的位置被稱爲 表(table)
,表存儲的位置被稱爲 數據庫(database)
,因此咱們須要先建數據庫後面再建表而後插入數據,再進行查詢。網絡
因此咱們首先要作的就是建立數據庫,建立數據庫能夠直接使用指令函數
CREATE DATABASE dbname;
複製代碼
進行建立,好比咱們建立數據庫 cxuandb
create database cxuandb;
複製代碼
注意最後的 ;
結束語法必定不要丟掉,不然 MySQL 會認爲你的命令沒有輸出完,敲 enter 後會直接換行輸出
建立完成後,會提示 Query OK, 1 row affected,這段語句什麼意思呢? Query OK 表示的就是查詢完成,爲何會顯示這個?由於全部的 DDL 和 DML 操做執行完成後都會提示這個, 也能夠理解爲操做成功。後面跟着的 **1 row affected ** 表示的是影響的行數,()
內顯示的是你執行這條命令所耗費的時間,也就是 0.03 秒。
上圖咱們成功建立了一個 cxuandb 的數據庫,此時咱們還想建立一個數據庫,咱們再執行相同的指令,結果提示
提示咱們不能再建立數據庫了,數據庫已經存在。這時候我就有疑問了,我怎麼知道都有哪些數據庫呢?別我再想建立一個數據庫又告訴我已經存在,這時候可使用 show databases
命令來查看你的 MySQL 已有的數據庫
show databases;
複製代碼
執行完成後的結果以下
由於數據庫我以前已經使用過,這裏就須要解釋一下,除了剛剛新建立成功的 cxuandb 外,informationn_schema
、performannce_schema
和 sys
都是系統自帶的數據庫,是安裝 MySQL 默認建立的數據庫。它們各自表示
其餘全部的數據庫都是做者本身建立的,能夠忽略他們。
在建立完數據庫以後,能夠用以下命令選擇要操做的數據庫
use cxuandb
複製代碼
這樣就成功切換爲了 cxuandb 數據庫,咱們能夠在此數據庫下進行建表、查看基本信息等操做。
好比想要看康康咱們新建的數據庫裏面有沒有其餘表
show tables;
複製代碼
果真,咱們新建的數據庫下面沒有任何表,可是如今,咱們還不進行建表操做,咱們仍是先來認識一下數據庫層面的命令,也就是其餘 DDL 指令
若是一個數據庫咱們不想要了,那麼該怎麼辦呢?直接刪掉數據庫不就行了嗎?刪表語句是
drop database dbname;
複製代碼
好比 cxuandb 咱們不想要他了,能夠經過使用
drop database cxuandb;
複製代碼
進行刪除,這裏咱們就不進行演示了,由於 cxuandb 咱們後面還會使用。
可是這裏注意一點,你刪除數據庫成功後會出現 0 rows affected,這個能夠不用理會,由於在 MySQL 中,drop 語句操做的結果都是 0 rows affected。
下面咱們就能夠對錶進行操做了,咱們剛剛 show tables 發現尚未任何表,因此咱們如今進行建表語句
CREATE TABLE 表名稱
(
列名稱1 數據類型 約束,
列名稱2 數據類型 約束,
列名稱3 數據類型 約束,
....
)
複製代碼
這樣就很清楚了吧,列名稱就是列的名字,緊跟着列名後面就是數據類型,而後是約束,爲何要這麼設計?舉個例子你就清楚了,好比 cxuan 剛被生出來就被打印上了標籤
好比咱們建立一個表,裏面有 5 個字段,姓名(name)、性別(sex)、年齡(age)、什麼時候僱傭(hiredate)、薪資待遇(wage),建表語句以下
create table job(name varchar(20), sex varchar(2), age int(2), hiredate date, wage decimal(10,2));
複製代碼
事實證實這條建表語句仍是沒問題的,建表完成後可使用 DESC tablename
查看錶的基本信息
DESC
命令會查看錶的定義,可是輸出的信息還不夠全面,因此,若是想要查看更全的信息,還要經過查看錶的建立語句的 SQL 來獲得
show create table job \G;
複製代碼
能夠看到,除了看到表定義以外,還看到了表的 engine(存儲引擎)
爲 InnoDB 存儲引擎,\G
使得記錄可以豎着排列,若是不用 \G
的話,效果以下
表的刪除語句有兩種,一種是 drop
語句,SQL 語句以下
drop table job
複製代碼
一種是 truncate
語句,SQL 語句以下
truncate table job
複製代碼
這二者的區別簡單理解就是 drop 語句刪除表以後,能夠經過日誌進行回覆,而 truncate 刪除表以後永遠恢復不了,因此,通常不使用 truncate 進行表的刪除。‘
對於已經建立好的表,尤爲是有大量數據的表,若是須要對錶作結構上的改變,能夠將表刪除而後從新建立表,可是這種效率會產生一些額外的工做,數據會從新加載近來,若是此時有服務正在訪問的話,也會影響服務讀取表中數據,因此此時,咱們須要表的修改語句來對已經建立好的表的定義進行修改。
修改表結構通常使用 alter table
語句,下面是經常使用的命令
ALTER TABLE tb MODIFY [COLUMN] column_definition [FIRST | AFTER col_name];
複製代碼
好比咱們想要將 job 表中的 name 由 varchar(20)
改成 varchar(25)
,可使用以下語句
alter table job modify name varchar(25);
複製代碼
也能夠對錶結構進行修改,好比增長一個字段
alter table job add home varchar(30);
複製代碼
將新添加的表的字段進行刪除
alter table job drop column home;
複製代碼
能夠對錶中字段的名稱進行修改,好比吧 wage 改成 salary
alter table job change wage salary decimal(10,2);
複製代碼
修改字段的排列順序,咱們前面介紹過修改語法涉及到一個順序問題,都有一個可選項 **first | after ** column_name,這個選項能夠用來修改表中字段的位置,默認 ADD 是在添加爲表中最後一個字段,而 CHANGE/MODIFY 不會改變字段位置。好比
alter table job add birthday after hiredate;
複製代碼
能夠對錶名進行修改,例如將 job 表改成 worker
alter table job rename worker;
複製代碼
有的地方把 DML 語句(增刪改)和 DQL 語句(查詢)統稱爲 DML 語句,有的地方分開,咱們目前使用分開稱呼的方式
表建立好以後,咱們就能夠向表裏插入數據了,插入記錄的基本語法以下
INSERT INTO tablename (field1,field2) VALUES(value1,value2);
複製代碼
例如,向中插入如下記錄
insert into job(name,sex,age,hiredate,birthday,salary) values("cxuan","男",24,"2020-04-27","1995-08-22",8000);
複製代碼
也能夠不用指定要插入的字段,直接插入數據便可
insert into job values("cxuan02","男",25,"2020-06-01","1995-04-23",12000);
複製代碼
這裏就有一個問題,若是插入的順序不一致的話會怎麼樣呢?
對於含可空字段、非空可是含有默認值的字段、自增字段能夠不用在 insert 後的字段列表出現,values 後面只須要寫對應字段名稱的 value 便可,沒有寫的字段能夠自動的設置爲 NULL、默認值或者自增的下一個值,這樣能夠縮短要插入 SQL 語句的長度和複雜性。
好比咱們設置一下 hiredate、age 能夠爲 null,來試一下
insert into job(name,sex,birthday,salary) values("cxuan03","男","1992-08-23",15000);
複製代碼
咱們看一下實際插入的數據
咱們能夠看到有一行兩個字段顯示 NULL。在 MySQL 中,insert 語句還有一個很好的特性,就是一次能夠插入多條記錄
INSERT INTO tablename (field1,field2) VALUES
(value1,value2),
(value1,value2),
(value1,value2),
...;
複製代碼
能夠看出,每條記錄之間都用逗號進行分割,這個特性可使得 MySQL 在插入大量記錄時,節省不少的網絡開銷,大大提升插入效率。
對於表中已經存在的數據,能夠經過 update 命令對其進行修改,語法以下
UPDATE tablename SET field1 = value1, field2 = value2 ;
複製代碼
例如,將 job 表中的 cxuan03 中 age 的 NULL 改成 26,SQL 語句以下
update job set age = 26 where name = 'cxuan03';
複製代碼
SQL 語句中出現了一個 where 條件,咱們會在後面說到 where 條件,這裏簡單理解一下它的概念就是根據哪條記錄進行更新,若是不寫 where 的話,會對整個表進行更新
若是記錄再也不須要,可使用 delete 命令進行刪除
DELETE FROM tablename [WHERE CONDITION]
複製代碼
例如,在 job 中刪除名字是 cxuan03 的記錄
delete from job where name = 'cxuan03';
複製代碼
在 MySQL 中,刪除語句也能夠不指定 where 條件,直接使用
delete from job
複製代碼
這種刪除方式至關因而清楚表的操做,表中全部的記錄都會被清除。
下面咱們一塊兒來認識一下 DQL 語句,數據被插入到 MySQL 中,就可使用 SELECT
命令進行查詢,來獲得咱們想要的結果。
SELECT 查詢語句能夠說是最複雜的語句了,這裏咱們只介紹一下基本語法
一種最簡單的方式就是從某個表中查詢出全部的字段和數據,簡單粗暴,直接使用 SELECT *
SELECT * FROM tablename;
複製代碼
例如咱們將 job 表中的全部數據查出來
select * from job;
複製代碼
其中 * 是查詢出全部的數據,固然,你也能夠查詢出指定的數據項
select name,sex,age,hiredate,birthday,salary from job;
複製代碼
上面這條 SQL 語句和 select * from job
表是等價的,可是這種直接查詢指定字段的 SQL 語句效率要高。
上面咱們介紹了基本的 SQL 查詢語句,可是實際的使用場景會會比簡單查詢複雜太多,通常都會使用各類 SQL 的函數和查詢條件等,下面咱們就來一塊兒認識一下。
使用很是普遍的場景之一就是 去重
,去重可使用 distinct
關鍵字來實現
爲了演示效果,咱們先向數據庫中插入批量數據,插入完成後的表結構以下
下面咱們使用 distinct 來對 age 去重來看一下效果
你會發現只有兩個不一樣的值,其餘和 25 重複的值被過濾掉了,因此咱們使用 distinct 來進行去重
咱們以前的全部例子都是查詢所有的記錄,若是咱們只想查詢指定的記錄呢?這裏就會用到 where
條件查詢語句,條件查詢能夠對指定的字段進行查詢,好比咱們想查詢全部年齡爲 24 的記錄,以下
select * from job where age = 24;
複製代碼
where 條件語句後面會跟一個判斷的運算符 =
,除了 =
號比較外,還可使用 >、<、>=、<=、!= 等比較運算符;例如
select * from job where age >= 24;
複製代碼
就會從 job 表中查詢出 age 年齡大於或等於 24 的記錄
除此以外,在 where 條件查詢中還能夠有多個並列的查詢條件,好比咱們能夠查詢年齡大於等於 24,而且薪資大雨 8000 的記錄
select * from job where age >= 24 and salary > 8000;
複製代碼
多個條件之間還可使用 or、and 等邏輯運算符進行多條件聯合查詢,運算符會在之後章節中詳細講解。
咱們會常常有這樣的需求,按照某個字段進行排序,這就用到了數據庫的排序功能,使用關鍵字 order by
來實現,語法以下
SELECT * FROM tablename [WHERE CONDITION] [ORDER BY field1 [DESC|ASC] , field2 [DESC|ASC],……fieldn [DESC|ASC]]
複製代碼
其中 DESC 和 ASC 就是順序排序的關鍵字,DESC 會按照字段進行降序排列,ASC 會按照字段進行升序排列,默認會使用升序排列,也就是說,你不寫 order by
具體的排序的話,默認會使用升序排列。order by 後面能夠跟多個排序字段,而且每一個排序字段能夠有不一樣的排序順序。
爲了演示功能,咱們先把表中的 salary
工資列進行修改,修改完成後的表記錄以下
下面咱們按照工資進行排序,SQL 語句以下
select * from job order by salary desc;
複製代碼
語句執行完成後的結果以下
這是對一個字段進行排序的結果,也能夠對多個字段進行排序,可是須要注意一點
根據 order by 後面聲名的順序進行排序,若是有三個排序字段 A、B、C 的話,若是 A 字段排序字段的值同樣,則會根據第二個字段進行排序,以此類推。
若是隻有一個排序字段,那麼這些字段相同的記錄將會無序排列。
對於排序後的字段,或者不排序的字段,若是隻但願顯示一部分的話,就會使用 LIMIT
關鍵字來實現,好比咱們只想取前三條記錄
select * from job limit 3;
複製代碼
或者咱們對排序後的字段取前三條記錄
select * from job order by salary limit 3;
複製代碼
上面這種 limit 是從表記錄的第 0 條開始取,若是從指定記錄開始取,好比從第二條開始取,取三條記錄,SQL 以下
select * from job order by salary desc limit 2,3;
複製代碼
limit 通常常常和 order by 語法一塊兒實現分頁查詢。
注意:limit 是 MySQL 擴展 SQL92 以後的語法,在其餘數據庫好比 Oracle 上就不通用,我犯過一個白癡的行爲就是在 Oracle 中使用 limit 查詢語句。。。
下面咱們來看一下對記錄進行彙總的操做,這類操做主要有
彙總函數
,好比 sum 求和、count 統計數量、max 最大值、min 最小值等group by
,關鍵字表示對分類聚合的字段進行分組,好比按照部門統計員工的數量,那麼 group by 後面就應該跟上部門with
是可選的語法,它表示對彙總以後的記錄進行再次彙總having
關鍵字表示對分類後的結果再進行條件的過濾。看起來 where 和 having 意思差很少,不過它們用法不同,where 是使用在統計以前,對統計前的記錄進行過濾,having 是用在統計以後,是對聚合以後的結果進行過濾。也就是說 where 永遠用在 having 以前,咱們應該先對篩選的記錄進行過濾,而後再對分組的記錄進行過濾。
能夠對 job 表中員工薪水進行統計,選出總共的薪水、最大薪水、最小薪水
select sum(salary) from job;
複製代碼
select max(salary),min(salary) from job;
複製代碼
好比咱們要統計 job 表中人員的數量
select count(1) from job;
複製代碼
統計完成後的結果以下
咱們能夠按照 job 表中的年齡來進行對應的統計
select age,count(1) from job group by age;
複製代碼
既要統計各年齡段的人數,又要統計總人數
select age,count(1) from job group by age with rollup;
複製代碼
在此基礎上進行分組,統計數量大於 1 的記錄
select age,count(1) from job group by age with rollup having count(1) > 1;
複製代碼
錶鏈接一直是筆者比較痛苦的地方,曾經由於一個錶鏈接掛了面試,如今來認真擼一遍。
錶鏈接通常體如今表之間的關係上。當須要同時顯示多個表中的字段時,就能夠用錶鏈接來實現。
爲了演示錶鏈接的功能,咱們爲 job 表加一個 type
字段表示工做類型,增長一個 job_type 表表示具體的工做種類,以下所示
下面開始咱們的演示
查詢出 job 表中的 type 和 job_type 表中的 type 匹配的姓名和工做類型
select job.name,job_type.name from job,job_type where job.type = job_type.type;
複製代碼
上面這種鏈接使用的是內鏈接,除此以外,還有外鏈接。那麼它們之間的區別是啥呢?
內鏈接:選出兩張表中互相匹配的記錄;
外鏈接:不只選出匹配的記錄,也會選出不匹配的記錄;
外鏈接分爲兩種
爲了演示效果咱們在 job 表和 job_type 表中分別添加記錄,添加完成後的兩表以下
下面咱們進行左外鏈接查詢:查詢出 job 表中的 type 和 job_type 表中的 type 匹配的姓名和工做類型
select job.name,job_type.name from job left join job_type on job.type = job_type.type;
複製代碼
查詢出來的結果以下
能夠看出 cxuan06 也被查詢出來了,而 cxuan06 他沒有具體的工做類型。
使用右外鏈接查詢
select job.name,job_type.name from job right join job_type on job.type = job_type.type;
複製代碼
能夠看出,job 表中並無 waiter 和 manager 的角色,可是也被查詢出來了。
有一些狀況,咱們須要的查詢條件是另外一個 SQL 語句的查詢結果,這種查詢方式就是子查詢,子查詢有一些關鍵字好比 in、not in、=、!=、exists、not exists 等,例如咱們能夠經過子查詢查詢出每一個人的工做類型
select job.* from job where type in (select type from job_type);
複製代碼
若是自查詢數量惟一的話,還能夠用 =
來替換 in
select * from job where type = (select type from job_type);
複製代碼
意思是自查詢不惟一,咱們使用 limit 限制一下返回的記錄數
select * from job where type = (select type from job_type limit 1,1);
複製代碼
在某些狀況下,子查詢能夠轉換爲錶鏈接
咱們還常常會遇到這樣的場景,將兩個表的數據單獨查詢出來以後,將結果合併到一塊兒進行顯示,這個時候就須要 UNION 和 UNION ALL 這兩個關鍵字來實現這樣的功能,UNION 和 UNION ALL 的主要區別是 UNION ALL 是把結果集直接合並在一塊兒,而 UNION 是將 UNION ALL 後的結果進行一次 DISTINCT
去除掉重複數據。
好比
select type from job union all select type from job_type;
複製代碼
它的結果以下
上述結果是查詢 job 表中的 type 字段和 job_type 表中的 type 字段,並把它們進行彙總,能夠看出 UNION ALL 只是把全部的結果都列出來了
使用 UNION 的 SQL 語句以下
select type from job union select type from job_type;
複製代碼
能夠看出 UNION 是對 UNION ALL 使用了 distinct
去重處理。
DCL 語句主要是管理數據庫權限的時候使用,這類操做通常是 DBA 使用的,開發人員不會使用 DCL 語句。
咱們通常使用 MySQL 遇到不會的或者有疑問的東西常常要去查閱網上資料,甚至可能須要去查 MySQL 官發文檔,這樣會耗費大量的時間和精力。
下面教你一下在 MySQL 命令行就能直接查詢資料的語句
可使用 ? contents
來查詢全部可供查詢的分類,以下所示
? contents;
複製代碼
咱們輸入
? Account Management
複製代碼
能夠查詢具體關於權限管理的命令
好比咱們想了解一下數據類型
? Data Types
複製代碼
而後咱們想了解一下 VARCHAR
的基本定義,能夠直接使用
? VARCHAR
複製代碼
能夠看到有關於 VARCHAR 數據類型的詳細信息,而後在最下面還有 MySQL 的官方文檔,方便咱們快速查閱。
在實際應用過程當中,若是要快速查詢某個語法時,可使用關鍵字進行快速查詢,好比咱們使用
? show
複製代碼
可以快速列出一些命令
好比咱們想要查閱 database 的信息,使用
SHOW CREATE DATABASE cxuandb;
複製代碼
MySQL 提供不少種數據類型來對不一樣的常量、變量進行區分,MySQL 中的數據類型主要是 數值類型、日期和時間類型、字符串類型 選擇合適的數據類型進行數據的存儲很是重要,在實際開發過程當中,選擇合適的數據類型也可以提升 SQL 性能,因此有必要認識一下這些數據類型。
MySQL 支持全部標準的 SQL 數據類型,這些數據類型包括嚴格數據類型的嚴格數值類型
,這些數據類型有
近似數值數據類型
並不用嚴格按照指定的數據類型進行存儲,這些有
還有通過擴展以後的數據類型,它們是
其中 INT 是 INTEGER 的縮寫,DEC 是 DECIMAL 的縮寫。
下面是全部數據類型的彙總
在整數類型中,按照取值範圍和存儲方式的不一樣,分爲
![image-20200613091331344](/Users/mr.l/Library/Application Support/typora-user-images/image-20200613091331344.png)
五個數據類型,若是超出類型範圍的操做,會發生錯誤提示,因此選擇合適的數據類型很是重要。
還記得咱們上面的建表語句麼
咱們通常會在 SQL 語句的數據類型後面加上指定長度來表示數據類型許可的範圍,例如
int(7)
複製代碼
表示 int 類型的數據最大長度爲 7,若是填充不滿的話會自動填滿,若是不指定 int 數據類型的長度的話,默認是 int(11)
。
咱們建立一張表來演示一下
create table test1(aId int, bId int(5));
/* 而後咱們查看一下表結構 */
desc test1;
複製代碼
整數類型通常配合 zerofill
來使用,顧名思義,就是用 0 進行填充,也就是數字位數不夠的空間使用 0 進行填充。
分別修改 test1 表中的兩個字段
alter table test1 modify aId int zerofill;
alter table test1 modify bId int(5) zerofill;
複製代碼
而後插入兩條數據,執行查詢操做
如上圖所示,使用zerofill
能夠在數字前面使用 0
來進行填充,那麼若是寬度超過指定長度後會如何顯示?咱們來試驗一下,向 aId 和 bId 分別插入超過字符限制的數字
會發現 aId 已經超出了指定範圍,那麼咱們對 aId 插入一個在其容許範圍以內的數據
會發現,aId 已經插進去了,bId 也插進去了,爲何 bId 顯示的是 int(5) 卻可以插入 7 位長度的數值呢?
全部的整數都有一個可選屬性 UNSIGNED(無符號)
,若是須要在字段裏面保存非負數或者是須要較大上限值時,可使用此選項,它的取值範圍是正常值的下限取 0 ,上限取原值的 2 倍。若是一個列爲 zerofill ,會自動爲該列添加 UNSIGNED 屬性。
除此以外,整數還有一個類型就是 AUTO_INCREMENT
,在須要產生惟一標識符或者順序值時,可利用此屬性,這個屬性只用於整數字符。一個表中最多隻有一個 AUTO_INCREMENT 屬性,通常用於自增主鍵
,並且 NOT NULL
,而且是 PRIMARY KEY
和 UNIQUE
的,主鍵必須保證惟一性並且不爲空。
小數說的是啥?它其實有兩種類型;一種是浮點數
類型,一種是定點數
類型;
浮點數有兩種
定點數只有一種 decimal
。定點數在 MySQL 內部中以字符串的形式存在,比浮點數更爲準確,適合用來表示精度特別高的數據。
浮點數和定點數均可以使用 (M,D)
的方式來表示,M 表示的就是 整數位 + 小數位 的數字,D 表示位於 .
後面的小數。M 也被稱爲精度 ,D 被稱爲標度。
下面經過示例來演示一下
首先創建一個 test2
表
CREATE TABLE test2 (aId float(6,2) default NULL, bId double(6,2) default NULL,cId decimal(6,2) default NULL)
複製代碼
而後向表中插入幾條數據
insert into test2 values(1234.12,1234.12,1234.12);
複製代碼
這個時候顯示的數據就是
而後再向表中插入一些約束以外的數據
insert into test2 values(1234.123,1234.123,1234.123);
複製代碼
發現插入完成後還顯示的是 1234.12
,小數位第三位的值被捨去了。
如今咱們把 test2 表中的精度所有去掉,再次插入
alter table test2 modify aId float;
alter table test2 modify bId double;
alter table test2 modify cId decimal;
複製代碼
先查詢一下,發現 cId 捨去了小數位。
而後再次插入 1.23,SQL 語句以下
insert into test2 values(1.23,1.23,1.23);
複製代碼
結果以下
這個時候能夠驗證
decimal(10,0)
來進行操做,若是數據超過了精度和標題,MySQL 會報錯對於位類型,用於存放字段值,BIT(M)
能夠用來存放多位二進制數,M 的範圍是 1 - 64,若是不寫的話默認爲 1 位。
下面咱們來掩飾一下位類型
新建一個 test3 表,表中只有一個位類型的字段
create table test3(id bit(1));
複製代碼
而後隨意插入一條數據
insert into test3 values(1);
複製代碼
發現沒法查詢出對應結果。
而後咱們使用 hex()
和 bin()
函數進行查詢
發現可以查詢出對應結果。
也就是說當數據插入 test3 時,會首先把數據轉換成爲二進制數,若是位數容許,則將成功插入;若是位數小於實際定義的位數,則插入失敗。若是咱們像表中插入數據 2
insert into test3 values(2);
複製代碼
那麼會報錯
由於 2 的二進制數表示是 10
,而表中定義的是 bit(1)
,因此沒法插入。
那麼咱們將表字段修改一下
而後再進行插入,發現已經可以插入了
MySQL 中的日期與時間類型,主要包括:YEAR、TIME、DATE、DATETIME、TIMESTAMP,每一個版本可能不一樣。下表中列出了這幾種類型的屬性。
下面分別來介紹一下
YEAR 可使用三種方式來表示
下面咱們來演示一下 YEAR 的用法,建立一個 test4 表
create table test4(id year);
複製代碼
而後咱們看一下 test4 的表結構
默認建立的 year 就是 4 位,下面咱們向 test4 中插入數據
insert into test4 values(2020),('2020');
複製代碼
而後進行查詢,發現表示形式是同樣的
使用兩位字符串來表示
delete from test4;
insert into test4 values ('0'),('00'),('11'),('88'),('20'),('21');
複製代碼
使用兩位數字來表示
delete from test4;
insert into test4 values (0),(00),(11),(88),(20),(21);
複製代碼
發現只有前兩項不同。
TIME 所表示的範圍和咱們預想的不同
咱們把 test4 改成 TIME 類型,下面是 TIME 的示例
alter table test4 modify id TIME;
insert into test4 values ('15:11:23'),('20:13'),('2 11:11'),('3 05'),('33');
複製代碼
結果以下
DATE 表示的類型有不少種,下面是 DATE 的幾個示例
create table test5 (id date);
複製代碼
查看一下 test5 表
而後插入部分數據
insert into test5 values ('2020-06-13'),('20200613'),(20200613);
複製代碼
DATE 的表示通常不少種,以下所示 DATE 的全部形式
DATETIME 類型,包含日期和時間部分,可使用引用字符串或者數字,年份能夠是 4 位也能夠是 2 位。
下面是 DATETIME 的示例
create table test6 (id datetime);
insert into test4 values ('2020-06-13 11:11:11'),(20200613111111),('20200613111111'),(20200613080808);
複製代碼
TIMESTAMP 類型和 DATETIME 類型的格式相同,存儲 4 個字節(比DATETIME少),取值範圍比 DATETIME 小。
下面來講一下各個時間類型的使用場景
通常表示年月日
,一般用 DATE
類型;
用來表示時分秒
,一般用 TIME
表示;
年月日時分秒
,一般用 DATETIME
來表示;
若是須要插入的是當前時間,一般使用 TIMESTAMP
來表示,TIMESTAMP 值返回後顯示爲 YYYY-MM-DD HH:MM:SS
格式的字符串,
若是隻表示年份、則應該使用 YEAR,它比 DATE 類型須要更小的空間。
每種日期類型都有一個範圍,若是超出這個範圍,在默認的 SQLMode
下,系統會提示錯誤,並進行零值存儲。
下面來解釋一下 SQLMode
是什麼
MySQL 中有一個環境變量是 sql_mode ,sql_mode 支持了 MySQL 的語法、數據校驗,咱們能夠經過下面這種方式來查看當前數據庫使用的 sql_mode
select @@sql_mode;
複製代碼
一共有下面這幾種模式
來源於 www.cnblogs.com/Zender/p/82…
MySQL 提供了不少種字符串類型,下面是字符串類型的彙總
下面咱們對這些數據類型作一個詳細的介紹
CHAR 和 VARCHAR 類型很類似,致使不少同窗都會忽略他們之間的差異,首先他倆都是用來保存字符串的數據類型,他倆的主要區別在於存儲方式不一樣。CHAR 類型的長度就是你定義多少顯示多少。佔用 M 字節,好比你聲明一個 CHAR(20)
的字符串類型,那麼每一個字符串佔用 20 字節,M 的取值範圍時 0 - 255。VARCHAR
是可變長的字符串,範圍是 0 - 65535,在字符串檢索的時候,CHAR 會去掉尾部的空格,而 VARCHAR 會保留這些空格。下面是演示例子
create table vctest1 (vc varchar(6),ch char(6));
insert into vctest1 values("abc ","abc ");
select length(vc),length(ch) from vctest1;
複製代碼
結果以下
能夠看到 vc 的字符串類型是 varchar ,長度是 5,ch 的字符串類型是 char,長度是 3。能夠得出結論,varchar 會保留最後的空格,char 會去掉最後的空格。
BINARY 和 VARBINARY 與 CHAR 和 VARCHAR 很是相似,不一樣的是它們包含二進制字符串而不包含非二進制字符串。BINARY 與 VARBINARY 的最大長度和 CHAR 與 VARCHAR 是同樣的,只不過他們是定義字節長度,而 CHAR 和 VARCHAR 對應的是字符長度。
BLOB 是一個二進制大對象,能夠容納可變數量的數據。有 4 種 BLOB 類型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。它們區別在於可容納存儲範圍不一樣。
有 4 種 TEXT 類型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。對應的這 4 種 BLOB 類型,可存儲的最大長度不一樣,可根據實際狀況選擇。
ENUM 咱們在 Java 中常常會用到,它表示的是枚舉類型。它的範圍須要在建立表時顯示指定,對 1 - 255 的枚舉須要 1 個字節存儲;對於 255 - 65535 的枚舉須要 2 個字節存儲。ENUM 會忽略大小寫,在存儲時都會轉換爲大寫。
SET 類型和 ENUM 類型有兩處不一樣
SET 對於每 0 - 8 個成員,分別佔用 1 個字節,最大到 64 ,佔用 8 個字節
MySQL 中有多種運算符,下面對 MySQL 運算符進行分類
下面那咱們對各個運算符進行介紹
MySQL 支持的算術運算符包括加、減、乘、除和取餘,這類運算符的使用頻率比較高
下面是運算符的分類
運算符 | 做用 |
---|---|
+ | 加法 |
- | 減法 |
* | 乘法 |
/, DIV | 除法,返回商 |
%, MOD | 除法,返回餘數 |
下面簡單描述了這些運算符的使用方法
+
用於得到一個或多個值的和-
用於從一個值減去另外一個值*
用於兩數相乘,獲得兩個或多個值的乘積/
用一個值除以另外一個值獲得商%
用於一個值除以另外一個值獲得餘數在除法和取餘須要注意一點,若是除數是 0 ,將是非法除數,返回結果爲 NULL。
熟悉了運算符,下面來聊一聊比較運算符,使用 SELECT 語句進行查詢時,MySQL 容許用戶對錶達式的兩側的操做數進行比較,比較結果爲真,返回 1, 比較結果爲假,返回 0 ,比較結果不肯定返回 NULL。下面是全部的比較運算符
運算符 | 描述 |
---|---|
= | 等於 |
<> 或者是 != | 不等於 |
<=> | NULL 安全的等於,也就是 NULL-safe |
< | 小於 |
<= | 小於等於 |
> | 大於 |
>= | 大於等於 |
BETWEEN | 在指定範圍內 |
IS NULL | 是否爲 NULL |
IS NOT NULL | 是否爲 NULL |
IN | 存在於指定集合 |
LIKE | 通配符匹配 |
REGEXP 或 RLIKE | 正則表達式匹配 |
比較運算符能夠用來比較數字、字符串或者表達式。數字做爲浮點數進行比較,字符串以不區分大小寫的方式進行比較。
<>
號用於表示不等於,和 =
號相反,示例以下<=>
NULL-safe 的等於運算符,與 = 號最大的區別在於能夠比較 NULL 值<
號運算符,當左側操做數小於右側操做數時,返回值爲 1, 不然其返回值爲 0。select 'a' <= 'b'; /* 返回 1 */
/*而*/
select 'a' >= 'b'; /* 返回 0 呢*/
複製代碼
關於 >
和 >=
是同理
BETWEEN
運算符的使用格式是 a BETWEEN min AND max ,當 a 大於等於 min 而且小於等於 max 時,返回 1,不然返回 0 。操做數類型不一樣的時候,會轉換成相同的數據類型再進行處理。好比
IS NULL
和 IS NOT NULL
表示的是是否爲 NULL,ISNULL 爲 true 返回 1,不然返回 0 ;IS NOT NULL 同理IN
這個比較操做符判斷某個值是否在一個集合中,使用方式是 xxx in (value1,value2,value3)LIKE
運算符的格式是 xxx LIKE %123%
,好比以下當 like 後面跟的是 123%
的時候, xxx 若是是 123 則返回 1,若是是 123xxx 也返回 1,若是是 12 或者 1 就返回 0 。123 是一個總體。
REGEX
運算符的格式是 s REGEXP str
,匹配時返回值爲 1,不然返回 0 。後面會詳細介紹 regexp 的用法。
邏輯運算符指的就是布爾運算符
,布爾運算符指返回真和假。MySQL 支持四種邏輯運算符
運算符 | 做用 |
---|---|
NOT 或 ! | 邏輯非 |
AND 或者是 && | 邏輯與 |
OR 或者是 || | 邏輯或 |
XOR | 邏輯異或 |
下面分別來介紹一下
NOT
或者是 !
表示的是邏輯非,當操做數爲 0(假) ,則返回值爲 1,不然值爲 0。可是有一點除外,那就是 NOT NULL 的返回值爲 NULLAND
和 &&
表示的是邏輯與的邏輯,當全部操做數爲非零值而且不爲 NULL 時,結果爲 1,但凡有一個 0 則返回 0,操做數中有一個 null 則返回 nullOR
和 ||
表示的是邏輯或,當兩個操做數均爲非 NULL 值時,若有任意一個操做數爲非零值,則結果爲 1,不然結果爲 0。XOR
表示邏輯異或,當任意一個操做數爲 NULL 時,返回值爲 NULL。對於非 NULL 的操做數,若是兩個的邏輯真假值相異,則返回結果 1;不然返回 0。一據說位運算,就知道是和二進制有關的運算符了,位運算就是將給定的操做數轉換爲二進制後,對各個操做數的每一位都進行指定的邏輯運算,獲得的二進制結果轉換爲十進制後就說是位運算的結果,下面是全部的位運算。
運算符 | 做用 |
---|---|
& | 位與 |
| | 位或 |
^ | 位異或 |
~ | 位取反 |
>> | 位右移 |
<< | 位左移 |
下面分別來演示一下這些例子
位與
指的就是按位與,把 & 雙方轉換爲二進制再進行 & 操做按位與是一個數值減少的操做
位或
指的就是按位或,把 | 雙方轉換爲二進制再進行 | 操做位或是一個數值增大的操做
位異或
指的就是對操做數的二進制位作異或操做位取反
指的就是對操做數的二進制位作 NOT
操做,這裏的操做數只能是一位,下面看一個經典的取反例子:對 1 作位取反,具體以下所示:爲何會有這種現象,由於在 MySQL 中,常量數字默認會以 8 個字節來顯示,8 個字節就是 64 位,常量 1 的二進制表示 63 個 0
,加 1 個 1
, 位取反後就是 63 個 1
加一個 0
, 轉換爲二進制後就是 18446744073709551614,咱們可使用 select bin() 查看一下
位右移
是對左操做數向右移動指定位數,例如 50 >> 3,就是對 50 取其二進制而後向右移三位,左邊補上 0 ,轉換結果以下位左移
與位右移相反,是對左操做數向左移動指定位數,例如 20 << 2下面咱們來了解一下 MySQL 函數,MySQL 函數也是咱們平常開發過程當中常用的,選用合適的函數可以提升咱們的開發效率,下面咱們就來一塊兒認識一下這些函數
字符串函數是最經常使用的一種函數了,MySQL 也是支持不少種字符串函數,下面是 MySQL 支持的字符串函數表
函數 | 功能 |
---|---|
LOWER | 將字符串全部字符變爲小寫 |
UPPER | 將字符串全部字符變爲大寫 |
CONCAT | 進行字符串拼接 |
LEFT | 返回字符串最左邊的字符 |
RIGHT | 返回字符串最右邊的字符 |
INSERT | 字符串替換 |
LTRIM | 去掉字符串左邊的空格 |
RTRIM | 去掉字符串右邊的空格 |
REPEAT | 返回重複的結果 |
TRIM | 去掉字符串行尾和行頭的空格 |
SUBSTRING | 返回指定的字符串 |
LPAD | 用字符串對最左邊進行填充 |
RPAD | 用字符串對最右邊進行填充 |
STRCMP | 比較字符串 s1 和 s2 |
REPLACE | 進行字符串替換 |
下面經過具體的示例演示一下每一個函數的用法
上面把 c xu an
拼接成爲了一個字符串,另外須要注意一點,任何和 NULL 進行字符串拼接的結果都是 NULL。
MySQL 支持數值函數,這些函數可以處理不少數值運算。下面咱們一塊兒來學習一下 MySQL 中的數值函數,下面是全部的數值函數
函數 | 功能 |
---|---|
ABS | 返回絕對值 |
CEIL | 返回大於某個值的最大整數值 |
MOD | 返回模 |
ROUND | 四捨五入 |
FLOOR | 返回小於某個值的最大整數值 |
TRUNCATE | 返回數字截斷小數的結果 |
RAND | 返回 0 - 1 的隨機值 |
下面咱們仍是以實踐爲主來聊一聊這些用法
日期和時間函數也是 MySQL 中很是重要的一部分,下面咱們就來一塊兒認識一下這些函數
函數 | 功能 |
---|---|
NOW | 返回當前的日期和時間 |
WEEK | 返回一年中的第幾周 |
YEAR | 返回日期的年份 |
HOUR | 返回小時值 |
MINUTE | 返回分鐘值 |
MONTHNAME | 返回月份名 |
CURDATE | 返回當前日期 |
CURTIME | 返回當前時間 |
UNIX_TIMESTAMP | 返回日期 UNIX 時間戳 |
DATE_FORMAT | 返回按照字符串格式化的日期 |
FROM_UNIXTIME | 返回 UNIX 時間戳的日期值 |
DATE_ADD | 返回日期時間 + 上一個時間間隔 |
DATEDIFF | 返回起始時間和結束時間之間的天數 |
下面結合示例來說解一下每一個函數的使用
具體的日期格式能夠參考這篇文章 blog.csdn.net/weixin_3870…
咱們演示一下將當前日期顯示爲年月日的這種形式,使用的日期格式是 %M %D %Y。
interval 表示間隔類型的關鍵字,expr 是表達式,這個表達式對應後面的類型,type 是間隔類型,MySQL 提供了 13 種時間間隔類型
表達式類型 | 描述 | 格式 |
---|---|---|
YEAR | 年 | YY |
MONTH | 月 | MM |
DAY | 日 | DD |
HOUR | 小時 | hh |
MINUTE | 分 | mm |
SECOND | 秒 | ss |
YEAR_MONTH | 年和月 | YY-MM |
DAY_HOUR | 日和小時 | DD hh |
DAY_MINUTE | 日和分鐘 | DD hh : mm |
DAY_SECOND | 日和秒 | DD hh :mm :ss |
HOUR_MINUTE | 小時和分 | hh:mm |
HOUR_SECOND | 小時和秒 | hh:ss |
MINUTE_SECOND | 分鐘和秒 | mm:ss |
查看離 2021 - 01 - 01 還有多少天
流程函數也是很經常使用的一類函數,用戶可使用這類函數在 SQL 中實現條件選擇。這樣作可以提升查詢效率。下表列出了這些流程函數
函數 | 功能 |
---|---|
IF(value,t f) | 若是 value 是真,返回 t;不然返回 f |
IFNULL(value1,value2) | 若是 value1 不爲 NULL,返回 value1,不然返回 value2。 |
CASE WHEN[value1] THEN[result1] ...ELSE[default] END | 若是 value1 是真,返回 result1,不然返回 default |
CASE[expr] WHEN[value1] THEN [result1]... ELSE[default] END | 若是 expr 等於 value1, 返回 result1, 不然返回 default |
除了咱們介紹過的字符串函數、日期和時間函數、流程函數,還有一些函數並不屬於上面三類函數,它們是
函數 | 功能 |
---|---|
VERSION | 返回當前數據庫的版本 |
DATABASE | 返回當前數據庫名 |
USER | 返回當前登錄用戶名 |
PASSWORD | 返回字符串的加密版本 |
MD5 | 返回 MD5 值 |
INET_ATON(IP) | 返回 IP 地址的數字表示 |
INET_NTOA(num) | 返回數字表明的 IP 地址 |
下面來看一下具體的使用