MySQL開發總結

1、理解MySQL基本概念mysql

  一、MySQL軟件:MySQL實際上就是一軟件,是一工具,是關係型數據庫管理系統軟件linux

  二、MySQL數據庫:就是按照數據結構來組織、存儲和管理數據的倉庫sql

  三、MySQL數據庫實例shell

    ①MySQL是單進程多線程(而oracle是多進程),也就是說MySQL實例在系統上表現就是一個服務進程,即進程;數據庫

    ②MySQL實例是線程和內存組成,實例纔是真正用於操做數據庫文件的;windows

  通常狀況下一個實例操做一個或多個數據庫;集羣狀況下多個實例操做一個或多個數據庫。安全

 

2、MySQL數據庫啓動以及啓動的判斷服務器

  一、啓動MySQL數據實例:session

    shell> service mysqld start  #rpm包安裝的mysql數據結構

  若是是源碼安裝的話,推薦使用mysqld_safe命令的安全啓動(能夠看到啓動信息)。

  二、判斷MySQL數據庫是否啓動:

    shell> netstat -tulnp|grep 3306  #若是能夠過濾出來(有輸出)證實已啓動

    shell> mysqladmin -uroot -p123 ping  #出現mysqld is alive證實是活躍的

 

3、如何使用官方文檔和help

  一、基本技能:DBA全部的操做必須來自於官方文檔

  二、mysql> help contents;  #尋求help幫助的入口

 

4、官方文檔概覽

  一、Tutorial:將MySQL經常使用的一些操做使用一個場景串聯起來

    只是關注裏面的灰色部分就能夠,按照裏面的灰色操做部分順一遍

  二、server Administrator:MySQL管理須要的一些命令、工具、參數等

  三、SQL Syntax

    SQL語法,使用最多,特別是DDL語句必定要使用SQL語法進行參考

  四、Server Option / Variable Reference:MySQL的參數和狀態值,使用較多

  五、Functions and Operators

    MySQL經常使用函數和操做符,使用較多

  六、Views and Stored Programs

    視圖、存儲過程、函數、觸發器、event語法參考

  七、Optimization:優化

    很是值得細緻的看一遍,此篇文檔不只僅用來參考,更多的是用來學習優化知識,算是DBA進階寶典

  八、Partitioning

    若是是要進行表分區,此文檔是必須參考的資料,也是惟一參考的資料

  九、Information Schema、Performance Schema

    中級DBA經常使用的兩個參考資料

  十、Spatial Extensions

    地理位置信息

  十一、Replication

    MySQL使用複製功能,經常使用的參考資料

  十二、Semisynchronous Replication

    半同步複製,個別場合會用到

 

5、如何使用官方文檔

  一、參考官方文檔修改密碼強度(下降密碼強度)、修改密碼

  ①改密碼強度:

    mysql> show variables like 'validate_password%';

    mysql> SET GLOBAL validate_password_policy=0;

  ②修改密碼:set、alter

  二、參考官方文檔查詢當前數據庫鏈接的數量(查詢狀態值Threads_connected)

    mysql> show status like '%Threads_connected%';

    注意:查看狀態值是show status

          查看變量值是show variables

  三、創建一個數據庫指定字符集

    mysql> create database test_db character set utf8;

  四、給一個表增長一個列,要求這個列的數據類型是字符串、非空(alter)

    ALTER TABLE tbl_name ADD COLUMN col_name varchar(20) not null;

  五、用函數將兩個字符串串聯起來(concat:合併多個字符串)

    CONCAT():returns NULL if any argument is NULL.

    CONCAT_WS(separator,str1,str2,...)

  六、mysqladmin的使用:類同於ping數據庫是否活躍、關閉數據庫

    shell> mysqladmin -uroot -p123 ping

    mysqld is alive

    shell> mysqladmin -uroot -p123 shutdown

  七、如何啓動數據庫:mysqld_safe命令(切記掛後臺&,不然佔領當前會話沒法退出)

    shell> mysqld_safe --defaults-file=/etc/my.cnf &

官方文檔對於具備必定基礎知識的人來講,是一個最合適的工具,可使DBA的操做變得沒有障礙     

 

6、登陸MySQL查看當前會話的狀態

  mysql> status

 

7、描述MySQL在Linux平臺下的大小寫、同時演示大小寫的區別

  一、數據庫名、表名、表別名嚴格區別大小寫

  二、列名、列別名忽略大小寫

  三、變量名嚴格區別大小寫

  四、MySQL在windows下各個對象都不區別大小寫

mysql> show variables like 'lower%'; +------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| lower_case_file_system | OFF   |
| lower_case_table_names | 0     |
+------------------------+-------+

  ①lower_case_file_system是對實際的文件系統的反應,爲只讀變量,不能修改。Off表示MySQL所在的文件系統大小寫敏感,也就是說進入MySQL所在的文件系統查看裏面的內容,發現有mysql文件夾,此時新建一個名爲MYSQL的文件夾是能夠的,說明大小寫敏感。

  ②lower_case_table_names表示表名或數據庫存儲是否區別大小寫,爲只讀變量,能夠在配置文件my.cnf裏面修改:

    0表示區分大小寫,按照新建數據庫的大小寫形式存儲顯示;

    1表示不管新建數據庫大小寫都以小寫的形式存儲顯示。

 

8、MySQL的幾種幫助

  一、shell> mysql --help

  二、mysql> help show

    mysql> show create table tel_name

    mysql> help set

 

9、MySQL的變量如何查看,如何修改

  一、查看變量用select

    局部變量select var_name;

    用戶變量select @var_name;

    全局變量select @@var_name;

  二、修改變量用set

SET variable_assignment [, variable_assignment] ... variable_assignment:   user_var_name = expr  #變量名字=一個值   |[GLOBAL | SESSION] system_var_name = expr   |[@@global. | @@session. | @@]system_var_name = expr

  ①set global表示修改後對所有會話生效,爲全局修改變量

  ②set session表示修改後對本次會話生效

  ③若是變量是隻讀變量能夠經過修改MySQL的配置文件my.cnf來修改變量,在[mysqld]下添加一行數據:user_var_name=expr,而後重啓數據庫再登陸便可。

 

10、MySQL的狀態參數如何查看、如何參考閱讀其內容

  在官方文檔的Server Option / Variable Reference部分,進行參考查看MySQL的參數變量以及狀態值

  一、cmd-line表示可否在mysql安全啓動(mysqld_safe)中進行參數設置 --var_name=……

  二、option file表示可否在mysql的參數文件中進行參數設置

  三、system var表示是不是系統變量

  四、status var表示是不是狀態變量

  五、var scope表示變量的範圍:全局global、會話session

  六、dynamic表示是不是動態參數,yes是動態,no是靜態

 

11、如何查看某個數據庫裏面有多少表、每個表的列的信息

  一、show tables;  desc tbl_name;

  二、mysql> select * from information_schema.TABLES

      -> where TABLE_NAME='tbl_name'\G;

  ①information_schema數據庫:也稱爲數據字典,記錄了各數據庫的表、視圖、索引、存儲過程、函數等信息……

  ②information_schema.TABLES:記錄了MySQL中每個數據庫中表所在的數據庫、表的名字、表的行數等信息。

 

12、如何查看一個表的建表語句、一個數據庫的建庫語句

  一、show create table tbl_name;

  二、show create database db_name;

 

十3、如何查看MySQL支持的數據類型以及數據類型如何使用

  mysql> help contents;

  mysql> help data types;

  mysql> help ……

 

十4、列舉show命令經常使用的語法

  一、show status like …… 查看狀態值

  二、show variables like …… 查看變量參數值

  三、show create …… 查看建表、庫……的語句信息

  四、show procedure status where db='db_name'\G;  #查看存儲過程信息

  五、show warnings\G;  #查看警告信息

 

十5、help kill如何使用

  mysql> help kill

    KILL [CONNECTION | QUERY] processlist_id

注:Thread processlist identifiers can be determined from the ID column of the INFORMATION_SCHEMA.PROCESSLIST table。

  mysql> select * from INFORMATION_SCHEMA.PROCESSLIST\G;

 

十6、描述MySQL用戶名組成以及特色

  一、MySQL用戶身份識別認證:用戶名user、密碼password、登陸mysqld主機host

  shell> mysql -uroot -p123 -h172.16.11.99

    -u:登陸的用戶名

    -p:登陸用戶對應的密碼

    -h:MySQL服務器主機IP,默認是localhost的IP

  二、MySQL的用戶管理模塊的特色客戶端請求鏈接,提供host、username、password,用戶管理模塊進行驗證請求鏈接,經過mysql.user表進行校驗信息

 

十7、如何查看MySQL有多少用戶以及對應的權限

  一、mysql> select count(*) from mysql.user;  #查看MySQL有多少用戶

  二、mysql> select * from mysql.user\G;  #用戶信息查詢(權限)

 

十8、創建一個用戶

  一、本地登陸

    mysql> create user 'u1'@'localhost' identified by '123';

  二、任意均可以登陸

    mysql> create user 'u2'@'%' identified by '123';

  三、某一個網段能夠登陸

    mysql> create user 'u3'@'172.16%' identified by '123';

  四、具體主機能夠登陸

    mysql> create user 'u4'@'172.16.12.24' identified by '123';

 

十9、使用help grant,給用戶賦權

 

二10、創建一個db1數據庫的只讀用戶

  建用戶而後受權

  mysql> GRANT SELECT ON db1.* TO 'olr_user'@'%';

 

二11、創建一個只能進行系統狀態信息查詢的管理用戶

  mysql> grant select on information_schema.* to 'admin_user'@'%';

 

二12、創建一個db1的生產用戶,只能進行dml、select,不能進行ddl

  mysql> grant select,insert,update,delete on *.* to 'pro_user'@'%';

 

二十3、創建一個能夠進行DDL的管理用戶

  mysql> grant create,drop,alter on *.* to 'admin_user'@'%';

 

二十4、創建一個工資表,只有指定的用戶能夠訪問工資列,其餘用戶都不能訪問工資列

  實現步驟:

    先在mysql.user裏將全部用戶檢索出來,進行跑批處理(腳本或存儲過程)revoke對該表列的權限;

    而後grant建立用戶,並對該表列賦訪問權限。 

 

二十5、查詢上述用戶以及所賦權限是否正確,同時進行驗證

  mysql> select * from mysql.user\G;  #查看MySQL用戶信息

  進行用戶登陸驗證

 

二十6、解釋with grant option,而且演示其功能

  mysql> grant all on *.* to 'zhang'@'%' identified by '123' with grant option;

  with grant option子句經過在grant語句的最後使用該子句,就容許被受權的用戶把獲得的權限繼續授給其餘用戶。也就是說,客戶端用zhang用戶登陸MySQL,能夠將zhang用戶有的權限使用grant進行受權給其餘用戶。

 

二十7、查詢某一個表上的權限、查看某一個列上的權限、查看某一個數據庫上面的權限

  一、 查詢全部數據庫的權限

    mysql> select * from mysql.user;

  二、 查詢某個數據庫的權限

    mysql> select * from mysql.db;

  三、 查詢某個數據庫中某個表的權限

    mysql> select * from mysql.tables_priv;

  四、 查詢某個數據庫某個表中某個列的權限

    mysql> select * from mysql.columns_priv;

 

二十8、修改參數運行使用grant創建用戶,修改參數禁止grant創建用戶

mysql> show variables like 'sql_mode%'; +---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                     |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.37 sec)

sql_mode參數中的NO_AUTO_CREATE_USER值:不自動建立用戶

  mysql>set @@session.sql_mode=……;   #設置sql_mode參數

 

二十9、修改mysql的用戶密碼,分別使用grant、alter、set修改

  ①mysql> grant all on *.* to '用戶名'@'登陸主機' identified by '密碼';

  ②mysql> alter user '用戶名'@'登陸主機' identified by '密碼(自定義)';

  ③mysql> SET PASSWORD FOR '用戶名'@'登陸主機' = PASSWORD('密碼');

 

三10、破解密碼步驟:

  ①到/etc/my.cnf 裏將 validate_password=off 行註釋  //關閉密碼策略

  ②shell> mysqld_safe --skip-grant-tables &  //重啓數據庫

  ③shell> mysql -uroot  //無密碼登陸

  ④mysql> flush privileges;  //刷新權限使密碼生效

  ⑤修改密碼,退出,重啓數據庫,進入

 

三11、使用revoke進行權限的收回,將上面用戶的受權分別收回,同時查看收回後的結果

  ①REVOKE INSERT ON *.* FROM 'jeffrey'@'localhost';

  ②REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...

 

三12、select最簡單經常使用語法

  一、全表查詢

    select * from tbl_name;

  二、某些行查詢

    select * from tbl_name where ……;

  三、某些列查詢

    select clm_name from tbl_name;

  四、某些行的某些列查詢

    select clm_name from tbl_name where ……;

  五、列別名

    select clm_name as new_name from tbl_name;

  六、列運算

    select clm_name+123 from tbl_name;

 

三十3、concat函數的使用

  一、concat函數:將多個字符串參數首尾相連後返回

  二、concat_ws函數:將多個字符串參數以給定的分隔符,首尾相連後返回

  三、group_concat:函數的值等於屬於一個組的指定列的全部值,以逗號隔開,而且以字符串表示

 

三十4、演示打開和關閉管道符號「|」的鏈接功能

  PIPES_AS_CONCAT:將「||」視爲字符串的鏈接操做符而非或運算符

  || 管道鏈接符:

    mysql> select  列名1 || 列名2 || 列名3   from   表名;

  在mysql中,進行上式鏈接查詢以後,會將查詢結果集在一列中顯示,列名是‘列名1 || 列名2 || 列名3’

mysql> select s_no || s_name || s_age -> from student; +-------------------------+
| s_no || s_name || s_age |
+-------------------------+
| 1001張三23              |
| 1002李四19              |
+-------------------------+

  若是不顯示結果,是由於sql_mode參數中沒有PIPES_AS_CONCAT,只要給sql_mode參數加入PIPES_AS_CONCAT,就能夠實現像CONCAT同樣的功能;

  若是不給sql_mode參數加入PIPES_AS_CONCAT的話,|| 默認是or的意思,查詢結果是一列顯示是1。

 

三十5、使用mysql> help functions; 學習MySQL各種函數

 

三十6、常見功能函數

  一、upper(……)、lower(……)大小寫變換

  二、user()查看登陸用戶、current_user()查看當前用戶

  三、database()查看使用的數據庫

 

三十7、使用help來學習下面的數據類型(創建對應類型的列、插入數據、顯示數據)

  一、整數:int

  二、非負數:unsigned無符號即非負數---e.g:int unsigned

  三、小數:dec

  四、浮點數以及科學計數法:float、double

  若是FLOAT數據在插入的時候,要使用NeM(科學計數法)的方式插入時:

  好比

    5e2 就是5*10的2次方

    5e-2就是5*10 的-2次方

    4e-1+5.1e2 就是510.4

  五、字符串:varchar

  六、布爾:bool、boolean---synonyms(同義詞):TINYINT(1)

  七、位:bit

    如何使用16進制常量:hex()

    如何使用2進制常量:bin()

  date類型以及STR_TO_DATE函數

  time類型以及STR_TO_DATE函數

  dateime數據類型以及標準寫法、STR_TO_DATE函數

  date和time顯示方式以及date_format函數

 

三十8、時區

  一、查看操做系統時區、數據庫時區

  查看操做系統時區:

    shell> cat /etc/sysconfig/clock

    ZONE="Asia/Shanghai"

    shell> ls /usr/share/zoneinfo

    ……

    mysql> show variables like 'system_time%';  #查看MySQL系統時區

    mysql> show variables like 'time_zone%';  #查看數據庫時區

  二、修改數據庫時區爲東八區,去掉數據庫時區對os時區的依賴(查看官方文檔)

  加載系統時區:將Linux時區導入到數據庫中

    shell> mysql_tzinfo_to_sql /usr/share/zoneinfo |mysql -uroot -p123 mysql

    mysql> set @@global.time_zone='Asia/Shanghai'; 

  修改數據庫時區爲東八區,同時在參數文件中進行修改,永久保存

  三、時區在何時有用:

  若是數據庫裏面沒有timestamp這個數據類型,那麼時區參數沒有意義!

  你如何確認你的數據庫裏面是否有timestamp類型的列?

mysql> select table_name,column_name,data_type -> from information_schema.columns     -> where data_type='timestamp';

……

  時區原理描述:insert過程和select過程的描述:相對應的0時區的轉換

  四、時區的正確實踐(timestamp)

    insert之前:你的values對應的時間究竟是哪一個時區,而後設置set @@session.time_zone爲對應的時區

    select獲取之前:你想獲得什麼時區的時間,就設置set @@session.time_zone爲對應的時區

 

三十9、字符集

  一、查看服務器的字符集

    mysql> show variables like 'character_set_server';

  二、查看數據庫字符集

    mysql> show variables like 'character_set_database';

  通常在數據庫實現字符集便可,表和列都默認採用數據庫的字符集

  gbk

  utf8

  三、查看錶的字符集、查看列的字符集

    mysql> show create table tbl_name;

  四、字符集原理描述、字符集正確實踐

  對於insert過程描述、對於select過程描述

    ①對於insert來講,character_set_client、character_set_connection相同,並且正確反映客戶端使用的字符集

    ②對於select來講,character_set_results正確反映客戶端字符集

    ③數據庫字符集取決於咱們要存儲的字符類型

    ④字符集轉換最多發生一次,這就要求character_set_client、character_set_connection相同

    ⑤全部的字符集轉換都發生在數據庫端 

總述:

  1)創建數據庫的時候注意字符集(gbk、utf8)

  2)鏈接數據庫之後,不管是執行dml仍是select,只要涉及到varchar、char列,就須要設置正確的字符集參數:

    character_set_client、character_set_connection、character_set_results

  五、客戶端字符集如何來理解?

  取決於客戶端工具

    shell> mysql -uroot -p123456 -hserver_host -P3306

  mysql工具自己沒有字符集,所以客戶端字符集取決於工具所在的os的字符集(windows:gbk、linux:utf8)

  sqlyog工具自己帶字符集,此時客戶端os字符集就沒有意義

  六、如何判斷字符集出現了問題?

  全部設置都正確,可是查詢到的仍是亂碼,這就是出現問題了

 

四10、如何識別變量參數、狀態參數status var

  show variables……

  show status……

  識別判斷都是查看官方文檔System Var、Status Var

 

四11、如何識別動態參數、靜態參數

  動態參數dynamic:Yes

  靜態參數dynamic:No

 

四12、對於動態參數如何設置,如何判斷動態參數是否能夠在全局級別或者會話級別修改

  一、set

  二、修改參數文件/etc/my.cnf:弊端是須要重啓才能生效(不多用)

判斷:參考官方文檔Option/Variable Summary,經過Var scope來進行判斷動態參數的全局global、both

 

四十3、對於靜態參數如何修改

  靜態參數,在整個實例聲明週期內都不得進行更改,就好似是隻讀的;

  通常靜態參數都是在配置文件中修改/etc/my.cnf,固然靜態參數可否寫入配置文件還要看官方文檔對該參數的Option File的描述Yes與否。

 

四十4、掌握@@、@的區別

  一、@@var_name表示的系統變量

    根據系統變量的做用域可分:全局變量、會話變量

  二、@var_name表示的用戶變量

    ①用戶變量和數據庫鏈接有關,鏈接後聲明變量,鏈接斷開後,自動消失;

    ②select一個沒有賦值的用戶變量,返回NULL,也就是沒有值;

  Mysql的變量相似於動態語言,變量的值隨所要賦的值的類型而改變。

 

四十5、set @@session.和set @@global.的生效時間

  對於一個新創建的鏈接,只有全局變量,會話變量還不存在,這個時候會從全局變量拷貝過來。

  一、set @@session.:只對當前鏈接起做用

  二、set @@global.:對全局變量的修改會影響到整個服務器

注意:set系統變量時,不帶做用域修飾,默認是指會話做用域

  (特別注意,有些系統變量不帶做用域修飾,沒法設置,所以最好都帶上做用域設置系統變量)。

 

四十6、動態參數最佳實踐

  一、儘可能先進行會話級別的設置set @@session,確認生效並且效果不錯之後,再進行全局設置,若是須要立刻生效,殺掉全部的會話:

    mysql> select concat('kill ',conn_id,';') from sys.session;

  二、確認沒有問題之後,修改參數文件,下次系統啓動一直生效。

 

四十7、select書寫技巧

  一、確認須要訪問數據來自於哪幾張表

    from來自某張表或者某幾張表

    join添加某張表

    on錶鏈接條件

  記住一點:每關聯一個表就須要加上對應的on條件(on條件就是主外鍵條件)

  二、經過where條件來過濾數據

  三、確認需求裏面是否有分組聚合的含義

    分組:group by

    聚合:聚合函數

    聚合條件過濾:having

  四、是否須要排序

    order by

 

四十8、MySQL內置函數(將列出的常見的一些函數熟悉過一遍)

  一、內置函數的多少是一個數據庫是否成熟的標誌

  二、學會使用help Functions學習和使用函數(重點!!!!!!!!!!!)

  三、經常使用函數要過一遍

    ①日期時間相關的函數

    CURDATE、DATEDIFF、DATE_FORMAT、DAYOFWEEK、LAST_DAY、EXTRACT、STR_TO_DATE

    ②比較操做符要求都過一遍,help Comparison operators;

    ③流程控制行數help Control flow functions;

    ④加密函數help Encryption Functions;

      只須要看看decode、password兩個函數便可

    ⑤信息獲取函數help Information Functions;

      經過這些函數能夠知道一些信息,過一遍便可

    ⑥邏輯操做符help Logical operators;

      !、and、or,這些經常使用的要過一遍

    ⑦雜項函數help Miscellaneous Functions;

      簡單瀏覽一下里面的函數,對於名字有個印象便可

    ⑧數值函數help Numeric Functions;

      使用數據庫來進行數學運算的狀況很少,經常使用的加減乘除、TRUNCATE、ROUND

    ⑨字符串函數help String Functions;

    CONCAT、CONCAT_WS、CAST、FORMAT、LIKE、REGEXP、STRCMP、TRIM、SUBSTRING、UPPER,其它函數名字過一遍

  四、聚合分組函數的使用瞭解

    ①select後面得列或者出如今group by中,或者加上聚合函數

select c1,c2,sum(c3),count(c4) from t1 group by c1,c2;

    ②help contents;

    查看聚合函數help Functions and Modifiers for Use with GROUP BY;

    AVG、MAX、MIN、SUM、COUNT、COUNT DISTINCT、GROUP_CONCAT、BIT_AND、BIT_OR、BIT_XOR

 

四十9、隱式類型轉換,要避免隱式類型轉換

  一、最經常使用的幾個數據類型:數字、字符串、日期時間

  二、字符串裏面能夠存放數字和日期,可是在設計表的時候,要注意不要將日期和數字列設計成字符串列

  三、對於字符串列的比較,必定要加上引號:

    mysql> select * from t where name_phone='1301110001';

 

五10、limit使用很頻繁,注意其使用方法

  一、limit使用的場合

    從結果集中選取最前面或最後面的幾行

  二、limit配合order by使用

  三、MySQL5.7 doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

 

五11、in、not in、exists、not exists、left join、distinct join互相轉換

  一、in和exists能夠互相轉換

select * from players a where a.teamno in (select teamno from team where teamname='騎士隊'); select * from players a where exists (select 1 from team b where a.teamno=b.teamno and b.teamname='騎士隊');

  二、not in和not exists能夠互相轉換

  三、not in、not exists能夠轉換成left join

select * from 學生信息 a where a.stuno not in (select stuno from 選課信息表); select * from 學生信息 a left join 選課信息 b on a.stuno=b.stuno where b.成績 is null;

  四、in、exists能夠轉換成distinct join

select * from 學生信息 a where a.stuno in (select stuno from 選課信息表 b); select * from 學生信息 a where exists (select 1 from 選課信息 b where a.stuno=b.stuno); select distinct a.*
from 學生信息 join 選課信息 b on a.stuno=b.stuno;

 

五12、鏈接的具體使用含義

  一、理解爲何會出現錶鏈接:查詢的列來自於多個表

selectfrom .. where 列 group by 列 having 列 order by 列 limit x

  二、理解錶鏈接的書寫方式

    join一個表、on一個條件

  三、理解錶鏈接的注意條件

    ①兩個表要鏈接必定要存在主外鍵關係(有可能須要第三張表協助關聯)

      實際上存在外鍵約束

      存在外鍵列,可是沒有外鍵約束

    ②防止扇形陷阱(兩個表須要關聯,可是沒有直接主外鍵,藉助第三個表進行關聯,可是存在扇形問題,此時不能借助第三個表進行關聯)

    示例:學院表、專業表、學生表

      學院實體和專業實體之間是一對多的聯繫;

      學院實體和學生實體之間也是一對多的聯繫;

      而學生和專業之間沒有聯繫;

    若是學生和專業經過學院表進行關聯,就會出現扇形問題。

  四、外鏈接:左外鏈接、右外鏈接

    外鏈接是爲了防止出現某一個表的數據被遺漏

    開發人員很是喜歡使用外鏈接.

 

五十3、子查詢

  一、子查詢可能出現的位置

    ①select from之間可能會出現子查詢

    ②from後面

    ③join後面可能會出現子查詢

    ④where後面可能會出現子查詢

    ⑤having後面可能會出現子查詢

  二、盡最大程度的不要使用子查詢

  三、相關子查詢、無關子查詢

    相關子查詢特別容易出如今select from之間、where後面

    相關子查詢不能獨立執行,子查詢執行次數取決於父查詢返回的行數

    無關子查詢能夠獨立執行,子查詢執行一次

 

五十4、子查詢出現的場合

  一、where中出現的子查詢,通常可以使用錶鏈接進行改寫

    ①select 列(涉及到A表,沒有涉及到B表)

    ②where 條件(涉及到B表)

  二、from後面的子查詢

    ①對於取出來的數據再次進行復雜的處理

      例如分組聚合、having條件、where條件

    ②對一個結果集再次進行復雜的查詢

    意味着咱們取數據的這個過程當中,對數據進行處理的力度很複雜

  三、select from之間的子查詢

    對於返回的每一行數據,select和from之間的子查詢都要執行一次

    select後面的列要進行復雜的處理,若是這個處理涉及到另一個表,若這個表極可能沒有出如今from和join裏面,則進行子查詢:

示例:將每個同窗的成績列出來,同時計算他的成績和本組平均成績的差距

select 學生成績, 學生成績-(select avg(成績) from 選課表 a  where a.組ID=b.組ID) from 選課表 b;

 

五十5、select執行的順序

select ... from ... join ... on ... where ... group by .. having ... order by ...

  一、先從表中取數據,訪問innodb buffer pool

    from ...

    join ...

    on ...

    where

  二、分組、聚合,數據已經進入用戶工做空間

    group by ...

    having ...

  三、select ....:取列數據

  四、order by:排序輸出

 

五十6、集合操做

  union:結果集去重

  union all:結果集不去重

 

五十7、insert增

  一、insert values一條數據

    表的名字後面最好加上列的名字

  二、insert values多條數據

  三、insert into select

    select能夠很是複雜,語法徹底就是select

 

五十8、update改

  基本格式:update 一個表 set 列 where 列條件;

  一、必定要帶上where條件

  二、update分爲下面的幾個步驟操做

    ①找到須要update的數據,此操做取決於where條件

    where條件能夠是一個複雜的where條件,好比是一個子查詢

示例:將平均成績75分以上的學生的級別設置爲優等生

update 學生信息表 a set grade=‘優等生’ where a.stuno in (select b.stuno from 成績表 b group by b.stuno having avg(成績)>=75);

    ②set後面的列,也能夠很複雜,好比是一個相對子查詢

UPDATE players_data pd SET number_mat = (     SELECT count(*)     FROM matches m     WHERE m.playerno = pd.playerno),   sum_penalties = (     SELECT sum(amount)     FROM penalties pen     WHERE pen.playerno = pd.playerno);

  三、update能夠改寫成一個select語句

    把1和2改寫成一個select語句,不要對一個update在生產裏面直接進行優化

  四、update可使用order by,數據按照順序進行更新

  五、update可使用limit,限制每次更新的行數

 

五十9、replace替代已有的行

  使用場合insert+update,兩個表數據合併到一塊兒

 

六10、delete刪

  一、絕大多數狀況下須要加上where條件

  二、where條件能夠很複雜,例如是一個子查詢

  三、理解delete和truncate的區別

    truncate:清空所有數據、速度快、釋放空間(不刪表)

    delete:所有或者部分刪除數據、速度慢、不釋放空間

 

六11、臨時表

  一、只是針對當前會話有效,臨時表和數據都存儲在用戶工做空間

  二、臨時表的使用很消耗資源

    ①create、insert、drop,所以在很是頻繁的查詢環境下,不宜使用臨時表;

    ②臨時表須要使用用戶工做空間,臨時表中存在的數據不易過多,不然容易出現磁盤臨時表;

  三、臨時表的使用場合

    須要暫存結果集數據,後面的操做須要訪問這些暫存結果集,主要是爲了可讀性。

  四、有一種誤區必定要注意,必定不要將普通表做爲臨時表來使用

  緣由:普通表當作臨時表來使用,下面的操做須要手工去作

    ①create、insert、truncate或者drop

    ②對於普通表的全部操做都會產生redo(事務),很是消耗資源

 

六12、關於約束

  一、非空

  二、default約束

  三、主鍵約束

  四、外鍵約束

  五、SET、ENUM約束

約束注意點:

  ①儘可能選擇列都爲非空

  ②對於bool、時間列常常會出現default約束

  ③每個表盡最大程度要有主鍵

  ④惟一鍵能夠有多個,惟一鍵能夠有空值

  ⑤外鍵列通常會有,可是外鍵約束不建議使用,在應用層面保證主表和外表的一致性

  ⑥合理使用set和enum約束,提高數據的質量

  ⑦外鍵約束中on delete、update,儘可能不要設置級聯刪除操做(很危險!!!)

 

六十3、表的DDL

  一、極其嚴肅的一個動做

  二、使用help書寫DDL語句

  三、ddl動做的後遺症和危險性

    ①影響I、D、U、S

    ②長時間鎖表、產生海量IO

  四、測試DDL的影響範圍---優化對象

    ①鎖表時間

    ②IO狀況

    ③具體測試要求

示例:產生一個500萬行的表(寫一個存儲過程實現),對錶進行增長列、刪除列、修改列的名字、將列的長度變長、將列的長度變短

mysql> delimiter $$ mysql> create procedure do_big(x int) -> begin ->   declare v int; ->   set v=x; ->   create table test(test_num int auto_increment not null primary key); ->   while v>0 do
    ->     insert into test values(null); ->     set v=v-1; ->   end while; -> end $$ mysql> delimiter ; mysql> call do_big(5000000); …… mysql> select count(*) from test; +----------+
| count(*) |
+----------+
| 5000000 |
+----------+

  看一下上面的這些操做,哪些操做時間長、哪些操做時間短,並對其進行初步的原理分析

mysql> insert into test values(123456789); mysql> delete from test where test_num=123; mysql> alter table test CHANGE COLUMN -> test_num -> test_id  int(10) not null auto_increment; mysql> alter table test modify test_id int(100); mysql> alter table test modify test_id int(20);

總結:對於一個大表而言,將列的長度變長時間是最長的,其餘的操做處理時間都還挺短。

 

六十4、視圖的最佳實踐

  一、視圖就是select的一個名字

  二、不建議使用複雜視圖

    select語句裏面不要帶有distinct、group by、聚合函數、union等操做

  三、不建議在視圖中嵌套視圖

  四、視圖的主要使用場合

    統一訪問接口(select)---主要的好處

    規範訪問

    隱藏底層表結構、ddl不影響應用訪問

  五、視圖在安全方面的意義

 

六十5、存儲過程(腳本)

  一、存儲過程使用的場合

    ①重複性很高的複合操做(dml)

    ②統一訪問接口(dml、事務)

    ③批量業務(跑批)

  二、存儲過程結構分析

    ①存儲過程當中嵌入了dml、select

    ②存儲過程有參數,參數的不一樣會產生不一樣的事務

      in、out、inout

    ③存儲過程裏面有結構化語句,即流程控制語句:

      循環

      條件判斷

    使得在執行dml、select的時候,變得方便

    ④存儲過程能夠定義變量

      select取出來的結果能夠存儲到變量中

      dml須要的輸入值能夠經過變量來實現

    ⑤存儲過程裏面能夠有遊標,遊標的核心就是能夠對一個結果集進行處理

      1)定義遊標(遊標和一個select關聯)

      2)打開遊標(將select的結果賦給遊標,能夠是N行列)

      3)遍歷遊標(一行行數據獲取,每一行數據賦給N個變量)

      4)關閉遊標

    ⑥存儲過程有異常處理部分

      1)異常處理是一個存儲過程是否能夠產品化、商業化很重要的一個標誌

      2)異常處理只關心SQL語句的異常

    每個存儲過程都要對着三類SQLWARNING、NOT FOUND、SQLEXCEPTION進行處理;

    存儲過程異常處理一般只是進行錯誤的記錄,或者空處理。

    ⑦存儲過程書寫過程

      1)定義一個結構

        存儲過程基本結構

        參數

        異常處理

      2)書寫涉及到SQL語句

      3)考慮使用變量、遊標、條件判斷、循環將SQL語句組合起來

      4)常用begin end來將一組SQL語句或者語句組合起來,做爲一個語句來出現

  三、存儲過程安全方面的意義:防止對底層表直接進行dml

 

六十6、自定義函數

  一、自定義函數和存儲過程的區別

  ①有一個返回值

CREATE FUNCTION SimpleCompare(n INT, m INT) RETURNS VARCHAR(20) ……

  ②調用的時候必須放在=的右邊

    set @ax = SimpleCompare(1,2);

  二、整理筆記,將函數定義和函數調用整理一個例子出來

 

六十7、觸發器

  一、儘可能少使用觸發器,不建議使用

  二、觸發器是一個begin end結構體

  三、觸發器和存儲過程的惟一區別就是在於被執行方式上的區別

    存儲過程須要手工去執行

    觸發器被DML自動觸發

  四、觸發器被觸發的條件

    ①for each row(每一行都被觸發一次,這就決定了頻繁dml的表上面不要有觸發器)

    ②增刪改均可以定義觸發器

    ③before、after能夠定義觸發的時機

  五、觸發器中常常使用new、old

    insert裏面能夠有new

    delete裏面能夠有old

    update裏面能夠有new、old

  六、使用觸發器的場合

  通常用來進行審計使用:產品價格表裏面的價格這個列,只要是有人對這個表的這個列進行更新,就要保存修改前和修改後的值,將這個信息記錄到一個單獨的表中(審計表)

  七、要求你將觸發器的例子保存到筆記中

    ①insert觸發器(new)

    ②delete觸發器(old)

    ③update觸發器(new、old)

    ④before、after

 

六十8、event

  一、週期性執行

    ①linux裏面的at、crontab

    ②MySQL裏面的event

  二、event的核心知識點

    ①執行一次

CREATE EVENT myevent ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE DO   begin     UPDATE t1 SET mycol = mycol + 1;   end

    ②週期性執行

CREATE EVENT myevent ON SCHEDULE EVERY 1 DAY STARTS STR_TO_DATE(‘2017-05-01 20:00:00’,'yyyy-mm-dd hh24:mi:ss') DO   begin     UPDATE t1 SET mycol = mycol + 1;   end
相關文章
相關標籤/搜索