Data Control Language
(數據庫的系統管理員)控制用戶的訪問權限。使用語句包括grant[受權]、revoke[回收權限]html
eg1:建立一個數據庫用戶 z1,具備對 zz 數據庫中全部表的 SELECT/INSERT 權限:mysql
grant select, insert on zz.* to 'z1'@'localhost' identified by 'z123';
eg2:將 z1 的權限變動,收回 INSERT,只能對數據進行 SELECT 操做:正則表達式
revoke insert on zz.* from 'z1'@'localhost';
這又是什麼?sql
GRANT update ON inventory TO joe WITH GRANT OPTION;
一個對象權限被授予用戶 JOE。
with admin option 只能在賦予 system privilege 的時使用;
with grant option 只能在賦予 object privilege 的時使用。數據庫
Data Definition Language
定義數據庫、表、視圖、索引和觸發器等。create[建立]、alter[修改表定義]、drop[刪除]truncate。windows
CREATE DATABASE 數據庫名;
若是建立的數據表中有值爲中文的字段,在建立數據庫時須要指定一個支持中文字符的字符集編碼。推薦使用UTF-8編碼。緩存
CREATE DATABASE db_1 CHARACTER SET UTF-8 COLLATE utf_general_ci;
ps:
1.數據庫名能夠由任意字母、數字、下畫線(_)和美圓符號($)組成,但不能由單獨的數字組成,也不能爲MySQL關鍵字,並且長度還不能超過64個字符。
2.在windows系統下,數據庫名不區分大小寫,在UNIX、Linux系統下,數據庫名、表名是區分大小寫的,但MySQL語句不區分大小寫。
3.完整的MySQL語句必須以‘;’結尾的語句。或者用g代替;(僅限命令行,有的版本可能不支持了)。安全
DROP DATABASE 數據庫名;
語法格式以下:併發
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition....)][table_options] [select_statement];
TEMPORARY:該參數用於建立臨時表。只有在當前鏈接下,臨時表纔是可見的;當鏈接關閉時,臨時表被自動取消。
數據表的名稱、命名要求與數據庫名同樣,由任意字母、數字、下畫線(_)和美圓符號($)組成,但tbl_name:表名不能由單獨的數字組成,也不能爲MySQL的關鍵字,並且長度還不能超過64個字符。
Table_options:該參數項用於設置數據庫表的一些特性。
Select_statement:該參數用於嵌入一個SELECT查詢語句,從而快速建立數據表。oracle
每一個字段的語法格式以下:
col_name type [NOT NULL|NULL][DEFAULT default_value][AUTO_INCREMENT][UNIQUE_KEY]|[PRIMARY_KEY][COMMENT ‘String’] [reference_definition](size)
type:字段的數據類型,如INT,REAL,DOUBLE,FLOAT,DATE,VARCHAR等。
NOT NULL,NULL:若是設置爲NULL,或者省略不設置,那麼代表該字段容許爲空值;若是設置爲NOT NULL,那麼代表該字段不容許爲空值。
DEFAULT default_value:該參數用來設置字段的默認值,default_value爲該字段默認的數值。
AUTO_INCREMENT:用於設置一個整數類型的字段爲自動增加字段。所謂自動增加,就是當試圖向該字段插入一個NULL值或0時,該字段的值會被設置成當前列的最大值+1,每張數據表只能有一個AUTO_INCREMNET字段,且該字段必須設置索引,同時不能爲有默認值。默認從1開始,後面加n。
UNIQUE或UNIQUE KEY:該參數用於設置UNIQUE索引。所謂UNIQUE索引(mysql裏叫索引INDEX而非constraint),就是插入該字段的值必須不相等,不然會出錯。例外狀況是,若是該字段被設置爲容許NULL值,則插入該字段的值能夠包含多個NULL值。但此例外狀況不適用於使用Berkley DB(BDB)引擎的數據表。
PRIMARY KEY或 KEY:該參數用於設置主鍵。一張數據表只能有一個PRIMARY KEY,即只能有一個主鍵(能夠是多個列)。設置爲主鍵的字段必須定義爲NOT NULL,若是該字段沒有被明確地定義爲NOT NULL,則MySQL會隱含地定義該字段爲NOT NULL。對於主健oracle/sql server/mysql等都會自動創建惟一索引。
主鍵的指定也能夠在()裏最後一列:primary key(colname)。
COMMENT ‘string’:該參數用於設置字段的註釋。字符串string中即爲註釋的內容。
Reference_definition:該參數用於引用其餘數據表中的字段。
size:最大長度。
create table test1 as select * from test;
後面加上WHERE 1=2則只複製表結構;
Constraints,用於規定表中的數據規則。若是存在違反約束的數據行爲,行爲會被約束終止。
約束能夠在建立表時規定(經過 CREATE TABLE 語句),或者在表建立以後規定(經過 ALTER TABLE 語句),包括:
NOT NULL - 指示某列不能存儲 NULL 值。
UNIQUE - 保證某列的每行必須有惟一的值。
PRIMARY KEY - NOT NULL 和 UNIQUE 的結合。確保某列(或兩個列多個列的結合)有惟一標識,有助於更容易更快速地找到表中的一個特定的記錄。
FOREIGN KEY - 約束一個表中的 FOREIGN KEY 指向另外一個表中的 PRIMARY KEY,用於預防破壞表之間鏈接的行爲,也能防止非法數據插入外鍵列,由於它必須是它指向的那個表中的值之一。
CHECK - 保證列中的值符合指定的條件。
DEFAULT - 規定沒有給列賦值時的默認值。
https://www.runoob.com/sql/sq...
語法格式以下:
DROP TABLE [IF EXISTS] 數據表名[,數據表名......];
可刪除一個或多個數據表,多個數據表名之間用英文逗號‘,’隔號。
若是僅僅須要刪除表內的數據,但並不刪除表自己,使用 TRUNCATE TABLE 語句:
TRUNCATE TABLE table_name;
在功能上與不帶 WHERE 子句的 DELETE 語句相同,兩者均刪除表中的所有行。區別在於:
truncate 只能對TABLE,delete 能夠是table,view,synonym。
在內存中,用delete刪除數據,表空間中其被刪除數據的表佔用的空間還在,便於之後的使用,另外它是「假相」的刪除,至關於windows中用delete刪除數據是把數據放到回收站中,還能夠恢復,固然若是這個時候從新啓動系統(OS或者RDBMS),它也就不能恢復了!
而用truncate清除數據,內存中表空間中其被刪除數據的表佔用的空間會被當即釋放,至關於windows中用shift+delete刪除數據,不可以恢復(回滾)!
delete通常用於刪除少許記錄的操做,並且它是要使用回滾段而且要進行顯示的提交 。
truncate 則使用於大量刪除數據,並且隱式提交事務,其速度要比使用 delete快。
包括重命名數據表名稱、重命名字段名稱、修改字段類型、修改字段默認值、增長和刪減字段等。
ALTER TABLE 原數據表名 RENAME 新數據表名;
ALTER TABLE 數據表名 CHANGE 原字段名 新字段的定義;
ALTER TABLE 數據表名 ADD 增長的字段定義;
刪減字段使用DROP子語句:
···
ALTER TABLE 數據表名 DROP 要刪減字段的名稱;
···
默認 ADD 增長的新字段是加在表的最後位置,而 CHANGE/MODIFY 默認都不會改變字段的位置。
alter table emp add birth date after ename; alter table emp modify age int(3) first;
ps:
ALTER TABLE語句在執行時,會對原數據表進行臨時複製,並在副本上進行修改,修改完成後刪除原數據表,再對新表進行重命名。在執行ALTER TABLE語句時,其餘用戶能夠閱讀原數據表,可是對該數據表的更新和修改操做將被延遲,直到新數據表生成爲止。新表生成後,這些更新和修改信息會自動轉移到新表上。
在MySQL的bin目錄下,有一個名爲mysqldump的可執行文件,執行:
mysqldump --opt 要備份的數據庫名 -h MySQL數據庫所在的域名或IP地址 -u 帳戶名 -p -r 備份文件的路徑backup.mysql
或者:
Mysqldump --opt 要備份的數據庫名 -h MySQL數據庫所在的域名或IP地址 -u 帳戶名 -p > 備份文件的路徑backup.mysql
經過使用mysqldump程序備份的文件,能夠將數據庫恢復到指定的狀態。語法格式:
mysql -h MySQL數據庫所在的域名或IP地址 -u 帳戶名 -p 要恢復的數據庫名 < 備份文件的路徑
視圖僅僅是用來查看存儲在別處數據的一種設施。視圖自己不包含數據,所以返回的數據是從其餘表中檢索出來的。在添加或更改這些表中的數據時,視圖將返回改變過的數據。
視圖是虛擬的表,它只是一個查詢語句對應的結果集。在SQL語句中體現的角色與表一致,但視圖不能索引,也不能有關聯的觸發器或默認值。
CREATE OR REPLACE VIEW v_emp_10 AS SELECT empno, ename, sal, deptno FROM emp WHERE deptno = 10
使用視圖好處:
1.簡化用戶操做:利用視圖簡化複雜的聯結利用視圖,可一次性編寫基礎的 SQL ,而後根據須要屢次使用。
2.對重構數據庫提供了必定程度上的邏輯獨立性:視圖可使應用程序和數據庫表在必定程度上獨立。若是沒有視圖,應用必定是創建在表上的。有了視圖以後,程序能夠創建在視圖之上,從而程序與數據庫表被視圖分割開來。
3.安全性:經過視圖用戶只能查詢和修改他們所能見到的數據。數據庫中的其餘數據則既看不見也取不到。數據庫受權命令可使每一個用戶對數據庫的檢索限制到特定的數據庫對象上,但不能受權到數據庫特定行和特定的列上。經過視圖,用戶能夠被限制在數據的不一樣子集上。
使用視圖壞處:
1.性能:若是這個視圖是由一個複雜的多表查詢所定義,那麼,即便是視圖的一個簡單查詢,它會變成一個複雜的結合體,須要花費必定的時間。許多 DBMS 禁止在視圖查詢中使用ORDER BY子句。
2.修改限制:當用戶試圖修改視圖的某些行時,對於簡單視圖來講,這是很方便的,可是,對於比較複雜的視圖,多是不可修改的。
常見應用:
重用 SQL 語句。 簡化複雜的 SQL 操做。在編寫查詢後,能夠方便地重用它而沒必要知道其基本查詢細節。 使用表的一部分而不是整個表。 保護數據。能夠授予用戶訪問表的特定部分的權限,而不是整個表的訪問權限。 更改數據格式和表示。視圖可返回與底層表的表示和格式不一樣的數據。
對應的子查詢不含有函數,表達式,分組,去重,關聯查詢。
簡單視圖能夠進行DML操做(只能對視圖可見的字段進行),對該視圖的操做就是對該視圖數據來源的基礎表進行的操做,因此不能違反基礎表的約束條件。
爲了禁止在視圖上執行DML操做,能夠在創建視圖時設置READ ONLY約束。
除了簡單視圖就是複雜視圖。
複雜視圖不容許進行DML操做。
對視圖的不當DML操做會污染基表數據,不當DML操做即:對視圖進行DML操做後,視圖對基礎表對應數據進行該DML操做,可是操做後視圖卻對該記錄不可見。
若有一個視圖,只檢索帶有電子郵件地址的顧客,若是更新某個顧客,刪除他的電子郵件地址,將使該顧客再也不屬於視圖。
DELETE不會產生污染現象。why?由於數據都被刪了,至關於查出來是空的。
爲視圖添加檢查選項,能夠避免對視圖操做而致使的對基表的數據污染。WITH CHECK OPTION
該選項要求對視圖進行DML操做後,該記錄必須對視圖可見。
CREATE OR REPLACE VIEW v_emp_10 AS SELECT empno id,ename name,sal salary,deptno FROM emp WHERE deptno=10 WITH CHECK OPTION
爲視圖添加只讀選項,要求對視圖僅能進行查詢操做不能進行任何DML操做。WITH READ ONLY
CREATE OR REPLACE VIEW v_emp_10 AS SELECT empno id,ename name, sal salary,deptno FROM emp WHERE deptno=10 WITH READ ONLY
是爲了幫助mysql高效獲取數據,對數據庫表中一個或多個列的值進行排序的結構,用戶沒法看到索引,它們只能被用來加速搜索/查詢。
注意:更新一個包含索引的表須要比更新一個沒有索引的表花費更多的時間,這是因爲索引自己也須要更新。所以,理想的作法是僅僅在經常被搜索的列(以及表)上面建立索引。
分爲:普通索引、惟一索引(確保每一行數據的惟一性)、主鍵索引、全文索引。
優化tips: 避免在索引列上使用計算、not、in、<>等操做。
eg1:在 "Persons" 表的 "LastName" 列上建立一個名爲 "PIndex" 的索引:
CREATE INDEX PIndex ON Persons (LastName);
若是但願索引不止一個列,能夠在括號中列出這些列的名稱,用逗號隔開:
CREATE INDEX PIndex ON Persons (LastName, FirstName);
刪除索引:
ALTER TABLE table_name DROP INDEX index_name
主要是SELECT。
SELECT 字段名[字段名,...] FROM 數據表名 WHERE 條件表達式;
1.「數據表名」能夠是一個子查詢獲得的結果。
條件表達式能夠是包含‘>’、‘<’ 、‘>=’、‘<=’、‘=’(相等)、‘<>’(不等)、‘BETWEEN’、'LIKE'、‘IN’、‘and’(邏輯與)、‘or’(邏輯或)、'IS NULL'等運算符。
但裏面不能夠放聚合函數!若是須要,能夠用GROUP BY 或子查詢。
用於結合聚合函數,根據一個或多個列對結果集進行分組。
有時須要對錶中的記錄按照字段進行分組,而後對每一個分組分別運用聚合函數進行查詢或者計算。語法格式以下:
SELECT [聚合函數] 起的名[,字段名 ... ] FROM 表名 WHERE 查詢條件 GROUP BY 字段名
eg1:統計80分及以上各個成績的學生人數:
SELECT score, count(*) FROM stu_ WHERE score>=80 GROUP BY score;
GROUP BY 子語句經常有HAVING子語句連用,接在GROUP BY後面。
增長 HAVING 子句緣由是,WHERE 關鍵字沒法與聚合函數一塊兒使用。
HAVING子語句與WHERE子語句的區別在於, having 是對聚合後的結果進行條件的過濾,而 where 是在聚合前就對記錄進行過濾。
優化tips:若是邏輯容許,咱們儘量用 where 先過濾記錄,這樣由於結果集減少,將對聚合的效率大大提升,最後再根據邏輯看是否用 having 進行再過濾。
eg1:統計各個部門的人數:select deptno,count(1) from emp group by deptno;
eg2:既要統計各部門人數,又要統計總人數: select deptno,count(1) from emp group by deptno with rollup;
eg3:統計人數大於 1 人的部門:select deptno,count(1) from emp group by deptno having count(1)>1;
SELECT 字段名[字段名,...] FROM 數據表名 WHERE 條件表達式 LIMIT [OFFSET,] row_count;
實現分頁查詢:
從索引爲offset(默認爲0)的記錄開始,返回row_count條記錄。
offset和row_count 必須爲非負整數常量。
SELECT * FROM city limit 10,5; --從索引爲10(第11條)的記錄開始,讀取5條,等同於下面 SELECT * FROM city limit 5 offset 10; --從索引爲10(第11條)的記錄開始,讀取5條數據。
LIMIT經常與ORDER BY配合使用,先對查詢結果進行排序,再從中挑出指定位置的記錄。‘ASC’與‘DESC’爲可選參數,分別表示升序(默認,小到大)排列和降序排列。ORDER BY 多列的時候,先按照第一個column name排序,在按照第二個column name排序。
SELECT 字段名[字段名,...] FROM 數據表名 WHERE 條件表達式 ORDER BY P字段名[字段名,...] [ASC|DESC] LIMIT [offset,] row_count;
還有一種寫法:
SELECT prod_id, prod_price, prod_name FROM Products ORDER BY 2, 3;
ORDER BY 2表示按SELECT清單中的第二個列prod_name進行排序。ORDER BY 2,3表示先按prod_price,再按prod_name進行排序。
一個列可能會包含多個重複值,有時您也許但願僅僅列出不一樣(distinct)的值
它會做用於所用列,怎麼使得它只做用於指定的列?
常與通配符連用。Select * from emp where ename like 'M%';
查詢 emp 表中 ename 列中 M開頭 的值。
與NOT連用,反向選擇:SELECT * FROM Websites WHERE name NOT LIKE '%oo%';
調優tips:通配符搜索通常比其餘搜索要耗費更長的處理時間,不要過分使用通配符。若是其餘操做符能達到相同的目的,應該使用其餘操做符。
在確實須要使用通配符時,也儘可能不要把它們用在搜索模式的開始處。把通配符置於開始處,搜索起來是最慢的。
%
表示1或多個字值,_
下劃線表示一個字符;M%
: 爲能配符,正則表達式,表示的意思爲模糊查詢信息爲 M 開頭的。%M%
: 表示查詢包含M的全部內容。%M_
: 表示查詢以M在倒數第二位的全部內容。[charlist]
字符列中的任何單一字符;[^charlist]
或[!charlist]
不在字符列中的任何單一字符。
eg1:選取 name 以 "G"、"F" 或 "s" 開始的全部網站:SELECT * FROM Websites WHERE name REGEXP '^[GFs]';
容許在 WHERE 子句中規定多個值。
Select * from emp where sal in (5000,3000,1500);
IN操做符完成了與OR相同的功能,其優勢在於:
1.語法更清楚,更直觀。
2.在與其餘AND和OR操做符組合使用IN時,求值順序更容易管理。
3.IN操做符通常比一組OR操做符執行得更快(在上面這個合法選項不多的例子中,你看不出性能差別)。
4.IN的最大優勢是能夠包含其餘SELECT語句,可以更動態地創建WHERE子句。
選取介於兩個值之間的數據範圍內的值(包括它兩)。這些值能夠是數值、文本或者日期。SELECT * FROM Websites WHERE name BETWEEN 'A' AND 'H';
選取 name 以介於 'A' 和 'H' 之間字母開始的全部網站SELECT * FROM access_log WHERE date BETWEEN '2016-05-10' AND '2016-05-14';
可加NOT反向選擇
能夠爲表名稱或列名稱指定別名
還把多個列(url、alexa 和 country)結合在一塊兒,並建立一個名爲 "site_info" 的別名:SELECT name, CONCAT(url, ', ', alexa, ', ', country) AS site_info FROM Websites;
查詢條件爲EXISTS關鍵字後面跟的SELECT語句的查詢結果不爲空便可!
Exists:若子查詢的結果集非空時,返回「True」;若子查詢的結果集爲空時,返回「False」 。
NOT EXISTS :若子查詢結果爲空,返回「TRUE」值;若子查詢的結果集非空時,返回 「FALSE。
SELECT * FROM A WHERE id IN (SELECT id FROM B);
這條sql子查詢IN中的內容只會執行一次,而後緩存子查詢結果,最後在內存中遍歷結果集並與A表遍歷出的全部id進行比較。一共要比較A.length*B.length次。
適合B表較小時使用。SELECT * FROM A WHERE EXISTS(SELECT 1 FROM B WHERE A.id=B.id);
這條sql子查詢EXISTS中的內容會執行A.length次去判斷t仍是f,它並不緩存結果,由於EXISTS裏的結果並不重要,再執行一次就行。
適合B表比A表大時使用。
可是,查詢數據庫所消耗的性能比內存遍歷比較大!因此最後結果是,EXISTS適合子查詢表很大的狀況!其餘狀況差很少。
Data Manipulation Language語句。操做數據庫的表如insert[插入],update[更新],delete[刪除]數據。
插入一行數據:
INSERT INTO 數據表名 VALUES(字段的值,...);
高度依賴於表中列的定義次序,若是表結構變了,會出錯。
插入行的部分數據:
INSERT INTO 數據表名(字段名,...) VALUES(字段的值,...);
其中,字段名與字段值必須一一對應。字段名能夠不列全,此時插入的這條記錄中,省略的字段會被默認值填充。
或者使用INSERT SET語句:
INSERT INTO 數據表名 SET 字段名1=字段值1, 字段名2=字段值2;
從一個表apps複製(查詢)數據,而後把數據插入到另外一個表Websites中INSERT INTO…SELECT…:
INSERT INTO Websites (name, country) SELECT app_name, country FROM apps WHERE id=1;
帶子查詢的:
insert into vehicle_nonetwork (time,areacode,vincode,color,vintype) SELECT 201507,areacode,vincode,color,tran_new FROM `vehicle_201507` where vincode not in (SELECT DISTINCT v.vincode from vehi v1,vehicle_201507 v where v.areacode=v1.areacode and v.color=v1.color and v.vincode=v1.vincode) order by areacode;
從一個表複製(查詢)數據,而後把數據插入到另外一個新表中(自動建立)SELECT …INTO … FROM …:SELECT * INTO newWebsites FROM apps;
複製全部的列,把*換爲column_name(s)只複製但願的列插入到新表中。
新表將會使用 SELECT 語句中定義的列名稱和類型進行建立。可使用 AS 子句來應用新字段名。
SELECT Websites.name, access_log.count, access_log.date INTO WebsitesBackup2016 FROM Websites LEFT JOIN access_log ON Websites.id=access_log.site_id;
UPDATE 數據表名 SET 字段名=新字段值,... [WHERE 查詢條件];
注意:update 後面能夠作任意的查詢,這個做用等同於from;但更新的表不能在set和where中用於子查詢。
同時更新多個表的複雜更新:
update ta a,(select * from tb where name='ee') b set a.Bid=b.id ,b.Aid=a.id where a.name=b.name and a.time=b.time;
多表更新的語法更多地用在了根據一個表的字段,來動態的更新另一個表的字段:
update emp a,dept b set a.sal=a.sal*b.deptno,b.deptname=a.ename where a.deptno=b.deptno;
set值也能夠帶子查詢:
update aaaCountV set 客車總數=(select sum from akeche1 where akeche1.owner_id=aaaCountV.owner_id);
ps:要刪除某個列的值,可設置它爲NULL(假如表定義容許NULL值)。
用REPLACE插入一條記錄時,若是不重複,REPLACE就和INSERT的功能同樣,若是有重複記錄,REPLACE就使用新記錄的值來替換原來的記錄值。
可是,在使用REPLACE時,表中必須有惟一索引,並且這個索引所在的字段不能容許空值,不然REPLACE就和INSERT徹底同樣的。
REPLACE tablename(列名…) VALUES(列值);
或者:
REPLACE tablename SET column_name1 =value1, column_name2 = value2,…;
用來刪除表中的記錄。常與WHERE子語句連用,用來定位須要刪除的記錄。
語法格式以下:
DELETE t1,t2…tn FROM t1,t2…tn [WHERE CONDITION];
若是沒有WHERE子語句,則該表中的全部數據將被刪除,DELETE不刪除表自己,表結構、屬性、索引將保持不變。同DELETE * FROM table_name
。
若是 from 後面的表名用別名,則 delete 後面的也要用相應的別名,不然會提示語法錯誤:
delete a,b from emp a,dept b where a.deptno=b.deptno and a.deptno=3;
查詢當前數據庫支持的存儲引擎:mysql> SHOW ENGINES \G;
獲得9條記錄。
ps:\G
選項的含義是使得記錄可以按照字段豎着排列,對於內容比較長的記錄更易於顯示(僅限命令行)
經過查看建表語句,能夠查看錶的存儲引擎:SHOW CREATE TABLE table_name;
MySQL 的默認存儲引擎。MyISAM 不支持事務、也不支持外鍵,其優點是訪
問的速度快,對事務完整性沒有要求或者以 SELECT、INSERT 爲主的應用基本上均可以使用
這個引擎來建立表。
支持外鍵、行鎖的鎖機制、提供了具備提交、回滾和崩潰恢復能力的事務安全。可是對比 MyISAM的存儲引擎,InnoDB 寫的處理效率(包括批量處理)差一些而且會佔用更多的磁盤空間以保留數據和索引。若是應用對事務的完整性有比較高的要求, 在併發條件下要求數據的一致性, 數據操做除了插入和查詢之外, 還包括不少的更新、刪除操做,那麼 InnoDB 存儲引擎應該是比較合適的選擇。InnoDB 存儲引擎除了有效地下降因爲刪除和更新致使的鎖定,還能夠確保事務的完整提交(Commit)和回滾(Rollback) ,對於相似計費系統或者財務系統等對數據準確性要求比較高的系統,InnoDB 都是合適的選擇。