MySQL系列(一)---基礎知識大總結


MySQL系列(一)---基礎知識大總結

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

目錄

數據庫和數據庫軟件

  • 數據庫是保存有組織數據的容器
  • DBMS是為管理數據庫而設計的軟件管理系統,MYSQL、ORACLE 等是數據庫管理系統

MYSQL

  • MYSQL是一種數據庫管理軟件
  • 開放源碼,免費使用

MYSQL命令

  • CREATE DATABASE NAME 創建數據庫
  • USE DATABASE 選擇數據庫
  • DROP DATABASE NAME 直接刪除數據庫
  • SHOW DATABASES 顯示可用數據庫列表
  • SHOW TABLES 顯示數據庫中的表的列表
  • SHOW COLUMNS FROM TABLE 與 DESCRIBE TABLE 等效,顯示表的字段信息
  • SHOW GRANTS 顯示授予用戶的安全權限
  • SHOW ERRORS SHOW WARNINGS 顯示服務器錯誤和警告信息

SQL

  • STRUCTURED QUERY LANGUAGE 結構化查詢語言,一種專門用於與數據庫通信的語言
  • 不是DBMS專有的語言,很多DBMS都支持SQL,但是不同DBMS對SQL的實現不同
  • DBMS支持的SQL語法不能完全適用於其他DBMS
  • SQL語句不區分大小寫
  • 多條語句需要分號分隔,單條語句可以不用分號
  • 通常SQL語句用大寫,標識符(比如表名 列名 數據庫名)用小寫

創建表

  • 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,比如有兩行用戶名是一樣的,只顯示一行記錄

限制結果

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

結果排序

  • SELECT * FROM user ORDER BY username,以username的字母順序排列
  • SELECT * FROM user ORDER BY username,password ,如果username有相同的,那么username相同的再按password排列,如果username都是唯一,這個時候password不起作用
  • SELECT * FROM user ORDER BY username DESC ,降序排列,默認是升序ASC
  • SELECT * FROM user e ORDER BY username DESC,password 此時按照username降序排列,如果username相同的行按照password升序排列
  • SELECT * FROM user ORDER BY username LIMIT 1 混合使用ORDER 和 LIMIT
  • SELECT * FROM user WHERE username ='jiajun' ORDER BY password 這里ORDER要在WHERE 之后

過濾數據

  • 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' 執行順序是 WHERE id=1 OR (username='jiajun' AND password='666')AND的優先級更高,但是建議添加括號
  • SELECT * FROM user WHERE id IN (1,2) 效果和SELECT * FROM user WHERE id=1 OR id =2 如果要實現這種效果,建議使用第一種,語法更清晰,而且一般執行更快
  • SELECT * FROM user WHERE id NOT IN (1,2)

通配符過濾

  • SELECT * FROM user WHERE username LIKE 'jia%' ,匹配jia開頭的username,不管后面有多少字符,jia和jiajun都是匹配,可以配置MySQL是否區份大小寫,如果區份大小寫,也就是jiajun是不匹配的 。注意LIKE '%'是不能匹配值為NULL的
  • SELECT * FROM user WHERE username LIKE 'jia_' , _只能匹配一個字符,也就是匹配jiaj不匹配jiajun
  • 通配符匹配是效率不高,如果其他方式能有相同的效果,建議用其他效果,並且最好不要將通配符放在開始處,因為這樣是很慢的

正則表達式過濾

  • SELECT * FROM user WHERE username REGEXP '.ia' ,正則表達式, . 匹配任意一個字符
  • 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],用'-'表示范圍
  • 匹配特殊字符(比如'.'和'_')可以采用'\'轉義,比如匹配有'.'的可以這樣表示'\.'

拼接字段

  • SELECT CONCAT(username,'(',password,')') FROM user,將兩個字段拼接到一起,查詢結果是一列,行值 jiajun(666)
  • SELECT CONCAT(username,')',password,')') AS up FROM user,為拼接后的一列設置字段名

算數運算

  • SELECT price*count AS all FROM TABLE 將單價和數量相乘,列名為all

函數

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

文本處理函數

  • LENGTH() 返回串長度
  • LOWER()將串轉換為小寫
  • UPPER()將串轉換為大寫
  • LTRIM()去掉串左邊的空格
  • RTRIM()去掉串右邊的空格

日期和時間處理函數

  • CURDATE() 2017-07-22

  • CURTIME()16:20:19

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

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

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

  • HOUR() 返回一個時間的小時部分

  • MINUTE() 返回一個時間的分鍾部分

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

  • NOW() 返回當前日期和時間

  • SECOND() 返回一個時間的秒部分

  • TIME() 返回一個日期時間的時間部分

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

日期函數注意點

  • SELECT * FROM TABLE WHERE date='2017-7-22' ,如果DATE的類型是DATATIME類型,那么表里一條記錄存放的格式應該是2017-07-22 16:20:19,此時這條記錄不會被篩選出來,篩選的是2017-07-22 00:00:00
  • 可以采用DATE函數 SELECT * FROM TABLE WHERE DATE(date)='2017-7-22'
  • 時間范圍 可以采用DATE函數 SELECT * FROM TABLE WHERE DATE(date) BETWEEN '2017-7-1' AND ''2017-7-31

數組處理函數

  • ABS() 返回一個數的絕對值
  • COS() 返回一個角度的余弦
  • EXP()返回一個數的指數值
  • MOD()返回除操作的余數
  • PI() 返回圓周率
  • RAND()返回一個隨機數
  • SIN()返回一個角度的正弦
  • SQRT() 返回一個數的平方根
  • TAN() 返回一個角度的正切

聚集函數

  • SELECT AVG(student_score) AS AVG_ PRIVE FROM score 求平均值
  • SELECT COUNT(*) FROM TABLE 表里記錄數
  • SELECT COLUMN(name) FROM TABLE 表里列有值的記錄數 ,值為NULL不計數
  • SELECT MAX(score) FROM TABLE 查找最大值
  • SELECT MIN(score) FROM TABLE 查找最小值
  • SELECT SUM(count) FROM TABLE 返回指定列的和 SUM(price*count)同樣適用

數據分組

  • SELECT AVG(score) FROM score GROUP BY class_id 檢索不同課的平均分
  • SELECT AVG(score) FROM score GROUP BY class_id, dep_id ,GROUP BY 后面可以多個字段
  • SELECT AVG(score) FROM score GROUP BY class_id ,SELECT 的字段必須是GROUP BY 后面的字段或者是聚合函數,在這里根據class_id分最后,class_id相同合並成一行,但是這里面的合並的這些score不同,如何能合並成一行
  • 如果分組列有NULL值的,將列值為NULL的分為一組
  • GROUP BY 要在WHERE之后,ORDER BY 之前,也就是先過濾再分組再排序
  • SELECT COUNT(*) FROM TABLE GROUP BY id HAVING COUNT(*)>3 ,分組后,對分組再進行過濾。

子查詢

  • 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 計算字段字段使用子查詢
  • 不建議使用太多的子查詢,會影響性能

主鍵

  • 唯一標識自己的一列或一組列,唯一區別表中的一行
  • 主鍵不能為空
  • 任意兩行的主鍵值必須不同
  • 主鍵不是必須的,但是建議每個表中有一個主鍵,這樣操作管理更方便
  • 主鍵值最好不更新
  • 一個表的主鍵只能有一個

外鍵

  • 一個表的主鍵指向另一個表的外鍵,比如說student表的主鍵student_id,在score表中也有,並且是score表的外鍵
  • 外鍵保持了數據完整性和一致。,比如你在student表里面修改了student_id后,則score的student_id也會聯動更新。並且score表中插入的student_id必須是student表里有的

聯結

  • SELECT name,score FROM score,student 兩個表進行聯結,此時進行的是笛卡爾積,就是說結果的行數score表行數*student表的行數
  • SELECT name,score FROM score,student WHERE student.student_id=score.student_id,在上面的基礎上,加上WHERE進行過濾
  • SELECT name,score FROM score INNER JOIN student ON student.student_id=SOCRE.student_id 內部聯結
  • 外部聯結,LEFT OUTER JOIN 和 RIGHT OUTER JOIN ,有時候內部聯結的時候會出現聯結條件不匹配的行,而LEFT JOIN 保證了保證左邊表的所有行,右聯結同理
  • FULL JOIN效果LEFT JOIN + RIGHT JOIN一致,左表不匹配的右表不匹配的都會列出
  • 不要聯結太多的表,這樣會降低性能
  • 聯結的時候可能因為兩個表有相同的列,因為沒有做好限制導致相同的列的出現兩次,所以這是需要的地方,這也是所謂的自然聯結

別名

  • SELECT CONCAT(username,'(',password,')') AS MES FROM user,這里采用CONCAT將兩個字段拼接在一起,並且給拼接后的字段起一個別名MES
  • 同樣表也可以起別名SELECT name,score FROM score AS A,student AS B WHERE A.student_id=B.student_id

組合查詢

  • 利用UNION將多個SELECT語句的結果組合起來,可以理解成同一個表頭的表垂直拼接在一起
  • 每個查詢必須包含相同的列數,而且字段類型要兼容。
  • 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感覺復雜了,但是如果用於不同表的查詢的連接會更簡單。
  • 如果A查詢查到5行,B查詢查到4行,由於有重復的,會去掉相同的行,最后剩下8行,如果需要的話可以用UNION ALL

插入數據

  • INSERT INTO user VALUES ('jiajun','666') 和 INSERT INTO user (username,password) VALUES ('jiajun','666'),在表里只有username和password兩個字段是等效,前一種方式必須值的個數和順序必須和字段的個數順序一致,而后者,因為給出列和值,只要一一對應就好
  • INSERT INTO user VALUES ('jiajun','666'),('jiajia','666') 插入多行
  • INSERT INTO user VALUES (SELECT username ,password FROM olduser),檢索出olduser的行然后插入到user表,這里注意的還是列的問題,后面的SELECT語句后的字段名並不重要,不需要和user表對應,因為只是將檢索的列值按順序插入到user表,並不在意olduser的字段名。同時列的數目和順序也是需要注意的

更新數據

  • UPDATE user SET password ='666',money='6666' WHERE username='jiajun',需要注意的是WHERE一定不要漏,要不然會更新表中的所有行
  • 在更新多行的時候如果中途出現錯誤,會將更新的恢復回原來的值,如果要做到即使中途發生錯誤也要繼續更新可以采用 IGNORE關鍵字,UPDATE IGNORE user

刪除數據

  • 如果想刪除一個列的值,SET username=NULL就行了
  • 如果想要刪除一行,DELETE FROM user WHERE username='jiajun'
  • 如果想要刪除整個表的行 DETELTE FROM user,注意這個表不會刪除,只是所有記錄清空。TRUNCATE user,也有相同的效果,不同的是他是先刪除表,然后重新建立一個表

更新表

  • 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

視圖

  • 當我們查詢后出現一個結果,我們可以包裝成一個虛擬表,也就是視圖,我們可以把他當成表使用
  • 視圖本身不包含數據,數據是從其他表檢索出來
  • 使用視圖可以重用SQL,並且可以保護數據,可以授予用戶部分數據權限而不是全部數據
  • 如視圖中存在分組(GROUP BY)、聯結、子查詢、並(UNOIN)、聚合函數(SUM/COUNT等)、計算字段、DISTINCT等都不能對視圖進行更新操作
  • CREATE VIEW my_view AS SELECT name,score FROM student ,創建視圖
  • DROP VIEW MY_VIEW 刪除視圖

存儲過程

  • 有時候SQL也需要有IF ELSE,我們可以把多條SQL語句封裝在一起形成存儲過程,這樣不僅簡單安全而且性能也會更高
  • 存儲過程並不顯示結果,只是將結果返回給你指定的變量。
  • 過程是這樣的,創建一個存儲過程,使用存儲過程,將參數傳入,SELECT參數輸出結果
  • 參數類型 IN 傳遞給存儲過程,OUT從存儲過程傳出,INOUT對存儲過程傳入傳出。結果將返回給OUT變量
  • CREATE PROCEDURE pro(IN PARAM INT,OUT PARAM2 INT)BEGIN SELECT COUNT(*) FROM user WHERE id=PARAM INTO PARAM2 END; 創建存儲過程
  • CALL PRO (666,@PARAM2);SELECT @PARAM2;調用並且會輸出PARAM2
  • SHOW CREATE PROCEDURE PRO顯示存儲過程的CREATE語句
  • SHOW PROCEDURE STATUS列出所有存儲過程

觸發器

  • 事件發生時自動執行某些語句,在INSERT UPDATE DELETE之前之后需要做一些操作,這時候可以使用觸發器
  • 一個表最多6個觸發器,插入刪除更新的前后。
  • CREATE TRIGGER my_trigger AFTER INSERT ON user FOR EACH ROW BEGIN SELECT NEW.id END,創建名為my_trigger的觸發器,在對user表,每插入一行,將id顯示出來
  • 在觸發器中可以引用NEW新的虛擬表,訪問插入的行。可以引用OLD虛擬表,訪問被刪除的行。
  • DROP TRIGGER my_trigger 刪除觸發器
  • 只有表支持觸發器,視圖不支持
  • 觸發器中不能調用存儲過程

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

作者:jiajun 出處: http://www.cnblogs.com/-new/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。如果覺得還有幫助的話,可以點一下右下角的【推薦】,希望能夠持續的為大家帶來好的技術文章!想跟我一起進步么?那就【關注】我吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM