數據庫基本知識+關系型數據庫的基本操作



  




  




  
數據庫:
    程序=指令 + 數據
    數據結構:變量,數組


    I/O    :
        提供數據,保存數據
        文件,交互式輸入
        持久存儲

    文件:
        數據冗余和不一致性
        數據訪問困難
        數據孤立
        原子性問題
        並發訪問異常
        安全性問題    
    DBMS:
        層次型:倒裝型
        網狀型:不易於開發,管理,都在一塊混着
        關系型:二維數據表(字段,記錄)

    RDBMS:關系型管理工具
        Sybase + Microsoft
            SQL Server
        Informix --> IBM
            DB2
        Oracle <--- SUN
            MySQL

    MySQL --- > MariaDB
        percona公司:---> xtradb(增強版的innodb)-->用於MariaDB


        webscaledb -——>為web產生的web數據庫

        PsotgreSQL ,pgsql(性能優秀,但是市場決定一切)


    C/S架構:
        mysql --> mysqld
            (mysql協議)
        sqlite:(工作有本地的,關系型數據庫接口,引擎,把數據組織成表格形似
 數據庫使用:
        1、直接使用交互式接口;
        2、使用開發程序軟件:
            可調用的客戶端:API

        sqlite:客戶端和服務器端在一塊,不需要C/S通信了,數據保存在一個lib中,包括元數據等信息,同時又可以加載用以自己理解的形式查看


        dbm:把數據保存成散列形式(哈希)

    SQL:structure query language
        DDL:定義
            CREATE,DROP,ALTER
        DML:操作語言
            INSERT,UPDATE,DELETE
        DCL:控制
            GRANT,REVOKE
        DQL:查詢
            SELECT

    事務:
        ACID
            A:原子性 ---> 要不執行,要不都執行 ,整個事務中的所有操作要么全部成功執行,要么全部失敗后回滾
            C:一致性 ---> 數據庫總是從一個一致性狀態轉換為另一個一致性狀態
            I:隔離性 ---> 一個事務的所有修改操作在提交之前對其它事務是不可見的
            D:持久性 --->  一旦事務得到提交,其所做的修改會永久有效

            提交:持久
            未提交:提交,回滾


        隔離:隔離級別
            read uncommitted 讀未提交
            read committed 讀提交
            repeatable read :可重讀
            serializable:串行化

    MySQL:存儲引擎:
        MyISAM:無事務
            分離索引:數據和索引分開

        InnoDB:事務型
            聚簇索引:數據和索引放一塊


    機械式硬盤:(對內存來講,兩種讀寫都是一樣的)
        隨機讀寫:慢,磁盤指針轉動需要時間
        順序讀寫:

    SQL:支持xml,可以輸出為xml文件
        規范:ANSI定義
            SQL-86,89,92,99,03

    關系數據庫的約束:
        主鍵約束,外鍵,唯一鍵,條件約束,非空約束

        約束:constraint,向數據表提供的數據要遵守的限制;
                    主鍵:一個或多個字段的組合,填入的數據必須能在本表中唯一標識本行;必須提供數據,即NOT NULL; 
                        一個表只能存在一個
                    惟一鍵:一個或多個字段的組合,填入的數據必須能在本表中唯一標識本行;允許為NULL;
                        一個表可以存在多個
                    外鍵:一個表中的某字段可填入數據取決於另一個表的主鍵已有的數據;
                    檢查性:字段值在一定范圍內

                索引:將表中的一個或多個字段中的數據復制一份另存,並且此些需要按特定次序排序存儲;

                關系運算:
                    選擇:挑選出符合條件的行(部分);
                    投影:挑選出需要的字段;
                    連接:表間字段的關聯
        數據抽象:
            物理層:決定數據的存儲格式,即RDBMS在磁盤上如何組織文件;
            邏輯層:描述DB存儲什么數據,以及數據間存在什么樣的關系;
            視圖層:描述DB中的部分數據;

        關系模型的分類:
            關系模型
            實體-關系模型
            基於對象的關系模型
            半結構化的關系模型

    DBA:
        開發:
            數據庫設計
            代碼設計 :存儲過程,存儲函數,觸發器
        管理:
            連接管理及優化
            備份及還原
            數據庫設計
            基本語句優化
            用戶即權限管理
            安全管理
            數據庫軟件安裝和升級
            配置優化

    MySQL:
        高性能,完全多線程,查詢緩存(小規模)
        支持復制(伸縮性)

    Product Family:
        MySQL server(mysqld,mysql)
        MySQL Cluster
        MySQL Proxy 
        MySQL Adminitrator
        MySQL Query Browser
        MySQL Workbench

    MySQL Arch:
        真正執行SQL的是優化器之后的存儲引擎,所以一個庫支持一個引擎
   MySQL安裝: rpm 源碼編譯 通用二進制(已經編譯好的) 版本: GA: RC: 即將變為GA beta:共測 alpha:內側 rpm安裝:client , server, shared, shared-compat 二進制安裝: 插件式引擎 三種默認服務,mysqld,mysqld-safe,mysql-mtuil 默認開始的是safe 約束: 主鍵約束: 不能重復,不能為NULL,有且只能有一個 外鍵約束 唯一鍵約束 可以有多個,唯一,可能為NULL 檢查是約束 用戶自定義有效取值范圍 鍵:(字段) 主鍵:能夠 唯一 標識表中每一個記錄的字段或字段的組合(不能重復,不能為NULL) 候選鍵:可以挑來做主鍵的組合,但是沒選 初始化:提供配置文件 配置文件 .cnf 集中式的配置,多個應用程序共用的配置文件 [mysqld]: [mysql_safe] [client] # ./usr/local/mmysql/bin/mysqld --help -v | head -20 # 讀取配置文件的順序 Default options are read from the following files in the given order: /etc/mysql/my.cnf /etc/my.cnf ~/.my.cnf 使用配置文件的方式: 1、它一次查找每個需要查找的文件,結果多有文件的並集 2、如果某參數出現多次,后去讀取的生效 # ./usr/local/mmysql/bin/mysqld --help -v 1、顯示 mysql程序啟動時可用的選項,通常是長選項 2、顯示mysql的配置文件中可用的服務變量 SHOW GLOBAL VARIABLES SHOW SESSION VARIABLES 初始化的第二個操作: 1、刪除所有的匿名用戶 DROP USER ''@loaclhost DROP USER ''@node2 用戶賬號有兩部分組成: user@hostname host可以使用通配符 %:任意長度的字符串 _:下划線匹配任意單個字符 2、給所有的root用戶設定密碼 第一種方式: SET PASSEORD FOR usernam@host = PASSEWORD('1231') 第二種范式:比較妥當的方式 UPFATE user SET password = PASSWORD('12345') WHERE user='root'; FLUSH PRIVILEGES; 第三種方式: mysqladmin -uUserName -hHost -p password 'new_password' mysqladmin -uUserName -hHost -p flush-privileges; 接入mysql服務器: mysql client
<----> mysql protocol ---> mysqld mysqld 接受連接請求L: 本地通信:客戶端與服務器端在同一個主機,而且還要基於127.0.0.1(localhost)地址或lo接口進行通信 Linux和UNix:unix sock /var/lib/mysql/mysql.sock windows:本地通信:共享內存,管道通信---memory,pipe 遠程通信:客戶端與服務器位與不同的主機,或在同一主機使用非 本地回環地址通信 tcp socket 客戶端工具: mysql,mysqladmin,mysqldump,mysqlcheck 有[client]段,其中的所有項,對以上工具都是生效的。 通行的選項: -u -h -p, --password --protocol = {tcp|scok|pipe|memory} 后三者都是本地,后兩者是windows上 --port 端口 --socket :指定文件名(本地通信) mysql監聽端口:tcp/3306 非客戶端類的管理工具: myisamchk, myisampack 第一個是檢查工具 第二個是打包工具 mysql: 交互式模式: 腳本模式:輸入重定向 mysql < /path/mysql.mysql 交互式模式: 客戶端命令:不要分號 help:查看命令 \C:不執行命令(命令結束符之前使用) \G:Send command to mysql server, display result vertically. \g:Send command to mysql server. \q:Exit mysql. Same as quit. \! :Execute a system shell command \s: Get status information from the server. \. 導入mysql腳本 服務器端命令:需要命令結束符,默認分號 help 關鍵字:查看幫助 help contents:內容列表,獲取整體,獲取某個,跟上具體的名字 mysql命令行選項: --compress:壓縮傳輸 --default-character-set:默認字符集(mysql客戶端),用的很少,避免與服務器端不同的編碼方式 -v -V: --ssl-ca:ca證書文件 --ssl-capath:多個ca證書,自動尋找 --ssl-cipher:冒號分割是加密方式 --ssl-verify-server-cert:驗證服務器端證書 -D /--database= :直接指定要使用的庫 mysql命令提示符: mysql> 等待輸入命令 '> "> `> /*> 注釋 */ 結束 -> :續航 支持光標移動: crtrl + w:刪除 光標之前的單詞 ctrl + u: 刪除光標之前至命令行之前的所有內容 ctrl + y:恢復之前刪除的內容 ctrl + a:行首 ctrl + e:行尾 -A:禁用命令補全 /#: 啟用 當前用戶家目錄下 ~/.mysql.history: 命令歷史 mysql的輸出格式: -H: mysql -H -uroot -p 進入之后,執行的命令結果都是html格式的 -X:輸出格式為xml --safe-updates:實現發送命令時拒絕 沒有where 或update 命令,如果后弦限制了行數的話,也可以執行 mysqladmin工具: mysqladmin [options] command command: create:創建庫 mysqladmin -uroot -p create mydb :不需要登錄創建庫 mysql -uroot -p -e show databases;直接查看庫 drop dbName:刪除庫 debug:打開調試日志,並記錄與mysql的error log中 status:輸出狀態信息 mysqladmin -uroot -p status --sleep 1 --count 5:間隔時長,顯示的批次 extended-status :相當於show global status 輸出mysql的各狀態變量及其值 variables:mysql的各服務器變量 flush-hosts:清空主機緩存 DNS解析緩存,此前因為連接錯誤次數過多而被拒絕訪問mysql的主機 flush-logs:日志滾動(二進制日志,中繼日志) refresh:相當於同時使用 flush-hosts, flush-logs flush-ptivileges:重載授權表 reload flush-status:重置狀態變量,不是清空,只把啟動到現在的一些變量信息歸0 flush-tables:關閉當前打開的表文件句柄(手動加鎖的時候用) flush-treads:清空線程緩存 kill :殺死指定的線程(線程ID),使用逗號分隔,不能有多余的空白字符 password:修改指定用戶密碼 ping:服務器是否在線 processlist:各線程信息 shutdown:關閉mysql進程 start-slave:啟動從服務器線程 stop-slave:關閉 GUI客戶端工具: Navicat for mysql: 之前公司用的 SQLyog phpMyAdmin MySQL Front 開發DBA: 數據庫設計(E-R關系圖) sql開發,內置函數,存儲例程(存儲過程和存儲函數)--盡量在服務器端執行,觸發器(自動執行),事件調度器(event sechduler) 管理DBA: 安裝, 升級,卸載,備份,恢復,用戶管理,權限管理,監控,測試,分析,語句優化(sql語句),配置服務器(服務器變量,定制存儲引擎參數,內置緩存,日志),數據字典, SQL語言的組成部分: DDL:數據定義語言 DML:數據操作語言 完整性定義語言:DDL的一部分功能 主鍵約束,外鍵約束(不是所有的引擎支持),條件約束,唯一鍵約束,非空約束,事物約束 視圖定義:虛表,存儲下來的的select語句 事務控制: 動態sql 和 嵌入sql DCL:控制(授權) 數據類型的作用: 1、存儲的值類型;數據類型 2、存儲空間的大小 3、定長,變長 4、如何被索引及排序:binary 是區分大小寫的 5、是否能夠被索引 text(只能索引左側固定長度的信息) 數據字典:系統編目(systm catalog),並不是目錄 保存數據庫服務器上的元數據 初始化數據表:mysql這個庫 元數據: 關系的名字 每個關系的各字段的名字 各字段的數據類型和長度 約束 每個關系上的視圖的名字及視圖的定義 授權用戶的名字 用戶的授權和賬號信息 統計類的數據: 每個關系字段的個數 每個關系中函數 每個關系的存儲方法 保存元數據的數據庫: information_schema 元數據,統計類信息, 虛的,不存在,在內存中,類似於/dev/映射為的設備文件 performance_schema 性能信息 SQL語句: 數據類型: 字符型: 不區分大小寫: char varchar text: 區分大小寫: binary varbinary blob:二進制的大對象 數值型 精確數值型 整型 十進制數據: 近似數值型 單精度 雙精度 日期型 時間型 日期型 日期時間型 時間戳 YEAR 布爾型:非真正的bool型 tinyint 內建型 ENUM, SET(枚舉,集合) 數值型: TINYINT:精確 SMALLINT MEDIUMINT INT BIGINT DECTML FLOAT DOUBAL 字符型: CHAR VARCHAR TINYTEXT MEDIUMTEXT LONGTEXT BINARY VARINARY BLOB MEDIUMBOLB 變長 是需要結束符的 盡量不要使用text,索引空難,而且以對象索引,存在於數據庫外的某個位置,數據庫存指針 盡量別可變長度,影響索引 char --- 最多255個字符 varchar --- 最多65535個字符 tinytext --- 最多255個 CHAR , VARCHAR, TEXT字符型常用的屬性修飾符: NOT NULL:非空約束 NULL:運行為空 DEFAULT ‘string':不適用於text CHARACTER SET ' 字符集':指定字符集 (從小到大范圍繼承) 查看字符集: SHOW CHARACETER SET; SHOW VARIABLES LIKE '%CHAR%' 支持的排序規則: SHOW COLLATION; BINARY,VARBINARY, BLOB:二進制存儲,字節的大小排序 NOT NULL NUL DEFAULT : 不適用於BLOB 數值型:常用屬性修飾符 TINYINT 0-255 1字節 SMALLINT 0-65535 2 MEDIUMINT 0-16777215 3 INT 0-4億 4字節 AUTO_INCREMENT :自動增長 前提:非空,唯一,支持索引(用過之后,就不會再用,即便前面數刪除了),非負值。 SELECT LAST_INSERT_ID():顯示插入語句用了多少,但是准確,如果批量插入,只記錄1次 使用 DROP FROM table;再插入數據,LAST_INSERT_ID() 從當前數據增長 最好使用 TRUNCATE table; 就1開始 UNSIGNED:無符號 NULL, NOT NULL , DEFAULT 不能加引號 浮點型:支持使用精度 NULL , NOT NULL , DEFAULT,UNSIGNED 日期: DATE 3 字節 DATETIME 8字節 TIME 3字節 YEAR 1字節 NOT NULL NULL DEFAULT ENUM:最大65535個字符,字符串,只能選一個 SET:單個字符, 或幾個字符,用的時候,是挑幾個的組合,而且使用的是索引 可以支持多個字節。 NOT NULL NULL DEFAULT ‘’ MySQL mysql_mode:sql 模型: 常用的模式: TRADITIONAL:傳統模式 STRICT_TRANS_TABLES:事務的表嚴格模式 STRICT_ALL_TABLES:所有的都 嚴格 SHOW GLOBAL VARIABLES LIKE '%mode%' 設定服務器變量的值:(僅用於支持動態的變量) 支持修改的服務器變量: 動態變量:mysql運行時修改 靜態變量:於配置文件中修改,重啟后才能生效 服務器變量從其生效范圍: 全局變量:服務器級別的,修改之后,僅對新建立的會話有效 會話變量:僅對當前的會話有效 會話建立時 ,從全局繼承各變量 查看服務器變量: SHOW GLOBAL[SESSION] VARIABLES [LIKE ' '] :默認session SELECT @@{GLOABL|SESSION}.sql_mode 或者在 information_schema 庫中,表中查看 修改變量: 前提:默認只有root才有權限修改全局 SET global | session variable_name=''; 例如: SET SESSION SQL_MODE=‘’ 修改了去全局,對當前會話無效,對新建會話有效。 注:無論是全局還是會話級別的動態變量的修改,在重啟mysql后,都會失效,想永久有效,一般放下配置文件的[mysqld] mysql --help -v : 帶-- 命令行參數, 不加的是配合文件參數,有重疊,但不一定相同 MySQL的大小寫問題: sql的關鍵字和函數名,是不區分大小寫的。 數據庫,表,視圖的名字,取決於 文件系統,linux區分,windows不區分(移植庫 可能會出現問題) 存儲過程和存儲函數,事件調度器不區分大小寫 觸發器區分大小寫 表別名 區分大小寫 主鍵,唯一鍵是否區分大小寫:字段類型,binary區分大小寫,char 不區分 SQL表,庫管理語句: 數據庫: 創建數據庫: CREATE DATABASE | SCHEMA [IF NOT EXISTS] [CHARACTER SET = ''] [COLLATE = ''] db_name; 默認字符集:等號可有可無 CHARACTER SET = 排序:等號可有可無 COLLATE = 默認值: DEFAULT 刪除庫: DROP DATABASE | SCHEMA [IF EXISTS] db_name 修改數據庫: [CHARACTER SET = ''] [COLLATE = ''],也可以升級數據字典 ALTER DATABASE | SCHEMA db_name [CHARACTER SET = ''] [COLLATE = ''] 表創建方式一: 數據表:鍵是索引,索引不一定是鍵,鍵有約束 HELP CREATE TABLES; ------- CREATE [TEMPORARY] TABLE [IN NOT EXISTS] tb_name (create_definition ,...) [table_options] [partition_options] (create_definition ,...): 字段定義:字段名,類型,類型修飾符 鍵,約束或索引: PRIMARY KEY, UNIQUE KEY, FOREIGN KEY, CHECK {INDEX | KEY} create table t1 (Name varchar(30) not null , age tinyint unsigned not null,primary key(Name,age)); 多字段組成的主鍵 [table_options]: ENGINE= engine_name; AUTO_INCREMENT [=] value 從幾開始 CHARACTER SET [=] characte—name COLLATE [=] collation_name COMMATION [=] 'STRING' 注釋 DELAY_KEY_WRITE [=] {0|1}:索引降低寫,提高查,每次修改都要重新構建,過一會再寫入 ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} 表格式 TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}] 表空間 create table t1 (Name varchar(30) not null , age tinyint unsigned not null,primary key(Name,age)) engine='MyISAM'; 添加引擎 SHOW ENGINES; 存儲引擎 SHOW TABLE STATUS LIKE 't1'\G mysql> SHOW TABLE STATUS LIKE 't1'\G *************************** 1. row *************************** Name: t1 Engine: InnoDB Version: 10 Row_format: Compact Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 10485760 Auto_increment: NULL Create_time: 2018-10-26 09:41:59 Update_time: NULL Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: MyISAM表每個表都有是哪個文件,都位於數據庫目錄中: tb_name.frm: 表結構定義 tb_naem.MYD:數據文件 tb_name.MYI:索引文件 InnoDB 有兩種存儲方式: 1、默認:每個表有一個獨立文件和一個多表共享的文件 tb_name.frm:表結構的定義,位於數據庫目錄(與數據庫同名的目錄) ibdata#:共享的表空間文件(所有的表),默認位於數目錄(datadir指向的目錄)中 2、獨立的表空間文件,每表有一個表結構文件一個獨有的表空間文件,包括索引。 修改配置文件:[mysqld] show global variables like '%innodb%'; | innodb_file_per_table | OFF | tb_name.frm:每表一個表結構文件 tb_name.ibd:一個獨有的表空間文件 表創建方式二:(復制表數據 CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] [table_options] [partition_options] select_statement 表創建方式三:基於某張表,創建空表(復制表結構) CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKE old_tbl_name) } 表刪除: DROP [IF EXISTS] tb_name [CASCADE -- 級聯,關聯的也會刪除] 修改: ALTER TABLE tb_name 修改字段定義: 插入新字段: ALTER TABLE t1 ADD IID INT NOT NULL; 刪除字段: ALTER TABLE t1 DROP IID; 修改字段: 修改字段名稱; | CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name] ALTER TABLE t1 CHANGE Name Sname char(10) NOT NULL; 修改字段類型及屬性等: | MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name] ALTER TABLE t1 MODIFY Name varchar(30) AFTER age; 添加索引: ALTER TABLE t1 ADD INDEX (Sname);把某個字段作為索引 給某個字段添加索引: CREATE INDEX idx_name ON tb_name(字段(指定長度)):指定長度:如果該字段的索引到了一定值后不會再改變,可以節省空間 查看索引: show indexes from t1; 刪除一個索引; ALTER TABLE t1 DROP INDEX Sname; DROP INDEX idx_name ON tb_name SHOW INDEX_STAISTICS;查看索引利用情況 修改約束,鍵,索引 表改名: RENAME [TO|AS] db_name 也可以直接使用: mysql> RENAME TABLE old_name TO new_name; 不建議修改引擎:(它會新建一個表,把數據復制過去) 要是修改,直接指定 指定排序標准的字段: ORDER BY col_name 轉換字符集及排序規則: CONVERT TO CHARACTER SET charset_name [COLATE collation_name] SQL查詢語句: 單表查詢:簡單查詢 多表查詢:連續查詢 聯合查詢: 單表查詢:簡單查詢 選擇和投影: 選擇:挑選要顯示的行: 投影:挑選要顯示的字段 投影:SELECT 字段1,字段2,... FROM 表名; SELECT * FROM tb_name; 選擇:SELECT 字段 FROM tb—name WHERE 子句; 布爾條件表達式 比較操作符: =:等值比較 <=> : 跟NULL 比較不會出現錯誤的 等值比較 <> != :不等比較 < > <= >= IS NULL:不能用= IS NOT NULL: LIKE:模糊匹配 % _ RLIKE:支持使用正則表達式的 REGEXP: IN:某一字段的值是否在指定的列表中 BETWEEN ,,, AND,,, : 在,,,之間 WHERE Age NETWEEN 10 AND 30; CREATE TABLE students (SID INT UNSIGNED AUTO_INCREMENT NOT NULL unique key,Name CHAR(10) NOT NULL, AGE INT UNSIGNED NOT NULL ,Gender ENUM('M','F') NOT NULL, Tutor CHAR(20)); INSERT INTO students VALUES ( , , ,) INSERT INTO tb_name (co1,co2) VALUES(VA1,VA2) 組合條件測試: NOT ! AND && OR || XOR:異或 排序: ORDER BY ' ' ASC 默認升序 ORDER BY ' ' DESC 降序 select * from students order by -classid desc;將NULL 放到最后 mysql內置的聚合函數: SUM(), AVG(), MAX() , MIN(),COUNT() SELECT SUM(Age) FROM students; 分組:以什么為條件,分組 GROUP BY SELECT gender,sum(age) fromstudents GROUP BY gender; 對GROUP BY的結果做過濾,使用having, 注:where用在group by之前 SELECT gender,sum(age) fromstudents GROUP BY gender having gender='M' 返回有限 的行 limit select* from, students limit 2 select* from, students limit 2,3 # 偏移兩行,顯示三行 SELECT語句的執行流程: FROM --> WHERE --->GROUP BY ---> HAVING ---> ORDER BY --SELECT ---> LIMIT SELECT語句后: DISTINCT:重復的值 只顯示一次 SQL_CACHE:緩存與查詢緩存中, SQL_NO_CACHE:不緩存 多表操作
     內連接:交集,缺點是,如果有的 NULL 不顯示 老方法:where 判斷 select * from students as s, teachers as t where s.teacherid=t.tid; 如果有相同的字段,可以加上表名.字段 select stuid,s.name,tid, s.name from students as s, teachers as t where s.teacherid=t.tid; 新方法:inner join ... on..... select s.name, s.age,t.name from students s inner join teachers t on s.age=t.age; 左外連接: 左邊表的全部內容,右邊的處理交集,都為NULL, left outer join select * from students s left outer join teachers t on s.teacherid=t.tid; 右外連接:right outer join ... on ... 注意表的先后順序; 對結果再次過濾: select * from students s left outer join teachers t on s.teacherid=t.tid where t.age>50; 左外連接去掉交集: select * from students s left outer join teachers t on s.teacherid=t.tid where t.tid is null; 右外連接去掉交集: 完全外鏈接:並集 select* from students s full outer join teachers t on s.teacherid=t.tid -----mysql 不支持 左外連接+ 右外連接+ union select * from students s left outer join teacher t on s.teacherid=t.tid -> union -> select * from stundents s right outer join teachers t on s.teacherid=t.tid 完全外連接去除交集: 上米昂的完全外鏈接,去掉公共部分 自連接:SELEsCT t.name,s.name FROM students s , students t where s.TID=t.tezcherID +-------+---------------+-----+--------+---------+-----------+ | TID | Name | Age | Gender | ClassID | TeacherID | +-------+---------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | 子查詢: 在查詢中嵌套的查詢 用於WHERE中的子查詢: 1、用於比較表達式中的子查詢 子查詢的返回值只能有一個 2、用於EXISTS中的子查詢 判斷存在與否 3、用於IN 中的子查詢 判斷存在於指定的列表中 SELECT name,classid from students 用於From的子查詢: SELECT alias.co1,... FROM (select clause) as alias where condition SELECT S.Name,s.Age, s.gender FROm (SELECT * FROM students WHERE gender='M') as s WHERE Age > 25 MySQL不擅長子查詢,應該避免使用,盡量使用聯合查詢 MySQL的聯合查詢: 表結構的合並: 縱向合並:字段數一直,數據類型一致。 union: select stuid,name,age,gender from students union select * from teachers; 有一模一樣的數,是可以去重的。 但是誰union誰是有區別的,還有字段名字 select * from teachers union select stuid,name,age,gender from students ; 自己union 自己,就會去重,但是一般都是有主鍵的; 橫向合並: cross join:交叉乘積 select * from students cross join teachers; +-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+ | StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender | +-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | 1 | Song Jiang | 45 | M | | 1 | Shi Zhongyu | 22 | M | 2 | 3 | 2 | Zhang Sanfeng | 94 | M | | 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F | | 1 | Shi Zhongyu | 22 | M | 2 | 3 | 4 | Lin Chaoying | 93 | F | | 1 | Shi Zhongyu | 22 | M | 2 | 3 | 5 | Yu Yutong | 26 | M | EXPLAIN select 語句: 顯示查詢詳細細節,可以看用到索引沒 等信息 mysql> EXPLAIN select * from students s, teachers t where s.teacherid = t.tid\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: s type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 25 Extra: *************************** 2. row *************************** id: 1 select_type: SIMPLE table: t type: ALL possible_keys: PRIMARY key: NULL key_len: NULL ref: NULL rows: 4 Extra: Using where; Using join buffer 視圖: 虛表 存儲下來的 select 語句:執行結果返回 create view stu AS SELECT Name,Age FROM students; show tables; show create view stu;查看創建過程 可以設置用戶 訪問view,就只能訪問某些字段 插入數據: 可以插入數據,同時插入到原表中,但是如果視圖設置了過濾條件,比如age>30 插入的20 ,是插不到視圖,但是還是能插到原表中 刪除: DROP VIEW stu; 查看waring:只能在剛出現warings后查看,在期間執行其他語句后,就查不到了 show warings; 插入:INSERT 第一種: INSERT INTO tb_name [(col1,col2...)]{VALUES|VALUE} (val11,val12...) (val21,val22...) 第二種: INSERT INTO tb_nam SET col=val1 ,col2=val2 第三種: INSERT INTO tb_name SELECT clause RAPLACE: 如果定義了主鍵的,唯一鍵的,只能替換,重復的不能插入 使用方式同INSERT 更新:可以多表,一般少用 UPDATE UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET col_name1=val1 [, col_name2=val2] ... [WHERE where_condition] [ORDER BY ...] [LIMIT row_count] UPDATE 通常必須使用WHERE 子句或者 LIMIT 限制要修改的行數 UPDATE student_count SET student_count=student_count+1; --safe-update:避免因為沒有where 全改了 DELETE: DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [WHERE where_condition] [ORDER BY ...] [LIMIT row_count] DELETE FROM students WHERE stuid = uid; 函數:不怎么使用 函數是有作用域的,某個庫的,不能被其他庫調用,(通過其他方式可以實現) show function status; 查看所有的函數 存儲於mysql庫中的proc表中 DELIMITER ; 設置語句結束符 函數:系統函數和自定義函數 系統函數:https://dev.mysql.com/doc/refman/5.7/en/func-op-summary- ref.html 自定義函數 (user-defined function UDF) 保存在mysql.proc表中 創建UDF CREATE [AGGREGATE] FUNCTION function_name(parameter_nametype,[parameter_name type,...])RETURNS {STRING|INTEGER|REAL} runtime_body 說明: 參數可以有多個,也可以沒有參數 必須有且只有一個返回值 自定義函數 創建函數 示例:無參UDF CREATE FUNCTION simpleFun() RETURNS VARCHAR(20) RETURN "Hello World!”; 查看函數列表: SHOW FUNCTION STATUS; 查看函數定義 SHOW CREATE FUNCTION function_name 刪除UDF: DROP FUNCTION function_name 調用自定義函數語法: SELECT function_name(parameter_value,...) 示例:有參數UDF DELIMITER // CREATE FUNCTION deleteById(uid SMALLINT UNSIGNED) RETURNS VARCHAR(20) BEGIN DELETE FROM students WHERE stuid = uid; RETURN (SELECT COUNT(stuid) FROM students); END// DELIMITER ;  自定義函數中定義局部變量語法 DECLARE 變量1[,變量2,... ]變量類型 [DEFAULT 默認值]  說明:局部變量的作用范圍是在BEGIN...END程序中,而且定義局部變量語句必須在 BEGIN...END的第一行定義  示例: DELIMITER // CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, Y SMALLINT UNSIGNED) RETURNS SMALLINT BEGIN DECLARE a, b SMALLINT UNSIGNED; SET a = x, b = y; RETURN a+b; END// DELIMITER ; 為變量賦值語法 SET parameter_name = value[,parameter_name = value...] SELECT INTO parameter_name 示例: ... DECLARE x int; ----只能在函數中調用 SELECT COUNT(id) FROM tdb_name INTO x; RETURN x; END// MySQL管理: 第一層:面向連接,用戶請求的連接,管理釋放。 Mysql是明文的,支持文本和二進制兩種格式的傳輸。 加密:基於SSL 第二層:MySQL核心服務層,BIF(內置函數),視圖等。。。 分析器:語法分析,語句切片等完成優化(yacc,lex分析器,開源的) 優化器:語句重構,多表查詢,調整順序,選擇開銷最小的索引 EXPLAIN: 第三層:存儲引擎,負責數據的存儲和提取。 MySQL鎖: 執行操作時,施加的鎖模式: 讀鎖:共享鎖,A讀,不會影響B的讀 寫鎖:獨占鎖,排他鎖,不能查,寫, 其他可能查到,因為緩存,要不這樣,關閉query_cache_wlock.... 鎖粒度: 表鎖:table lock 鎖定了整張表 行鎖:row lock 鎖定了需要的行 粒度越小,開銷越大,但並發性越好 鎖的實現位置: MySQL鎖(第二層):顯示鎖,可以手動施加 存儲引擎鎖(第三層):隱式鎖,自動的 顯示鎖: LOCK TABLES; UNLOCK TABLES; LOCK TABLES tbl_name lock_type [, tbl_name lock_type] ... UNLOCK TABLES; 施加讀鎖,不影響別人讀,但是別人不能鎖,只有釋放,別人才能寫,自己也不能寫 施加寫鎖, 別人不能讀,也不能寫 InnoDB存儲引擎 也支持另外一種顯示鎖(鎖定挑選出的部分行,行級鎖) SELECT .... LOCK IN SHARE MODE; SELECT .... FOR UPDATE; 先 show tables classes status; 查看引擎類型 注意:鎖是在執行語句的過程中加入的,語句執行完,就失效了 SELECT * FROM classes WHERE ClassID
<= 3 LOCK IN SHARE MODE; SELECT * FROM classes WHERE ClassID <= 3 FOR UPDATE; 事務:Transaction 事務就是一組原子性的查詢語句(查詢—*****),也即將多個查詢當作一個獨立的工作單元。 ACID測試:能滿足ACID 的測試,就表示能支持事務,兼容事務 A:atomictiy原子性,一個事務被視為一個不可分割的單元,要不執行,要不都不執行 C:Consistency ,一致性, A 轉賬B 總金額是不變的,從一個一致性狀態,到另一個一致性狀態 I:isolation,隔離性,事務所做的操作,在提交之前,別人是看不到的 A -300的過程,別人看不到A 減少了300 (在沒提交之前) D:durability,持久性,一旦事務提交了,其所作的修改就會永久有效 隔離級別: READ - UNCOMMITED :讀尚未提交,安全性差,並發好點(別人也能看到你沒有提交的數據),會出現臟讀,出現不可重復讀(兩次結果不一致,一個是未提交,一個是提交之后) READ - COMMITTED (讀提交,未提交的看不到,不可重讀) REPEATABLE READ(可重讀,解決臟讀),出現幻讀 ---mysql,兩個人同時是操作數據庫,未提交,看到兩種不同結果 A 刪除了一條,也提交了 B 還是沒有看到刪除的,只有自己提交,在開啟,才能看到刪除的 便於數據備份,備份過程中數據不變 SERIALIZABLE 可串行化,隔離級別最高,但是性能太低(事務串行執行) 事務的未提交讀 組織別人的寫 A 為提交 B 阻塞 > start transaction > commit > rollback 全部回滾 > savepoint point_name > rollabck to point_name 提交事務后,不能回滾的(顯示開啟,顯示提交) innodb支持自動提交事務(非顯示開啟),每一條語句都是一個事務,行級鎖 SHOW GLOBAL VARIABLES LIKE '%commit%' SET GLOBAL autocommit = 0(記得手動開啟,手動提交) 查看隔離級別: SHOW GLOBAL VARIABLES LIKE '%iso%' 或 SELECT @@global.tx_isolation 注意:服務器端修改 transaction-tx_isolation 建議:對事務要求不特別的嚴格,可以使用讀題交 MySQL如何實現: MVCC:多版本並發控制的內在機制實現的 每個事務啟動時,InnoDB為每個啟動的事務提供一個當下的快照,后續的操作,都在快照上操作 為了實現此功能,InnoDB 會為每個表提供兩隱藏的字段: 一個用於保存行的創建時間,一個用於保存行的失效時間 里面存儲的是系統版本號: 只在兩個隔離級別下有效:讀提交,可重讀(默認) MySQL存儲引擎: SHOW ENGINES; SHOW TABLES STATUS [LIKE ''] [WHERE 語句] SHOW TABLES STATUS IN hellodb; SHOW TABLE STATUS IN hellodb WHERE name='classes'\G :查看庫中某個表的引擎 *************************** 1. row *************************** Name: classes 表名 Engine: InnoDB 存儲引擎 Version: 10 版本 Row_format: Compact 行格式(創建表的時候有)ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} 表格式 Rows: 9 表中的行數,innodb未必精確,mvcc機制導致可能存在鏡像 Avg_row_length: 1820 行的平均長度(字節) Data_length: 16384 表的數據總體大小 Max_data_length: 0 表的最大空間 Index_length: 0 索引的最大長度 Data_free: 9437184 可以用來存儲的空間,但是未用的空間,也包括刪除行釋放的空間 Auto_increment: 10 自動增長(下一ge的值) Create_time: 2018-10-26 11:52:27 表創建時間 Update_time: null 表數據的最近一次的修改時間 Check_time: NULL 使用CHECK TABLE 或myisamchk最近一次檢測標的時間 Collation: utf8_general_ci 排序規則 Checksum: NULL 如果啟用,則為表的checksum Create_options: 創建表時指定的其他選項 Comment: 表的注釋、如果是視圖,顯示VIEW,其他的為NILL 存儲引擎也通常稱為’表類型‘ MyISAM: db_name.frm db_name.MYD db_name.MYI InnoDB: 第一種格式:innodb_file_per_table=off 共享表空間 ibdata # 達到一定大小,啟動新的(數據目錄下) tb_name.frm 第二種;innodb_file_per_table=on 獨立表空間 每個表在數據庫目錄下存儲兩個文件 tb_name.frm tb_name.idb 表空間:table space 由InnoDB管理的特有格式數據文件,Innodb使用聚簇索引 show engines; SHOW VARIABLES LIKE '%ENGINE%'; default_storage_engine 服務變量實現 各存儲引擎的特性:存儲引擎比較:https://docs.oracle.com/cd/E17952_01/mysql-5.5-en/storage-engines.html 事務日志:隨機IO 改為順序IO(是一段連續的空間) 數據目錄下 ib_logfile{1,0},一般是兩個 InnoDB: 事務:事務日志 外鍵: MVCC: 聚簇索引: 聚簇索引之外的索引,通常稱為 輔助索引,不是指向數據,而是指向聚餐索引的 聚簇索引和數據是存放在一塊的。一張表,聚簇索引只能有一個。否則就會亂套 輔助索引可以多個。 輔助索指針指向的是聚簇索引(InnoDB) 輔助索引 ---> 聚簇索引 ---> 數據本身 主鍵 作為聚簇索引。 輔助索引、聚簇索引 是基於位置的。 輔助索引、聚簇索引都是 B+tree 索引(也就是說內部結構) 行級鎖:間隙鎖 支持輔助索引 支持自適應的hash索引 支持熱備份 MyISAM: 全文索引 (Mroonga引擎) 壓縮(做數據倉庫,節約空間,IO次數減少) 空間索引(通過空間函數) 表級鎖 延遲更新索引 不支持事務 不支持外鍵 不支持MVCC 不支持行級鎖 奔潰后,無法安全恢復 使用場景:只讀數據(數據倉庫),較小的表,能忍受數據丟失(崩潰后,數據恢復能力差,非事務) ARCHIVE: 僅支持INSERT 和 SELECT 支持很好的壓縮 適用於存儲日志信息,或其他按時間序列實現的數據采集類的應用。 支持行級鎖和專用緩存區 CSV: CSV存儲引擎使用逗號分隔值格式將數據存儲在文本文件中。可以使用 CSV引擎以CSV格式導入和導出其他軟件和應用程序之間的數據交換 不支持數據索引 僅適用於數據交換場景 BLACKHOLE : 黑洞存儲引擎接受但不存儲數據,檢索總是返回一個空集。該功 能可用於分布式數據庫設計,數據自動復制,但不是本地存儲 沒有存儲機制,常用於多級復制架構中做中轉服務區 MEMORY: 保存數據在內存中,內存表,實現臨時表,保存中間數據,周期性的聚合數據等。 僅支持hash索引,適用表級鎖,不支持BLOB 和text數據類型 MRG_MYISAM: 把兩個MyISAM連到一起,能夠將多個MyISAAM合並成一個虛表 NDB: MySQL CLUSTER 中專用的存儲引擎 第三方存儲引擎: OLTP:在線事務處理: XtraDB:增強版的InnoDB, 由Percona提供 編譯安裝時,下載xtradb 的原碼 替換mysql存儲引擎中的InnoDB的原碼 PBXT:MariaDB自帶 支持引擎級別的復制操作 支持引擎級別的外加約束, 對SSD磁盤提供適當支持 支持MVCC TokuDB: 使用Fractal Trees索引,沒有鎖片問題,適合在大數據領域,有和好的壓縮比 被引入 MariaDB 列式存儲引擎: Infobright:目前較有名的劣勢引擎,適用於海量數據存儲場景,PB級別的,專為數據分析和數據倉庫設計 InfiniDB MonetDB LucidDB 開源社區存儲引擎: Aria:前身Maria, 可理解為增強版的MyIS AM ,支持奔潰后恢復,支持數據緩存 Groona:全文索引引擎,用在搜索引擎上。Mroonga是改進版 QQGraph:Open Query開發,支持圖結的存儲引擎 SphinxSE:整合到MariaDB 中,全文搜索服務器提供了sql接口 Spider:將數據切片,能將數據分成不同的切片,比較透明的實現了分片,並支持在分片上支持並行查詢 如何選擇: 是否需要事務 是否需要備份,以及備份類型 崩潰后的恢復 ; 特有的特性(如,利用特有特性) 如果多個要求一致,做性能測試,再做出選擇 索引類型: 聚簇索引 輔助索引 B樹索引 R樹索引 hash索引 全文索引 Mysql用戶管理: 用戶賬號: username@hostname, password 用戶賬號管理: CREATE USER DROP USER RENAME USER SET PASSWORD 權限管理: GRANT:同時還可以創建用戶 REVOKE: CREATE TEMPORARY TABLES:創建臨時表,內存中 SHOW PROCESSLIST:顯示當前運行的所有線程(跟用戶相關的)mysqladmin那塊有提到 MySQL權限級別: 庫級別: 表級別: 字段級別: 管理類: CREATE USER CREATE USER username@hostname [ IDENTIFIED BY [PASSWORD] 'password' ] CREATE USER test@'192.168.%.%' IDENTIFIED BY '123456' 主機可以使用通配符: testuser@'192.168.100.1__' ----> 100-199 查看用戶能都使用的權限: SHOW GRANTS FOR 'test'@192.168.%.%'; RENAME USER .... TO ...: RENAME USER 'test1'@'192.168.%.%' TO 'jack'@'192.168.%.%' SET: SET PASSWORD [FOR user] = { PASSWORD('cleartext password') | OLD_PASSWORD('cleartext password') | 'encrypted password' } SET PASSWORD FOR 'bob'@'%.example.org' = PASSWORD('cleartext password'); GRANT: 管理類權限: CREATE TEMPORARY TABLES CREATE USER FILE SHOW DATABASES SHUTDOWN SUPER REPLICATION SLAVE 復制 REPLICATION CLIENT LOCK TABLES PROCESS 數據庫級別,表級別 的權限: ALTER:修改表 ALTER ROUTINE:修改存儲函數,存儲過程 CREATE :創建表,庫 CREATE ROUTEINE CREATE VIEW 視圖 DROP:刪除表,庫 EXECUTE:執行函數或存儲過程 GRANT OPTION:轉增權限 INDEX: SHOW VIEW:是否有權限查看view 數據操作(表級別: SELECT INSERT UPDATE DELETE 字段相關的: SELECT (col,...) UPDATE(COl ,....) INSERT(col, ....) 命令: GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level TO user_specification [, user_specification] ... [REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}] [WITH with_option ...] GRANT PROXY ON user_specification TO user_specification [, user_specification] ... [WITH GRANT OPTION] object_type: TABLE | FUNCTION | PROCEDURE priv_level: * | *.* | db_name.* | db_name.tbl_name | tbl_name | db_name.routine_name user_specification: user [ IDENTIFIED BY [PASSWORD] 'password' | IDENTIFIED WITH auth_plugin [AS 'auth_string'] ] ssl_option: SSL with_option: GRANT OPTION | MAX_QUERIES_PER_HOUR count 多少次查詢 | MAX_UPDATES_PER_HOUR count 更新次數 | MAX_CONNECTIONS_PER_HOUR count 最大建立個數 | MAX_USER_CONNECTIONS count 使用同一個賬戶,同時連接幾次 GRANT CREATEE ON hellodb.* TO 'test'@'%' IDENTIFIED BY '123456' 獲得創建庫的權限,必須對庫的所有表有權限,才能創建庫 REVOKE:收回授權: REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level FROM user [, user] ... REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ... REVOKE CREATE ON test.t FROM test@'%' 授權信息表: mysql庫下的 db:庫級別的權限 host:主機級別,廢棄 tables_priv:表級別 colomns_priv:列級別的 procs_priv:存儲過程和存儲函數相關的授權 proxies_priv:代理用戶的權限 FLUSH!!!!!!!!!!!!! 如果連接多次被拒絕了,需要清理一下host文件 如果root用戶密碼忘了? 配置mysqld中添加:skip-grant-tables 如何從mysql 升級到 mariadb MySQL查詢緩存: 用於保存Mysql 查詢語句返回的完整結果,被命中時,Msyql 會立即返回,省去解析,優化,執行等過程。 如何檢查緩存: Mysql保存數據於緩存中: 把select語句本身做hash計算,計算的結果作為key,查詢的結果作為value 次數命中率,字節命中率 什么樣的語句不能被緩存: 查詢語句中有一些不確定數據,用戶自定義函數,存儲函數,用戶定義變量,臨時表,系統表,或權限表 緩存帶來的額外開銷: 1、每個查詢都得先查詢是否命中 2、查詢結果先緩存 3、內存有限,而且還要分配內存大小,lru刪除,還可能產生內存碎片等等 mysql> show global variables like 'query_cache%'; +------------------------------+----------+ | Variable_name | Value | +------------------------------+----------+ | query_cache_limit | 1048576 | | query_cache_min_res_unit | 4096 | | query_cache_size | 16777216 | | query_cache_type | ON | | query_cache_wlock_invalidate | OFF | +------------------------------+----------+ query_cache_type:查詢緩存類型,是否開啟緩存功能,開啟方式有三種,ON, OFF ,EDMAND DEMAND SELECT SQL_CACHE .... select語句只有加SQL_CACHE這句,才緩存 query_cache_size:緩存使用的總空間,單位字節,大小是1024的整數倍 mysql啟動時,一次性分配,並立即初始化這里的指定大小空間 如果修改此大小,會清空全部緩存,並重新初始化 query_cache_min_res_unit:存儲緩存的最小內存塊 (query_cache_size - Qcache_free_memory)/Qcache_queries_in_cache 獲取一個理想值 query_cache_limit:一個查詢語句緩存的最大值(先緩存,如果超過了,再刪除 ,又降低性能) 手動使用SQL_NO_CACHE 可以人為的避免嘗試緩存返回結果超出此參數限定值的語句 query_cache_wlock_invalidate: 如果某個表被其他的用戶鎖住,是否從緩存中返回結果,OFF 表示返回。 如何判斷命中率: 次數命中率: 狀態變量是統計值,服務器變量是設定值******** SHOW GLOBAL STATUS LIKE 'Qcache%' mysql> SHOW GLOBAL STATUS LIKE 'Qcache%'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Qcache_free_blocks | 1 | | Qcache_free_memory | 16759696 | | Qcache_hits | 0 | | Qcache_inserts | 0 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 3 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 1 | +-------------------------+----------+ Qcache_hits:命中次數 Qcache_free_memory:尚且空閑的空間,尚未分配 事先申請好的內存空間: Qcache_free_blocks:空閑塊數 Qcache_total_blocks:總塊數 Qcache_queries_in_cache:緩存中緩存的查詢個數 Qcache_inserts :緩存插入次數 Qcache_not_cached :沒有緩存的 Qcache_lowmem_prunes:內存太少,修剪(騰出)內存的次數 碎片整理: FLUSH QUERY_CACHE: 把小的集合起來 清空緩存: RESET: 命中率的估算方式: mysql> SHOW GLOBAL STATUS WHERE variable_name='Qcache_hits' OR variable_name='com_select'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Com_select | 3 | | Qcache_hits | 0 | +---------------+-------+ 緩沖命中,Com_select是不會增加 所以命中率 Qcache_hits / (Qcache_hits + Com_select) 也參考另外一個指標:命中和寫入的比率 Qcache_hits / Qcache)inserts 的值,大於3 表示緩存是有效的。 緩存優化使用的思路: 1、批量寫入,而非多次單個寫入 2、緩存空間不宜過大,因為大量緩存失效,會導致服務器假死 3、必要時,使用SQL_CACHE 和SQL_NO_CACHE 手動控制緩存 4、對寫密集型的應用場景來說,警用緩存反而能提高性能 M有SQL日志: 查詢日志:查詢相關的信息 慢查詢日志:查詢執行時長超過指定時長的查詢,未必是語句查詢慢,可能被其他線程阻塞 錯誤日志:啟動,關閉,復制線程(從服務器) 二進制日志:mysql中引起數據變化,mysql服務器改變的信息(修改的信息)MySQL復制的基本憑據 中繼日志:保存在從服務器上的日志,跟主服務器上的二進制日志相同,用完可以刪除。 事務日志:已提交數據,保存,未提交數據,回滾。 隨機IO 轉換為 順序IO 日志文件組:至少有兩個日志文件 注意:盡可能使用小事務 因為,如果事務大,事務日志中放不下,就會存到磁盤中,但是如果回滾,磁盤中的也得刪除,這樣,開銷就會增大 ib_logfile{1|0} 兩個 InnoDB_buffer支持read操作 如何盡量保證事務日志和數據的安全: 1、磁盤,事務日志,分別放在raid上(raid 10, 或raid 1) 2、做鏡像 mysql> show global variables like 'innodb%'; +---------------------------------+------------------------+ | Variable_name | Value | +---------------------------------+------------------------+ | innodb_log_buffer_size | 8388608 | | innodb_log_file_size | 5242880 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | | innodb_max_dirty_pages_pct | 75 | | innodb_max_purge_lag | 0 | | innodb_mirrored_log_groups | 1 | | innodb_old_blocks_pct | 37 | | innodb_old_blocks_time | 0 | 查詢日志;默認關閉 ---- 一般不要開啟 (動態變量) log = ON|OFF 是否記錄所有的語句的日志信息與一般產需日志文件(general_log) log_output = TABLE| FILE | NONE :TABLE 和FILE 可以同時出現,用逗號分隔 general_log:是否啟用查詢日志 general_log_file:定義了一般查詢日志保存文件 ---一般是 主機名。log 此選項 ,取決 log_output 是什么類型,只有FILE 的時候,次選項才能生效 開啟:(兩個都得打開) SET GLOBAL log='ON' SET GLOBAL general_log='ON' 記錄到數據庫: SET GLOBAL log_output=’table'; mysql.general_log 表中 慢查詢日志: mysql> show global variables like 'long%'; 指定時間,多長時間才算慢 +-----------------+-----------+ | Variable_name | Value | +-----------------+-----------+ | long_query_time | 10.000000 | +-----------------+-----------+ slow_query_log OFF|ON 是啟用慢查詢 ,輸出位置取決於log_ouput=FILE| TABLE| NONE log_slow_queries ON|OFF slow_query_log_file /mydata/data/node1-slow.log 如果log_ouput = FILE保存位置 記錄到: mysql.low_log查看 錯誤日志: 服務器啟動和關閉信息: 服務器運行中的錯誤信息 事件調度器運行一個事件產生的信息; 在復制架構中從服務器上啟動從服務器線程時產生的信息; log_error /mydata/data/node1.err log_warnings 1 :是否記錄警告信息 二進制日志:記錄的是,可能修改數據,或修改數據的信息 一般在數據目錄下 使用 mysqlbinlog 查看 position:位置 time:時間 滾動:每一個日志文件不能過大 1、按照大小 2、按照時間 3、按照服務器啟動 SHOW BINARY LOGS; 從開始到當前mysql服務器使用了的二進制文件 記錄在 x.index文件中 功能: 時間點恢復: 復制: PURGE:刪除日志 PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr } 示例: PURGE BINARY LOGS TO ‘mariadb-bin.000003’;刪除3之前的日志 PURGE BINARY LOGS BEFORE '2017-01-23'; PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30'; 刪除所有二進制日志,index文件重新記數 RESET MASTER [TO #]; 刪除所有二進制日志文件,並重新生成日志文 件,文件名從#開始記數,默認從1開始,一般是master主機第一次啟動時執行,MariaDB10.1.6開始支持TO # SHOW MASTER STATUS;查看日志信息 FLUSH LOGS;重啟一個新的日志文件,滾動日志 SHOW BINARY LOGS; mysql> SHOW BINARY LOGS; +---------------+-----------+ | Log_name | File_size | +---------------+-----------+ | binlog.000015 | 724935 | | binlog.000016 | 733481 | +---------------+-----------+ SHOW BINLOG EVENTS 查看二進制文件 SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count] eg: SHOW BINLOG EVENTS IN 'aria_log.00000001' SHOW BINLOG EVENTS IN 'aria_log.00000001' FROM 66761: 從指定的位置查看 mysqlbinlog: --start-time --stop-time --start-poditon --stop-positon mysqlbinlog --start-positon= mysql-bin.log000001 > /a.sql server-id: 服務器身份標識 Mysql記錄二進制日志格式有兩種: 1、基於語句:statment, 2、基於行:row:更精確 CURRENT_DATE():這種,只能基於行,基於語句,時間就不對了 3、混合模式:mixed 二進制日志文件的內容格式: 時間發生的時間和日期 服務器的ID 事件的結束位置 事件的類型 原服務器生成此事件的線程ID 語句的時間戳和寫入二進制日志文件的時間差 錯誤代碼 事件內容 事件位置,也就是下一個事件的開始位置 服務器參數: log-bin log-bin-trust-function-creators sql_log_bin sync_binlog:記錄緩沖的 多久同步到磁盤中,0 不同步 log-bin = {ON|OFF|path} 文件路徑,哪個路徑下的文件中 ON 默認 mysql...00001 sql_log_bin = {ON|off} 會話級別參數,是否記錄到二進制文件中,只有SUPER權限才可以修改 binlog_format = {statement | row|mixed} max_binlog_cache_size = 二進制日志緩沖空間大小,僅用於緩沖實物類的語句 max_binlog_stmt_cache_size = 非事務類和事務類 共用的空間大小 max_binlog_size 二進制日志文件的大小 建議:二進制日志 與 數據文件 不要放在同一設備上 中繼日志: relay-log | relay_log | relay_log_index | relay_log_info_file relay-log.info | relay_log_purge ON 是否清理不用的中繼日志 | relay_log_recovery OFF | relay_log_space_limit 0 空間大小是否有限定 備份 和 恢復: 1、災難恢復 2、審計 (某一數據在某一時刻是什么樣的) 3、測試 備份:目的用於恢復,對備份數據做定期的恢復測試 備份類型: 根據備份時,服務器是否在線: 冷備:離線狀態 熱備:基於事務的 溫備:全局施加共享鎖,阻止寫 根據備份的數據集: 完全備份: 部分備份: 根據備份時的接口(直接備份數據文件還是通過mysql服務器導出數據) 物理備份:直接復制數據文件的備份方式,存儲引擎必須一致 邏輯備份:把數據從庫中提取出來保存為文本文件,可以基於網絡恢復,與存儲引擎無關,避免數據恢復 缺點:速度慢,占據空間大。無法保證浮點數的精度,還原回來的數據需要 重建索引。(不適合數據量大的,慢) 工具:mysqldump 根據備份時是備份變化數據,還是整個數據: 完全備份; 增量備份: | |_________1________2________3 |---------> -------> --------> 完全備份 + 增量備份 + 二進制即使點恢復 + 回滾 差異備份:(容易備份) | |_________1________2________3 |---------> |------------------> |----------------------------> 備份策略: 選擇備份時間,備份方式,備份成本(鎖時間,備份時長,備份負載),恢復成本 備份對象: 數據; 配置文件 代碼:存儲過程,存儲函數,觸發器 OS相關的配置文件:crontabl配置計划及相關腳本 跟復制先關的配置信息 二進制日志文件。 常用的工具: mysqldump:邏輯備份工具 InnoDB 熱備,MyISAM溫備,Aria溫備 備份和恢復時間較慢 mysqldumper:多線程MySQLdump 很難實現差異或增量備份; lvm-snapshot: 接近於熱備的工具:因為要先請求全局所,而后創建快照,並在創建快照完成后釋放全局鎖 cp,tar等工具物理備份, 備份和恢復速度快 無法做增量備份,請求全局鎖需要等待一段時間 SELECT:部分備份工具: SELECT 語句 INTO OUTEFILE '/path/to/somefile' 恢復:LOAD DATA INFILE '/path/to/somefile' 僅備份數據,不會備份關系 Innobase:商業備份,innobackup Xtrabackup:由percona提供的開源備份工具。 InnoDB熱備,增量備份 MyISAM溫備,完全備份,不支持增量 物理備份,速度快 mysqlhotcopy:幾乎冷備 具體使用 mysqldump:邏輯備份時文本信息,可以二次編輯 還原的時候如果庫不在,需要手動闖將 步驟:備份單個庫(備份的文件里沒有創建庫的語句,所以建議使用--databases 1、mydqldump -uroot -hlocalhost -p hellodb > /tmp/bdb.sql /tmp/bdb.sql 是可以vim打開,二次編輯 2、恢復的時候,先創建庫, CREATE DATABSE hellodb 3、導入:mysql-uroot -hlocalhost -p hellodb < /tmp/bdb.sql 步驟:備份所有庫 msyqldump --all-databases > /tmp/all.sql 步驟:部分指定的多個庫,不需要手動創建庫 mysqldump --databases db1 db2 > /tmp/m.sql 注意:備份前要加鎖 --lock-all-tabes:請求鎖定所有表之后備份(讀鎖),對MyISAM,InnoDB,Aria 做溫備 --single-transaction:能夠對InnoDB引擎 實現熱備(就不用--lock-all-tabes) 備份代碼: --events:備份事件調度器代碼 --routines:備份存儲過程和存儲函數 --triggers:備份觸發器 備份時 滾動日志: --flush-logs:備份前,請求到鎖之后滾動日志 復制時的同步標記: --master-data = 0,1,2 0:不記錄 1:記錄為CHANGE MASTER 語句 2:記錄為是注釋的CHANGE MASTER 的語句 使用mysqldump備份: 請求鎖:--lock-all-tables或--singe-transaction 進行INNODB熱備 滾動日志: --flush-logs 選定要被扥的庫: --databases 指定二進制日志文件及位置 --master-data 實例: 手動施加全局鎖: 1、FLUSH TABLES WITH READ LOCK:緩存中的同步到磁盤,同時施加全局讀鎖 2、FLUSH LOGS 3、SHOW MASTER STATUS 4、mysqldump --databases hdb > /tmp/hdb.sql 5、UNLOCK TABLES; mysqldump --databases hdb --lock-all-tables --flush-logs > /tmp/hdb2.sql (溫備) 熱備:(全是innodb引擎) mysqldump --databases hdb --single-transaction --flush-logs > /tmp/hdb2.sql 恢復: 即使點恢復 一次完成過程: 備份: 1、先查看 存儲引擎: 2、 mysqldump --databases hdb --lock-all-tables --flush-logs --master-data=2 > /tmp/hdb2.sql (溫備) 查看hdb2.sql 有一句:注釋掉的語句: -- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.00005',MASTER_LOG_POS=367 也就是說,下次即使點恢復,從此二進制文件的367位置開始往后 3、備份之后,又在表中插入數據等操作,而后,不小心把表刪了 4、恢復到表刪除之前: 4.1、先找到二進制文件,並備份保存 4.2、mysqlbinlog --start-positions=367 master-bin.00005 在里邊找,不小心刪除的語句之前的一個位置 4.3、保存二進制文件 mysqlbinlog --start-positions=367 --stop-positons=669 master-bin.00005 > /tmp/hdb2.inc.sql 4.4、因為不需要恢復的日志,不需要記錄,所以先關掉, SET SESSION sql_log_bin=0 5、導入完全備份: SHOW MASTERS STATUS;查看位置對不 mysql> source /tmp/hdb2.sql 6、增量 恢復: mysql> source /tmp/hdb2.inc.sql 7、SET SESSION sql_log_bin=1 注:恢復,關閉二進制文件,關閉其他用戶連接(關閉全局二進制日志) 備份策略:基於mysqldump 備份:mysqdump +二進制日志文件 周日做一次完全備份:備份的同時滾動日志(下次二進制就從新的文件開始) 周一-周六:備份二進制日志 恢復: 完全備份 +各二進制文件至此刻事件 lvm-snapshot: 快照卷,獲得文件的一致性通路 作為原卷的訪問路徑, 剛創建是沒有內容,指向原卷, 修改的數據,文件先復制到快照卷,未修改的來自原卷,修改的來自快照卷 1、事務日志 跟 數據文件 必須在同一個卷上,兩個卷不能保證時間一致 2、創建快照卷之前,要請求全局鎖; 快照創建完之后,釋放鎖 3、請求全局鎖完成之后,做一次日志滾動。做二進制日志文件及位置標記 實例:/mydata/data 1、lvs 看下邏輯卷 LV VG mydata myvg 2、FLUSH LOGS WITH LOCK READ; 刷新日志,並施加鎖 3、mysql -e 'show master status' > /binlog.pos 記錄位置 4、lvcreat -L 100M -s -n mydata-snap -p -r /dev/myvg/mydata lvs :查看 5、unlock tables; 6、掛載 快照卷 mount /dev/myvg/mydata /mnt -o ro 7、之后又進行了操作,如插圖數據 8、開始備份 cd /mnt/data/ cp data/ /backup/data-2018-10-25 -a (歸檔模式,保證原權限) 9、卸載快照卷 10、一不小心刪了/mydata/data/ 11、二進制文件在 /mydata/binlog/ 12、到新電腦上,安裝mysql 13、cp /backup/data-2018-10-25/* /mydata/data/ 確保權限mysql.mysql 14、啟動mysqld 15、基於二進制還原 原電腦上 根據剛才記住的位置,和文件 導出二進制文件內容 mysqlbinlog --start-positions=367 /mydata/binlog/master-bin.000009 | mysql Xtrabackup(percona):實現增量備份 innobackupex:需要服務器處於運行狀態 注意: 1、要將數據和備份放在不同的磁盤設備上,異機 或異地設備存儲最為理想 2、備份的數據,應該周期性的進行還原測試 3、每一次災難恢復后,都應該做一次完全備份 4、針對不同規模或級別的數量,要定制好備份策略 5、做好二進制日志備份,並跟數據 放在不同磁盤上, 從備份中恢復應該遵循步驟: 1、停止MySQL服務器(mysqldump不能) 2、記錄服務器的配置和文件權限 3、將數據從備份移到MySQL數據目錄中,執行方式,依賴於工具 4、改變配置和文件權限 5、以限制訪問模塊重啟服務器,mysql的--skip-networking選項跳過網絡功能 方法:編輯my.cnf skip-networking soket=/tmp/mysql-recorvery.socket 6、載入邏輯備份(如果有) ,而后檢查和重放二進制日志 7、檢查已經還原的數據 8、重新以完全訪問模式重啟服務器。 注釋前面在my.cnf中添加的選項,並重啟 SELECT .... INTO OUTEFILE '/tmp/stu.sql.txt' 這種方式需要手動創建表格式 testtb LOAD DATA INFILE '...' INTO TABLE testtb

 


免責聲明!

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



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