Mysql/MariaDB基礎

1. Mysql/MariaDB的使用模式:

  • 交互模式:html

    可運行命令有兩類:mysql

    • 客戶端命令:
      \h,help
    • 服務器端命令:
      SQL,須要語句結束符(冒號;)
  • 非交互模式:sql

    • mysql -e 「SQL語句」shell

    • 導入sql腳本,mysql -uUSERNAME -hHOST -pPASSWORD < /PATH/TO/FILE.sql數據庫

      也可在交互模式下導入腳本:mysql> source /PATH/TO/FILE.sql緩存

  • 客戶端程序:
    • mysql:交互式的CLI工具;
    • mysqldump:邏輯備份工具,基於mysql協議向mysqld發起查詢請求,並將查得的全部數據轉換成insert等寫操做語句保存文本文件中,速度慢;
    • mysqladmin:基於mysql協議管理mysqld;
  • 客戶端命令:安全

    經常使用選項:
      --host=host_name, -h host_name:服務端地址;
      --user=user_name, -u user_name:用戶名;
      --password[=password], -p[password]:用戶密碼;
      --port=port_num, -P port_num:服務端端口;
      --protocol={TCP|SOCKET|PIPE|MEMORY}:
          本地通訊:基於本地迴環地址進行請求,將基於本地通訊協議;
              Linux:SOCKET
              Windows:PIPE,MEMORY
          非本地通訊:使用非本地迴環地址進行的請求; TCP協議;
      --socket=path, -S path
      --database=db_name, -D db_name:
      --compress, -C:數據壓縮傳輸
      --execute=statement, -e statement:非交互模式執行SQL語句;
      --vertical, -E:查詢結果縱向顯示;

    客戶端命令:
    ? (?) Synonym for `help'.
    help (\h) Display this help.
    clear (\c) Clear the current input statement.
    connect (\r) Reconnect to the server. Optional arguments are db and host.
    delimiter (\d) Set statement delimiter.
    edit (\e) Edit command with $EDITOR.
    ego (\G) Send command to mysql server, display result vertically.
    exit (\q) Exit mysql. Same as quit.
    go (\g) Send command to mysql server.
    nopager (\n) Disable pager, print to stdout.
    notee (\t) Don't write into outfile.
    pager (\P) Set PAGER [to_pager]. Print the query results via PAGER.
    print (\p) Print current command.
    prompt (\R) Change your mysql prompt.
    quit (\q) Quit mysql.
    rehash (#) Rebuild completion hash.
    source (.) Execute an SQL script file. Takes a file name as an argument.
    status (\s) Get status information from the server.
    system (!) Execute a system shell command.
    tee (\T) Set outfile [to_outfile]. Append everything into given outfile.
    use (\u) Use another database. Takes database name as argument.
    charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
    warnings (\W) Show warnings after every statement.
    nowarning (\w) Don't show warnings after every statement.服務器

  • 參數設定session

    服務器端(msyqld)工做特性有多種定義方式:併發

    • 啓動mysql服務時的附帶選項

    • 配置文件中設定的參數

      配置文件啓動查找路徑:/etc/my.cnf 、 /etc/mysql/my.cnf 、 $MYSQL_HOME/my.cnf、 ~/.my.cnf

      同一項設置多個文件中都存在的話,以最後查找的配置文件爲準。

    • 運行中的mysql進程使用命令修改參數及其值;

      • 全局參數:

        1. mysql> SET GLOBAL system_var_name=value;

        2. mysql> SET @@global.system_var_name=value;

      • 會話參數:

        1. mysql> SET [SESSION] system_var_name=value;

        2. mysql> SET @@[session.]system_var_name=value;

        注意:兩種修改方式都可;會話參數(顧名思義,僅本次會話生效)和部分全局參數支持運行時修改,會當即生效;有些全局參數不支持,且只能經過修改配置文件,並重啓服務器程序生效。

2. MariaDB初始化操做

安裝後的設定:

  1. 建議關閉主機名反解功能;

    skip_name_resolve = ON

  2. 開啓InnoDB的每數據庫文件單獨目錄存放;

    innodb_file_per_table = ON

    注:MariaDB10.3已經默認開啓

  3. 設定服務端默認字符集

    character_set_server=utf8

  4. 設定默認存儲引擎;

    default-storage-engine=InnoDB

    存儲引擎是表級概念,即同數據庫在建立表時可用type=VALUE的形式爲不一樣表指定不一樣存儲引擎,但不推薦這樣作。

以上項目寫入配置文件的mysqld項

  1. 爲全部root用戶設定密碼;

    mysql>SET PASSWORD FOR

    mysql> update mysql.user SET password=PASSWORD(‘your_pass’) WHERE clause;

  2. 刪除全部匿名用戶

    Mysql>DROP USER ‘’@’localhost’;

上述兩步驟建議經過運行安全初始化完成:mysql_secure_installation

3.SQL語言

3.1DDL:數據定義語言

DDL主要是用在定義或改變表(TABLE)的結構,數據類型,表之間的連接和約束等初始化工做上,他們大多在創建表時使用如,CREATE,ALTER,DROP等命令

相關的經常使用操做對象:數據庫、表、索引、視圖、用戶、存儲過程、存儲函數、觸發器、事件調度器等。

3.2 DML:數據操做語言

就象它的名字同樣,是用來對數據庫裏的數據進行操做的語言。

  • SELECT - retrieve data from the a database 查詢
    • 有的分類方式會將Select語句單獨做爲DQL語言分類
  • INSERT - insert data into a table 添加
  • UPDATE - updates existing data within a table 更新
  • DELETE - deletes all records from a table, the space for the records remain 刪除
  • CALL - 調用存儲過程
  • LOCK TABLE - control concurrency 鎖,用於控制併發
  • EXPLAIN PLAN - explain access path to data
    RDBMS(關係型數據管理系統)執行每一條SQL語句,都必須通過優化器的評估。因此,瞭解優化器是如何選擇(搜索)路徑以及索引是如何被使用的,對優化SQL語句有很大的幫助。Explain能夠用來迅速方便地查出對於給定SQL語句中的查詢數據是如何獲得的即搜索路徑(咱們一般稱爲Access Path)。從而使咱們選擇最優的查詢方式達到最大的優化效果。

語句格式

數據庫:
    CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name CHARACTER SET [=] charset_name  COLLATE [=] collation_name

    ALTER {DATABASE | SCHEMA} [db_name] CHARACTER SET [=] charset_name  COLLATE [=] collation_name

    DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

表:
CREATE

(1) 常規方式建立表;
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name (create_definition,...) [table_options] [partition_options]

CREATE TABLE [IF NOT EXISTS] tble_name (col_name data_type|INDEX|CONSTRAINT);

    table_options:
        ENGINE [=] engine_name
    查看支持的全部存儲引擎:
        mysql> SHOW ENGINES;
    查看指定表的存儲引擎:
        mysql> SHOW TABLE STATUS LIKE clause;

ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

(2) 直接建立表,並將查詢語句的結果插入到新建立的表中;
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] [table_options][partition_options] select_statement

(3) 複製某存在的表的結構來建立新的空表;
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKE old_tbl_name) }

DROP:
    DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name];

ALTER:
    ALTER  TABLE tbl_name [alter_specification [, alter_specification] ...]
    可修改內容:
        (1) table_options
        (2) 添加定義:
            ADD 字段、字段集合、索引、約束
        (3) 修改字段:
            CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name]
            MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
        (4) 刪除操做:
            DROP 字段、索引、約束

表重命名:
    RENAME [TO|AS] new_tbl_name

查看錶結構定義:
    DESC tbl_name;

查看錶定義:
    SHOW CREATE TABLE tbl_name

查看錶屬性信息:
    SHOW TABLE STATUS [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]
3.3 DCL:數據控制語言

數據控制語言DCL用來授予或回收訪問數據庫的某種特權,並控制數據庫操縱事務發生的時間及效果,對數據庫實行監視等。如:

  • GRANT:受權
  • REVOKE:收回受權

  • ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一點
    回滾---ROLLBACK
    回滾命令使數據庫狀態回到上次最後提交的狀態。

  • COMMIT [WORK]:提交。

    在數據庫的插入、刪除和修改操做時,只有當事務在提交到數據庫時纔算完成。提交數據有三種類型:顯式提交、隱式提交及自動提交。下面分別說明這三種類型。

    • 顯式提交
      用COMMIT命令直接完成的提交爲顯式提交。其格式爲:

    • 隱式提交
      用SQL命令間接完成的提交爲隱式提交。這些命令是:
      ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,
      EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。

    • 自動提交
      若把autocommit參數設置爲ON,則在插入、修改、刪除語句執行後,系統將自動進行提交,這就是自動提交。其格式爲:

      SET @@[GLOBAL|SESSION].autocommit=ON;

4.Mysql數據類型

4.1字符型
VARCHAR, VARBINARY:變長數據類型;須要結束符;

          TEXT:TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT

          BLOB: TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB

          ENUM, SET

字符型修飾符:

NOT NULL:非空約束;

          NULL:

          DEFAULT ‘STRING’:指明默認值;

          CHARACTER SET ‘’:使用的字符集;

          COLLATION:使用的排序規則;
4.2 數值型

精確數值型:

整型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT,DECIMAL

整形修飾符:NOT NULL, NULL, DEFALUT value, AUTO_INCREMENT, UNSIGNED

近似數值型:

浮點型:FLOAT,DOUBLE,BIT,REAL
4.3 日期時間型

日期:DATE

時間:TIME

日期&時間:DATETIME

時間戳:TIMESTAMP

年份:YEAR(2), YEAR(4)

日期時間型修飾符:NOT NULL, NULL, DEFAULT

4.4 內建數據類型

ENUM:枚舉

如:ENUM('Sun','Mon','Tue','Wed')

SET:集合

4.5 SQL MODE

定義mysqld對約束等違反時的響應行爲等設定。

經常使用的MODE:

TRADITIONAL

STRICT_TRANS_TABLES

STRICT_ALL_TABLES

MODE的具體介紹請移步http://www.cnblogs.com/ainiaa/archive/2010/12/31/1923002.html

修改方式:mysql> SET GLOBAL sql_mode='MODE';

5. 查詢語句詳解

查詢執行路徑:

  1. 命中緩存:

    請求-->查詢緩存

    緩存以K-V形式存儲查詢的執行結果;key:查詢語句的hash值;value:查詢語句的執行結果;

  2. 未命中緩存:

  3. 請求-->查詢緩存-->解析器-->預處理器-->優化器-->查詢執行引擎-->存儲引擎-->緩存-->響應

SELECT語句的執行流程:

FROM  --> WHERE --> Group By --> Having --> Order BY --> SELECT --> Limit
5.1 單表查詢

單表查詢:

SELECT

                [ALL | DISTINCT | DISTINCTROW ]

                [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]

                select_expr [, select_expr ...]

                [FROM table_references

                [WHERE where_condition]

                [GROUP BY {col_name | expr | position}

                [ASC | DESC], ... [WITH ROLLUP]]

                [HAVING where_condition]

                [ORDER BY {col_name | expr | position}

                [ASC | DESC], ...]

                [LIMIT {[offset,] row_count | row_count OFFSET offset}]      

            用法:

                SELECT col1, col2, ... FROM tble_name;   **無限定條件的查詢極其危險,慎用**;

                SELECT col1, col2, ... FROM tble_name WHERE clause;

                SELECT col1, col2, ... FROM tble_name  [WHERE clause] GROUP BY col_name [HAVING clause]; 

            DISTINCT:數據去重;

            SQL_CACHE:顯式指定緩存查詢語句的結果;

            SQL_NO_CACHE:顯式指定不緩存查詢語句的結果;

            query_cache_type服務器變量有三個值:

                ON:啓用;

                    SQL_NO_CACHE:不緩存;默認符合緩存條件都緩存;

                OFF:關閉;

                DEMAND:按需緩存;

                    SQL_CACHE:緩存;默認不緩存;​    

            字段可使用別名 :

                col1 AS alias1, col2 AS alias2, ...

            WHERE子句:指明過濾條件以實現「選擇」功能;

                過濾條件:布爾型表達式;

                [WHERE where_condition]

                    算術操做符:+, -, *, /, %

                    比較操做符:=, <>, !=, <=>, >, >=, <, <=

                        IS NULL, IS NOT NULL

                        區間:BETWEEN min AND max

                        IN:列表;

                        LIKE:模糊比較,%和_;

                        RLIKE或REGEXP​     

                    邏輯操做符:

                        AND, OR, NOT​      

            GROUP BY:根據指定的字段把查詢的結果進行「分組」以用於「聚合」運算;

                avg(), max(), min(), sum(), count()

                HAVING:對分組聚合後的結果進行條件過濾;

            ORDER BY:根據指定的字段把查詢的結果進行排序;

                升序:ASC

                降序:DESC

            LIMIT:對輸出結果進行數量限制

                [LIMIT {[offset,] row_count | row_count OFFSET offset}]
5.2 多表查詢:

鏈接操做:

交叉鏈接:笛卡爾乘積;

    內鏈接:

    等值鏈接:讓表之間的字段以等值的方式創建鏈接;

    不等值鏈接:

自鏈接

例子:

內鏈接

select st.name,sc.score from students as st,scores as sc where st.stuid=sc.stuid;
select st.name,sc.score from students as st inner join scores as sc on st.stuid=sc.stuid;

外鏈接
左:select st.name,sc.score from students as st left outer join scores as sc on st.stuid=sc.stuid;
右:select st.name,sc.score from scores as sc right outer join students as st on st.stuid=sc.stuid;

自鏈接
select e2.name,e1.name as 上司的名字 from emp as e1 inner join emp as e2 on e1.id=e2.leaderid;

    crossjoin 交叉鏈接

select c.course,t.name," " as 評分 from teachers as t cross join courses as c;

5.3 子查詢:在查詢中嵌套查詢;
用於WHERE子句中的子查詢;

                (1) 用於比較表達式中的子查詢:子查詢僅能返回單個值;

                (2) 用於IN中的子查詢:子查詢能夠返回一個列表值;

                (3) 用於EXISTS中的子查詢:

            用於FROM子句中的子查詢;

                SELECT tb_alias.col1, ... FROM (SELECT clause) AS tb_alias WHERE clause;​

例子:
select * from students where age < ( select age from students where stuid=9 ) ;

5.4 聯合查詢:將多個查詢語句的執行結果相合並;
SELECT clause UNION SELECT cluase;

如:select t.tid,t.name from teachers as t union select s.stuid,s.name from students as s;

5.5 select練習

導入hellodb.sql,完成如下題目:

  1. 顯示前5位同窗的姓名、課程及成績;

    MariaDB [hellodb]> SELECT s.Name,c.Course,sc.Score FROM (select * from students limit 5) AS s  LEFT JOIN scores AS sc ON sc.StuID = s.StuID LEFT JOIN courses AS c ON sc.CourseID =c.CourseID;
    +-------------+----------------+-------+
    | Name        | Course         | Score |
    +-------------+----------------+-------+
    | Shi Zhongyu | Kuihua Baodian |    77 |
    | Shi Zhongyu | Weituo Zhang   |    93 |
    | Shi Potian  | Kuihua Baodian |    47 |
    | Shi Potian  | Daiyu Zanghua  |    97 |
    | Xie Yanke   | Kuihua Baodian |    88 |
    | Xie Yanke   | Weituo Zhang   |    75 |
    | Ding Dian   | Daiyu Zanghua  |    71 |
    | Ding Dian   | Kuihua Baodian |    89 |
    | Yu Yutong   | Hamo Gong      |    39 |
    | Yu Yutong   | Dagou Bangfa   |    63 |
    +-------------+----------------+-------+
    10 rows in set (0.000 sec)
  2. 顯示其成績高於80的同窗的姓名及課程與成績;

    MariaDB [hellodb]> SELECT s.Name,c.Course,sc.Score FROM students  AS s  LEFT JOIN scores AS sc ON sc.StuID = s.StuID LEFT JOIN courses AS c ON sc.CourseID =c.CourseID WHERE sc.Score >80; 
    +-------------+----------------+-------+
    | Name        | Course         | Score |
    +-------------+----------------+-------+
    | Shi Zhongyu | Weituo Zhang   |    93 |
    | Shi Potian  | Daiyu Zanghua  |    97 |
    | Xie Yanke   | Kuihua Baodian |    88 |
    | Ding Dian   | Kuihua Baodian |    89 |
    | Shi Qing    | Hamo Gong      |    96 |
    | Xi Ren      | Hamo Gong      |    86 |
    | Xi Ren      | Dagou Bangfa   |    83 |
    | Lin Daiyu   | Jinshe Jianfa  |    93 |
    +-------------+----------------+-------+
    8 rows in set (0.101 sec)
  3. 求前8位同窗每位同窗本身兩門課的平均成績,並按降序排列;

    MariaDB [hellodb]> SELECT s.Name,AVG(Score) FROM  (select Name,StuID from students limit 8)   AS s  LEFT JOIN scores AS sc ON s.StuID = sc.StuID  GROUP BY Name ORDER BY AVG(Score) DESC;
    +-------------+------------+
    | Name        | AVG(Score) |
    +-------------+------------+
    | Shi Qing    |    96.0000 |
    | Shi Zhongyu |    85.0000 |
    | Xi Ren      |    84.5000 |
    | Xie Yanke   |    81.5000 |
    | Ding Dian   |    80.0000 |
    | Lin Daiyu   |    75.0000 |
    | Shi Potian  |    72.0000 |
    | Yu Yutong   |    51.0000 |
    +-------------+------------+
    8 rows in set (0.000 sec)
  4. 顯示每門課程課程名稱及學習了這門課的同窗的個數,並降序排列;

    MariaDB [hellodb]> SELECT c.Course AS 課程名稱,count(s.StuID) AS 學生數量  FROM  courses  AS c  LEFT JOIN scores AS s ON c.CourseID = s.CourseID  GROUP BY s.CourseID ORDER BY count(s.StuID) DESC;
    +----------------+--------------+
    | 課程名稱       | 學生數量     |
    +----------------+--------------+
    | Kuihua Baodian |            4 |
    | Hamo Gong      |            3 |
    | Daiyu Zanghua  |            2 |
    | Dagou Bangfa   |            2 |
    | Weituo Zhang   |            2 |
    | Taiji Quan     |            1 |
    | Jinshe Jianfa  |            1 |
    +----------------+--------------+
    7 rows in set (0.000 sec)
  5. 如何顯示其年齡大於平均年齡的同窗的名字和年齡?

    MariaDB [hellodb]> select name,age from students where age >(select avg(age) from students) order by age desc; 
    +--------------+-----+
    | name         | age |
    +--------------+-----+
    | Sun Dasheng  | 100 |
    | Xie Yanke    |  53 |
    | Shi Qing     |  46 |
    | Tian Boguang |  33 |
    | Ding Dian    |  32 |
    +--------------+-----+
    5 rows in set (0.001 sec)
  6. 如何顯示其學習的課程爲第一、2,4或第7門課的同窗的名字及課程名?

    MariaDB [hellodb]> select s.Name, s.CourseID, courses.Course from (select students.Name,scores.CourseID from students left join scores on students.StuID = scores.StuID where scores.CourseID in (1,2,4,7)) as s left join courses on s.CourseID=courses.CourseID;
    +-------------+----------+----------------+
    | Name        | CourseID | Course         |
    +-------------+----------+----------------+
    | Shi Zhongyu |        2 | Kuihua Baodian |
    | Shi Potian  |        2 | Kuihua Baodian |
    | Xie Yanke   |        2 | Kuihua Baodian |
    | Ding Dian   |        2 | Kuihua Baodian |
    | Yu Yutong   |        1 | Hamo Gong      |
    | Yu Yutong   |        7 | Dagou Bangfa   |
    | Shi Qing    |        1 | Hamo Gong      |
    | Xi Ren      |        1 | Hamo Gong      |
    | Xi Ren      |        7 | Dagou Bangfa   |
    | Lin Daiyu   |        4 | Taiji Quan     |
    +-------------+----------+----------------+
    10 rows in set (0.104 sec)
  7. 如何顯示其成員數最少爲3個的班級的同窗中年齡大於同班同窗平均年齡的同窗?

    MariaDB [hellodb]> SELECT students.name,students.age,s.classid,s.pj FROM students,(SELECT classid,COUNT(stuid)  AS cs,AVG(age) AS pj FROM students GROUP BY classid HAVING cs >=3) AS s WHERE  students.age>s.pj AND students.classid =s.classid;
    +---------------+-----+---------+---------+
    | name          | age | classid | pj      |
    +---------------+-----+---------+---------+
    | Shi Potian    |  22 |       1 | 20.5000 |
    | Xie Yanke     |  53 |       2 | 36.0000 |
    | Ding Dian     |  32 |       4 | 24.7500 |
    | Yu Yutong     |  26 |       3 | 20.2500 |
    | Yuan Chengzhi |  23 |       6 | 20.7500 |
    | Xu Zhu        |  21 |       1 | 20.5000 |
    | Lin Chong     |  25 |       4 | 24.7500 |
    | Hua Rong      |  23 |       7 | 19.6667 |
    | Huang Yueying |  22 |       6 | 20.7500 |
    +---------------+-----+---------+---------+
    9 rows in set (0.017 sec)
  8. 統計各班級中年齡大於全校同窗平均年齡的同窗。

select name,age,classid from students where age > (select avg(age) as a from students);
此種寫法簡單但不能過濾students表中classid = NULL的條目
MariaDB [hellodb]> SELECT s.Name,s.Age FROM students AS s LEFT JOIN classes AS c ON s.ClassID=c.ClassID WHERE s.ClassID=c.ClassID AND Age > (SELECT AVG(Age) FROM students);
+--------------+-----+
| Name         | Age |
+--------------+-----+
| Xie Yanke    |  53 |
| Ding Dian    |  32 |
| Shi Qing     |  46 |
| Tian Boguang |  33 |
+--------------+-----+
4 rows in set (0.000 sec)
相關文章
相關標籤/搜索