前言:本文主要為mysql基礎(chǔ)知識的大總結(jié),mysql的基礎(chǔ)知識很多,這里作簡單概括性的介紹,具體的細(xì)節(jié)還是需要自行搜索。當(dāng)然本文還有很多遺漏的地方,后續(xù)會慢慢補(bǔ)充完善。

數(shù)據(jù)庫和數(shù)據(jù)庫軟件

  • 數(shù)據(jù)庫是保存有組織數(shù)據(jù)的容器

  • DBMS是為管理數(shù)據(jù)庫而設(shè)計(jì)的軟件管理系統(tǒng),MYSQL、ORACLE 等是數(shù)據(jù)庫管理系統(tǒng)

MYSQL

  • MYSQL是一種數(shù)據(jù)庫管理軟件

  • 開放源碼,免費(fèi)使用

MYSQL命令

  • CREATE DATABASE NAME 創(chuàng)建數(shù)據(jù)庫

  • USE DATABASE 選擇數(shù)據(jù)庫

  • DROP DATABASE NAME 直接刪除數(shù)據(jù)庫

  • SHOW DATABASE 顯示可用數(shù)據(jù)庫列表

  • SHOW TABLE 顯示數(shù)據(jù)庫中的表的列表

  • SHOW COLUMNS FROM TABLE 與 DESCRIBE TABLE 等效,顯示表的字段信息

  • SHOW GRANTS 顯示授予用戶的安全權(quán)限

  • SHOW ERRORS SHOW WARNINGS 顯示服務(wù)器錯(cuò)誤和警告信息

SQL

  • STRUCTURED QUERY LANGUAGE 結(jié)構(gòu)化查詢語言,一種專門用于與數(shù)據(jù)庫通信的語言

  • 不是DBMS專有的語言,很多DBMS都支持SQL,但是不同DBMS對SQL的實(shí)現(xiàn)不同

  • DBMS支持的SQL語法不能完全適用于其他DBMS

  • SQL語句不區(qū)分大小寫

  • 多條語句需要分號分隔,單條語句可以不用分號

  • 通常SQL語句用大寫,標(biāo)識符(比如表名 列名 數(shù)據(jù)庫名)用小寫

創(chuàng)建表

  • CREATE TABLE user (id INT NOT NULL AUTO_INCREMENT, username VARCHAR(50) NOT NULL,password VARCHAR (50) NOT NULL DEFAULT 1,PRIMARY KEY(id)) ENGINE =INNODB

檢索列

  • SELECT username FROM user

  • SELECT username,password FROM user

  • SELECT * FROM user 建議不是要所有的列,不用'*',要不然這種操作是很耗性能的

  • SELECT DISTINCT username FROM user 只返回不同的username,比如有兩行用戶名是一樣的,只顯示一行記錄

限制結(jié)果

  • SELECT * FROM TABLE LIMIT 5 檢索前五行

  • SELECT * FROM TABLE LIMIT 5,5 檢索6到10

  • SELECT * FROM TABLE LIMIT 5,-1 檢索6到最后一行

結(jié)果排序

  • SELECT * FROM user ORDER BY username,以username的字母順序排列

  • SELECT * FROM user ORDER BY username,password ,如果username有相同的,那么username相同的再按password排列,如果username都是唯一,這個(gè)時(shí)候password不起作用

  • SELECT * FROM user ORDER BY username DESC ,降序排列,默認(rèn)是升序ASC

  • SELECT * FROM user e ORDER BY username DESC,password 此時(shí)按照username降序排列,如果username相同的行按照password升序排列

  • SELECT * FROM user ORDER BY username LIMIT 1 混合使用ORDER 和 LIMIT

  • SELECT * FROM user WHERE username ='jiajun' ORDER BY password 這里ORDER要在WHERE 之后

過濾數(shù)據(jù)

  • SELECT * FROM user WHERE username <> 'jiajun' 不等于 和 != 效果相同

  • SELECT * FROM user WHERE id BETWEEN 1 AND 10 檢索1到10的記錄,包括1和10

  • SELECT * FROM user WHERE username IS NULL 查找列無值的行,這里的無值不等于 值為0 和 空字符串

  • SELECT * FROM user WHERE id=1 OR username='jiajun' AND password='666' 執(zhí)行順序是 WHERE id=1 OR (username='jiajun' AND password='666')AND的優(yōu)先級更高,但是建議添加括號

  • SELECT * FROM user WHERE id IN (1,2) 效果和SELECT * FROM user WHERE id=1 OR id =2 如果要實(shí)現(xiàn)這種效果,建議使用第一種,語法更清晰,而且一般執(zhí)行更快

  • SELECT * FROM user WHERE id NOT IN (1,2)

通配符過濾

  • SELECT * FROM user WHERE username LIKE 'jia%' ,匹配jia開頭的username,不管后面有多少字符,jia和jiajun都是匹配,可以配置MySQL是否區(qū)份大小寫,如果區(qū)份大小寫,也就是jiajun是不匹配的 。注意LIKE '%'是不能匹配值為NULL的

  • SELECT * FROM user WHERE username LIKE 'jia_' , _只能匹配一個(gè)字符,也就是匹配jiaj不匹配jiajun

  • 通配符匹配是效率不高,如果其他方式能有相同的效果,建議用其他效果,并且最好不要將通配符放在開始處,因?yàn)檫@樣是很慢的

正則表達(dá)式過濾

  • SELECT * FROM user WHERE username REGEXP '.ia' ,正則表達(dá)式, . 匹配任意一個(gè)字符

  • SELECT * FROM user WHERE username REGEXP 'jun' 匹配包含jun的username,'jiajun'和'jun'都匹配

  • SELECT * FROM user WHERE username REGEXP 'jiajun|jiaj' ,'|'和'OR' 效果一樣

  • SELECT * FROM user WHERE username REGEXP ‘[123]jun’ ,匹配包含'1jun'或者'2jun'或者'3jun'

  • [^123]123除外

  • [1-9],[A-Z],用'-'表示范圍

  • 匹配特殊字符(比如'.'和'_')可以采用'\'轉(zhuǎn)義,比如匹配有'.'的可以這樣表示'\.'

拼接字段

  • SELECT CONCAT(username,'(',password,')') FROM user,將兩個(gè)字段拼接到一起,查詢結(jié)果是一列,行值 jiajun(666)

  • SELECT CONCAT(username,')',password,')') AS up FROM user,為拼接后的一列設(shè)置字段名

算數(shù)運(yùn)算

  • SELECT price*count AS all FROM TABLE 將單價(jià)和數(shù)量相乘,列名為all

函數(shù)

  • 函數(shù)可移植性不高,也就是一個(gè)函數(shù)支持一個(gè)DBMS,但不一定支持另一個(gè)DBMS,比如支持MYSQL而不支持ORACLE。所以使用函數(shù)的要寫好注釋。

文本處理函數(shù)

  • LENGTH() 返回串長度

  • LOWER()將串轉(zhuǎn)換為小寫

  • UPPER()將串轉(zhuǎn)換為大寫

  • LTRIM()去掉串左邊的空格

  • RTRIM()去掉串右邊的空格

日期和時(shí)間處理函數(shù)

  • CURDATE() 2017-07-22

  • CURTIME()16:20:19

  • NOW() 2017-07-22 16:20:19

  • DATE() 返回日期的日期部分 SELECT DATE(NOW()) 2017-07-22

  • DATE_FORMAT() 返回格式化的日期和時(shí)間串

  • HOUR() 返回一個(gè)時(shí)間的小時(shí)部分

  • MINUTE() 返回一個(gè)時(shí)間的分鐘部分

  • MONTH() 返回一個(gè)日期的月份部分

  • NOW() 返回當(dāng)前日期和時(shí)間

  • SECOND() 返回一個(gè)時(shí)間的秒部分

  • TIME() 返回一個(gè)日期時(shí)間的時(shí)間部分

  • YEAR() 返回一個(gè)日期的年份部分

日期函數(shù)注意點(diǎn)

  • SELECT * FROM TABLE WHERE date='2017-7-22' ,如果DATE的類型是DATATIME類型,那么表里一條記錄存放的格式應(yīng)該是2017-07-22 16:20:19,此時(shí)這條記錄不會被篩選出來,篩選的是2017-07-22 00:00:00

  • 可以采用DATE函數(shù) SELECT * FROM TABLE WHERE DATE(date)='2017-7-22'

  • 時(shí)間范圍 可以采用DATE函數(shù) SELECT * FROM TABLE WHERE DATE(date) BETWEEN '2017-7-1' AND ''2017-7-31

數(shù)組處理函數(shù)

  • ABS() 返回一個(gè)數(shù)的絕對值

  • COS() 返回一個(gè)角度的余弦

  • EXP()返回一個(gè)數(shù)的指數(shù)值

  • MOD()返回除操作的余數(shù)

  • PI() 返回圓周率

  • RAND()返回一個(gè)隨機(jī)數(shù)

  • SIN()返回一個(gè)角度的正弦

  • SQRT() 返回一個(gè)數(shù)的平方根

  • TAN() 返回一個(gè)角度的正切

聚集函數(shù)

  • SELECT AVG(student_score) AS AVG_ PRIVE FROM score 求平均值

  • SELECT COUNT(*) FROM TABLE 表里記錄數(shù)

  • SELECT COLUMN(name) FROM TABLE 表里列有值的記錄數(shù) ,值為NULL不計(jì)數(shù)

  • SELECT MAX(score) FROM TABLE 查找最大值

  • SELECT MIN(score) FROM TABLE 查找最小值

  • SELECT SUM(count) FROM TABLE 返回指定列的和 SUM(price*count)同樣適用

數(shù)據(jù)分組

  • SELECT AVG(score) FROM score GROUP BY class_id 檢索不同課的平均分

  • SELECT AVG(score) FROM score GROUP BY class_id, dep_id ,GROUP BY 后面可以多個(gè)字段

  • SELECT AVG(score) FROM score GROUP BY class_id ,SELECT 的字段必須是GROUP BY 后面的字段或者是聚合函數(shù),在這里根據(jù)class_id分最后,class_id相同合并成一行,但是這里面的合并的這些score不同,如何能合并成一行

  • 如果分組列有NULL值的,將列值為NULL的分為一組

  • GROUP BY 要在WHERE之后,ORDER BY 之前,也就是先過濾再分組再排序

  • SELECT COUNT(*) FROM TABLE GROUP BY id HAVING COUNT(*)>3 ,分組后,對分組再進(jìn)行過濾。

子查詢

  • SELECT * FROM student WHERE class_id IN (SELECT class_id FROM teacher WHERE teacher_id=6) ,子查詢過濾,WHERE里面嵌套子查詢

  • SELECT name ,(SELECT score FROM score WHERE studen.student_id=score.student_id) AS score FROM student 計(jì)算字段字段使用子查詢

  • 不建議使用太多的子查詢,會影響性能

主鍵

  • 唯一標(biāo)識自己的一列或一組列,唯一區(qū)別表中的一行

  • 主鍵不能為空

  • 任意兩行的主鍵值必須不同

  • 主鍵不是必須的,但是建議每個(gè)表中有一個(gè)主鍵,這樣操作管理更方便

  • 主鍵值最好不更新

  • 一個(gè)表的主鍵只能有一個(gè)

外鍵

  • 一個(gè)表的主鍵指向另一個(gè)表的外鍵,比如說student表的主鍵student_id,在score表中也有,并且是score表的外鍵

  • 外鍵保持了數(shù)據(jù)完整性和一致。,比如你在student表里面修改了student_id后,則score的student_id也會聯(lián)動更新。并且score表中插入的student_id必須是student表里有的

聯(lián)結(jié)

  • SELECT name,score FROM score,student 兩個(gè)表進(jìn)行聯(lián)結(jié),此時(shí)進(jìn)行的是笛卡爾積,就是說結(jié)果的行數(shù)score表行數(shù)*student表的行數(shù)

  • SELECT name,score FROM score,student WHERE student.student_id=score.student_id,在上面的基礎(chǔ)上,加上WHERE進(jìn)行過濾

  • SELECT name,score FROM score INNER JOIN student ON student.student_id=SOCRE.student_id 內(nèi)部聯(lián)結(jié)

  • 外部聯(lián)結(jié),LEFT OUTER JOIN 和 RIGHT OUTER JOIN ,有時(shí)候內(nèi)部聯(lián)結(jié)的時(shí)候會出現(xiàn)聯(lián)結(jié)條件不匹配的行,而LEFT JOIN 保證了保證左邊表的所有行,右聯(lián)結(jié)同理

  • FULL JOIN效果LEFT JOIN + RIGHT JOIN一致,左表不匹配的右表不匹配的都會列出

  • 不要聯(lián)結(jié)太多的表,這樣會降低性能

  • 聯(lián)結(jié)的時(shí)候可能因?yàn)閮蓚€(gè)表有相同的列,因?yàn)闆]有做好限制導(dǎo)致相同的列的出現(xiàn)兩次,所以這是需要的地方,這也是所謂的自然聯(lián)結(jié)

別名

  • SELECT CONCAT(username,'(',password,')') AS MES FROM user,這里采用CONCAT將兩個(gè)字段拼接在一起,并且給拼接后的字段起一個(gè)別名MES

  • 同樣表也可以起別名SELECT name,score FROM score AS A,student AS B WHERE A.student_id=B.student_id

組合查詢

  • 利用UNION將多個(gè)SELECT語句的結(jié)果組合起來,可以理解成同一個(gè)表頭的表垂直拼接在一起

  • 每個(gè)查詢必須包含相同的列數(shù),而且字段類型要兼容。

  • SELECT score FROM score WHERE NAME='jiajun' OR score BETWEEN 95 AND 100 和 SELECT score FROM score WHERE NAME='jiajun' UNION SELECT score FROM score WHERE score BETWEEN 95 AND 100 作用等效。

  • 上面的是單表查詢,用了UNION感覺復(fù)雜了,但是如果用于不同表的查詢的連接會更簡單。

  • 如果A查詢查到5行,B查詢查到4行,由于有重復(fù)的,會去掉相同的行,最后剩下8行,如果需要的話可以用UNION ALL

插入數(shù)據(jù)

  • INSERT INTO user VALUES ('jiajun','666') 和 INSERT INTO user (username,password) VALUES ('jiajun','666'),在表里只有username和password兩個(gè)字段是等效,前一種方式必須值的個(gè)數(shù)和順序必須和字段的個(gè)數(shù)順序一致,而后者,因?yàn)榻o出列和值,只要一一對應(yīng)就好

  • INSERT INTO user VALUES ('jiajun','666'),('jiajia','666') 插入多行

  • INSERT INTO user VALUES (SELECT username ,password FROM olduser),檢索出olduser的行然后插入到user表,這里注意的還是列的問題,后面的SELECT語句后的字段名并不重要,不需要和user表對應(yīng),因?yàn)橹皇菍z索的列值按順序插入到user表,并不在意olduser的字段名。同時(shí)列的數(shù)目和順序也是需要注意的

更新數(shù)據(jù)

  • UPDATE user SET password ='666',money='6666' WHERE username='jiajun',需要注意的是WHERE一定不要漏,要不然會更新表中的所有行

  • 在更新多行的時(shí)候如果中途出現(xiàn)錯(cuò)誤,會將更新的恢復(fù)回原來的值,如果要做到即使中途發(fā)生錯(cuò)誤也要繼續(xù)更新可以采用 IGNORE關(guān)鍵字,UPDATE IGNORE user

刪除數(shù)據(jù)

  • 如果想刪除一個(gè)列的值,SET username=NULL就行了

  • 如果想要刪除一行,DELETE FROM user WHERE username='jiajun'

  • 如果想要刪除整個(gè)表的行 DETELTE FROM user,注意這個(gè)表不會刪除,只是所有記錄清空。TRUNCATE user,也有相同的效果,不同的是他是先刪除表,然后重新建立一個(gè)表

更新表

  • ALTER TABLE user ADD phone CHAR(20) 添加一列

  • ALTER TABLE user DROP COLUMN phone 刪除一列

  • ALTER TABLE user CONSTRAINT wai_jian FOREGIN KEY (class_id) REFERENCES class (class_id) 定義外鍵

  • ALTER TABLE user ADD PRIMARY KEY (id)添加主鍵

  • 修改前做好備份,表的更改不能撤銷

刪除表

  • DROP TABLE user

重命名表

  • RENAME TABLE user TO users

視圖

  • 當(dāng)我們查詢后出現(xiàn)一個(gè)結(jié)果,我們可以包裝成一個(gè)虛擬表,也就是視圖,我們可以把他當(dāng)成表使用

  • 視圖本身不包含數(shù)據(jù),數(shù)據(jù)是從其他表檢索出來

  • 使用視圖可以重用SQL,并且可以保護(hù)數(shù)據(jù),可以授予用戶部分?jǐn)?shù)據(jù)權(quán)限而不是全部數(shù)據(jù)

  • 如視圖中存在分組(GROUP BY)、聯(lián)結(jié)、子查詢、并(UNOIN)、聚合函數(shù)(SUM/COUNT等)、計(jì)算字段、DISTINCT等都不能對視圖進(jìn)行更新操作

  • CREATE VIEW my_view AS SELECT name,score FROM student ,創(chuàng)建視圖

  • DROP VIEW MY_VIEW 刪除視圖

存儲過程

  • 有時(shí)候SQL也需要有IF ELSE,我們可以把多條SQL語句封裝在一起形成存儲過程,這樣不僅簡單安全而且性能也會更高

  • 存儲過程并不顯示結(jié)果,只是將結(jié)果返回給你指定的變量。

  • 過程是這樣的,創(chuàng)建一個(gè)存儲過程,使用存儲過程,將參數(shù)傳入,SELECT參數(shù)輸出結(jié)果

  • 參數(shù)類型 IN 傳遞給存儲過程,OUT從存儲過程傳出,INOUT對存儲過程傳入傳出。結(jié)果將返回給OUT變量

  • CREATE PROCEDURE pro(IN PARAM INT,OUT PARAM2 INT)BEGIN SELECT COUNT(*) FROM user WHERE id=PARAM INTO PARAM2 END; 創(chuàng)建存儲過程

  • CALL PRO (666,@PARAM2);SELECT @PARAM2;調(diào)用并且會輸出PARAM2

  • SHOW CREATE PROCEDURE PRO顯示存儲過程的CREATE語句

  • SHOW PROCEDURE STATUS列出所有存儲過程

觸發(fā)器

  • 事件發(fā)生時(shí)自動執(zhí)行某些語句,在INSERT UPDATE DELETE之前之后需要做一些操作,這時(shí)候可以使用觸發(fā)器

  • 一個(gè)表最多6個(gè)觸發(fā)器,插入刪除更新的前后。

  • CREATE TRIGGER my_trigger AFTER INSERT ON user FOR EACH ROW BEGIN SELECT NEW.id END,創(chuàng)建名為my_trigger的觸發(fā)器,在對user表,每插入一行,將id顯示出來

  • 在觸發(fā)器中可以引用NEW新的虛擬表,訪問插入的行。可以引用OLD虛擬表,訪問被刪除的行。

  • DROP TRIGGER my_trigger 刪除觸發(fā)器

  • 只有表支持觸發(fā)器,視圖不支持

  • 觸發(fā)器中不能調(diào)用存儲過程

我覺得分享是一種精神,分享是我的樂趣所在,不是說我覺得我講得一定是對的,我講得可能很多是不對的,但是我希望我講的東西是我人生的體驗(yàn)和思考,是給很多人反思,也許給你一秒鐘、半秒鐘,哪怕說一句話有點(diǎn)道理,引發(fā)自己內(nèi)心的感觸,這就是我最大的價(jià)值。(這是我喜歡的一句話,也是我寫博客的初衷)

http://www.cnblogs.com/-new/p/7229305.html