更多內容請點擊:html
Linux學習從入門到打死也不放棄,徹底筆記整理(持續更新,求收藏,求點贊~~~~)
前端
https://blog.51cto.com/13683480/2095439java
第22章,mysql數據庫-1mysql
本章內容:linux
關係型數據庫基礎c++
mariadb 安裝和使用正則表達式
二進制安裝mariadbsql
源碼編譯安裝mariadbshell
MYSQL體系架構數據庫
存儲引擎介紹
SQL語句使用
視圖,函數,存儲過程
流程控制和觸發器
數據庫基礎:
數據的時代:
涉及的數據量愈來愈大
數據不隨程序的結束而消失
數據被多個程序共享
大數據
數據庫的發展史:
萌芽階段:使用磁盤文件系統來存儲數據
初級階段:使用層級模型,網狀模型的數據庫
中級階段:關係型數據庫和結構化查詢語言
高級階段:」關係-對象「 型數據庫
文件管理系統的缺點:
編寫應用程序不方便
數據冗餘不可避免
應用程序依賴性
不支持對文件的併發訪問
數據間聯繫弱
難以按用戶視圖表示數據
無安全控制功能
數據庫管理系統的優勢:
相關關聯的數據的集合
較少的數據冗餘
程序和數據相互獨立
保證數據的安全、可靠
最大限度地保證數據的正確性
數據能夠併發使用並能同時保證一致性
數據庫管理系統:
DBMS(database management system)
數據庫是數據的聚集,它以必定的組織形式存於存儲介質上
DBMS是管理數據庫的系統軟件,它實現數據庫系統的各類功能。是數據庫系統的核心
DBA:(database administrator)負責數據庫的規劃,設計,協調,維護和管理等工做
應用程序指以數據庫爲基礎的應用程序
數據庫管理系統的基本功能:
數據定義
數據處理
數據安全
數據備份
數據庫系統架構:
單機架構
大型主機/終端架構
C/S主從式架構
分佈式架構
關係型數據庫:
RDBMS:
關係:關係就是二維表,並知足必定規則
行:row,表中的每一行,又稱爲一條記錄
列:column,表中的每一列,稱爲屬性,字段
主鍵:(Primary key):用於惟一肯定一個記錄的字段
域:domain:屬性的取值範圍,如性別只能是男和 女 兩個值
事務:transaction,多個操做被當作一個總體對待,具備ACID特性
ACID:
A: 原子性,整個事務被封裝成一個總體,具備總體原子性,要麼執行完成,
如執行途中被中斷,會將已執行的操做一一撤銷,回滾(rollback)到事務執行以前的狀態
C: 一致性,
I: 隔離性,併發執行時互相隔離,互補干涉
D: 一旦處理完成,將永久保留。不會回滾
數據三要素:
數據結構:
包含兩類:
1 數據類型、內容、性質有關的對象,好比關係模型中的域、屬性和關係等
2 與數據之間聯繫有關的對象,它從數據組織層表達數據記錄與字段的結構
數據的操做:
數據提取:在數據集合中提取感興趣的內容。(select)
數據更新:變動數據庫中的數據。(insert delete update)
數據的約束條件:是一組完整性規則的集合
實體(行)完整性 entity integrity
域(列)完整性 domain integrity
參考完整性 referential integrity
簡易數據規劃流程:
第一階段:收集數據,獲得字段
收集必要且完整的數據項
轉換成數據表的字段
第二階段:把字段分類,納入表,創建表的關聯
分隔數據表並創建關聯的有點:
節省空間
減小輸入錯誤
方便數據修改
第三階段:
規範化數據庫
數據庫的正規化分析:
RDBMS設計範式基礎概念:
設計關係數據庫時,聽從不一樣的規範要求,設計出合理的關係型數據庫,這些
不一樣的規範被稱爲不一樣的範式
範式呈遞次規範,越高的範式數據庫冗餘越小
目前關係數據庫有6種範式:1NF,2NF,3NF,巴德斯科範式BCNF,4NF,5NF
知足最低要求的範式是第一範式(1NF)
在第一範式的基礎上進一步知足更多規範要求的稱爲第二範式(2NF)
....
通常說來,數據庫只須要知足第三範式(3NF)便可
範式:
1NF:
無重複的列
每一列都是不可分割的基本數據項,同一列中不能有多個值。即實體中的某個屬性
不能有多個值或者不能有重複的屬性。
第一範式(1NF)是對關係模式的基本要求,不知足第一範式的數據庫就不是關係數據庫
2NF:
知足第一範式1NF
要求表中的每行必須能夠被惟一的區分,(經過一個字段,或多個字段)
一般爲表加上一個列,以存儲各個實例的惟一標識PK
屬性徹底依賴於主鍵
非PK的字段須要與整個PK有直接相關性
3NF:
知足第二範式2NF
屬性不依賴與其它非主屬性。
要求一張表中不能包含已在其餘表中已包含的且爲非主鍵的字段,
即,若是一張表的非主鍵字段包含在另外一張表中,則必需要主鍵
非PK的字段間不能有從屬關係
SQL概念:
SQL: Structure Query Language
機構化查詢語言
sql解釋器
數據存儲協議:基於C/S架構的應用層協議
S: server,監聽於套接字,接受並處理客戶端的應用請求
C: client
程序接口:
CLI 字符接口
GUI 圖形接口
應用編程接口:
ODBC: Open Database Connectivity 開放式數據庫鏈接
JDBC:Java Database Connettivity java數據庫鏈接
約束:constraint,表中的數據要遵照的限制
主鍵: 一個個多個字段的組合,填入的數據必須能在本表中惟一標識本行
必須提供數據,即NOT NULL,一個表只能有一個主鍵
惟一鍵:一個或多個字段的組合,填入的數據必須能在本表中惟一標識本行
容許爲NULL,一個表能夠存在多個
外鍵: 一個表中的某字段可填入的數據取決於另外一個表的主鍵或惟一鍵已有的數據
檢查: 字段值在必定範圍內
基本概念:
索引:
將表中的一個或多個字段中的數據複製一份另存,而且此些須要按特定次序排列存儲
關係運算:
選擇:挑選出符合條件的行 row
投影:挑選出符合條件的列 column
鏈接:表間字段的關聯
數據模型:
數據抽象:
物理層:數據存儲格式,級RDBMS 在磁盤上如何組織文件
邏輯層:DBA 角度,描述存儲什麼數據,以及數據間存在什麼樣的關係
視圖層:用戶角度,描述DB中的部分數據
關係模型的分類:
關係模型
基於對象的關係模型
半結構化的關係模型,xml數據
mariadb 安裝和簡單使用:---------------------------------------------------------------------
mariadb安裝方式:
1 源碼編譯安裝
2 二進制格式的程序包安裝
3 程序包管理器安裝
方法1 使用安裝光盤
方法2 項目官方yum源,安裝最新版
mariadb 安全初始化:
1 先使用yum安裝mariadb-server
yum install mariadb-server
安裝會自動安裝客戶端工具:mariadb
2 stytemctl start mariadb 啓動服務
使用客戶端工具:
/usr/bin/mysql 鏈接服務器
注意此時本機用戶,能夠任意鏈接服務器,且無需密碼,全部沒有安全保障
此時執行:
select user,host,password from mysql.user;
MariaDB [mysql]> select user,host,password from user;
+------+-------------+----------+
| user | host | password |
+------+-------------+----------+
| root | localhost | |
| root | 2-centos7.5 | |
| root | 127.0.0.1 | |
| root | ::1 | |
| | localhost | |
| | 2-centos7.5 | |
+------+-------------+----------+
6 rows in set (0.00 sec)
能夠看到password爲空,且包含2個匿名帳號
3 使用exit退出
執行:mysql_secure_installation 進行初始化
包括:
是否設置root帳號密碼
是否刪除匿名帳號
是否禁止root 遠程登陸
是否刪除test數據庫
4 執行完畢以後,(建議設置密碼),再次鏈接,需使用:
mysql -uroot -p
再次執行:
select user,host,password from mysql.user;
MariaDB [mysql]> select user,host,password from user;
+------+-------------+-------------------------------------------+
| user | host | password |
+------+-------------+-------------------------------------------+
| root | localhost | *128977E278358FF80A246B5046F51043A2B1FCED |
| root | 2-centos7.5 | *128977E278358FF80A246B5046F51043A2B1FCED |
| root | 127.0.0.1 | *128977E278358FF80A246B5046F51043A2B1FCED |
| root | ::1 | *128977E278358FF80A246B5046F51043A2B1FCED |
+------+-------------+-------------------------------------------+
4 rows in set (0.00 sec)
mariadb 程序:
客戶端程序:
mysql: 交互式的CLI工具
mysqldump:備份工具,基於mysql協議向mysqld發起查詢請求,並將查詢的全部數據
裝換成insert等寫操做語句保存文本文件中
mysqladmin:基於mysql協議管理mysqld
mysqllimport: 數據導入工具
myisam存儲引擎的管理工具:
myisamchk: 檢查myisam庫
myisampack: 打包myisam表,只讀
服務器端程序:
mysqld_safe
mysqld 獲取默認配置:mysqld --print-defaults
mysqld_multi
用戶帳號:
mysql用戶帳號由兩部分組成:
'username'@'host'
說明:
host限制此用戶可經過哪些遠程主機鏈接mysql服務器
支持使用通配符:
% 匹配任意長度的任意字符
172.20.0.0/255.255.0.0 或172.16.%.%
下劃線 _ 匹配任意單個字符
mysql客戶端:
鏈接數據庫
mysql -uroot -p
交互式模式:
可運行命令有兩類:
客戶端命令:\h,help 獲取幫助選項
\u,use 切換數據庫
\s,status 查看狀態
\!,system 執行shell命令
\R,prompt 修改mysql提示符
服務器端命令:
SQL語句; 必須使用;結尾
腳本模式:
mysql -uUSER -pPASSWORD < file.sql
mysql > source /path/from/somefile.sql
mysql客戶端可用選項:
-A,--no-auto-rehash 禁止補全
-u,--user= 用戶名,默認爲root
-h,--host= 服務器主機,默認爲localhost
-p,--port= 服務器端口
-S,--socket= 指定鏈接socket文件路徑
-D,--database= 指定默認數據庫
-C,--compress 啓用壓縮
-e,"SQL" 執行SQL命令
-V,--version 顯示版本
-v,--verbose 顯示詳細信息
--print-default 獲取程序默認使用的配置
--safe-updates| --i-am-a-dummy|-U 刪除提醒模式
命令示例:
use mysql 切換數據庫爲mysql
show tables;|databases 查看當前全部表|數據庫
select user(); 查看當前用戶
select version(); 查看數據庫版本
socket地址:
服務器監聽的兩種socket地址:
ip socket: 監聽在tcp的3306端口,支持遠程通訊
unix sock: 監聽在sock文件上,僅支持本機通訊
如:/var/lib/mysql/mysql.socket
說明:host爲localhost,127.0.0.1時自動使用unix.socket
服務器端配置:
服務器端:工做特性有多種配置方式
1 命令行選項:
2 配置文件:類ini格式
集中式的配置,可以爲mysql的各應用程序提供配置信息
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
[mysqld_multi]
[mysql]
[mysqldump]
[server]
[client]
格式說明:
parameter=value
_和- 相同
0,off,false 意義相同
1,on,true 意義相同
配置文件:
後面覆蓋前面的配置文件,順序以下
/etc/my.cnf
/etc/mysql/my.cnf /etc/my.cnf.d/*.cnf
sysconfdir/my.cnf
$MYSQL_HOME/my.cnf server-specific選項
--default-extra-file
~/.my.cnf user-specific選項
建議開啓的配置項:
innodb_file_per_table =on
skip_name_resolve =on
獲取可用參數列表:
mysqld --help --verbose
偵聽3306/tcp端口能夠綁定在一個或所有接口IP上
vim /etc/my.cnf
[mysqld]
skip-networking=1 關閉網絡鏈接,只偵聽本地客戶端
通用二級制格式安裝 mariadb :-----------------------------------------------------------
1 準備用戶和組
groupadd -r -g 306 mysql
useradd -r -g 306 -u 306 -d /mysqldb -s /sbin/nologin mysql
2 準備數據目錄,建議使用邏輯卷
使用單獨邏輯卷分區掛載 /mysqldb
chown mysql: /mysqldb
3 準備二進制程序,解壓縮,並建立軟連接,修改目錄權限
tar -xf mariadb-10.2.15-linux-x86_64.tar.gz -C /usr/local/
cd /usr/local/
ln -sv mariadb-10.2.15-linux-x86_64/ mysql
chown root:mysql mysql/
4 添加PATH路徑
vim /etc/profile.d/mysql.sh
PATH=/usr/local/mysql/bin:$PATH
5 準備配置文件,複製並適當修改
cd /usr/local/mysql/
cp support-files/my-huge.cnf /etc/mysql/my.cnf
vim /etc/mysql/my.cnf
添加項:
datadir =/mysqldb
innodb_file_per_table =on
skip_name_resolve =on
6 建立數據庫文件
cd /usr/local/mysql/
./scripts/mysql_install_db --datadir=/mysqldb --user=mysql
7 建立日誌文件
touch /var/log/mysqld.log
chown mysql /var/log/mysqld.log
8 準備服務腳本,啓動腳本
cp ./support-files/mysql.server /etc/rc.d/init.d/mysqld
chkconfig --add mysqld
systemctl start mysqld
9 安全初始化:
mysql_secure_installation
源碼編譯安裝 mariadb :--------------------------------------------------------------
1 安裝開發包組:
yum install bison bison-devel zlib-devel libcurl-devel libarchive-devel \
boost devel gcc gcc-c++ cmake libevent-devel gnutls-devel libaio-devel \
openssl-devel ncurses-devel libxml2-devel
2 添加用戶和組
groupadd -r -g 306 mysql
useradd -r -g 306 -u 306 -d /data/mysqldb mysql
3 準備數據目錄,建議使用邏輯卷
mkdir /data/mysqldb
chown mysql:mysql /data/mysqldb
4 解壓源碼包,並cd進解壓以後的目錄
編譯選項
https://dev.mysql.com/doc/refman/5.7/en/source-configuration-options.html
執行cmake
cmake . \
-DCMAKE_INSTALL_PREFIX=/app/mysql \
-DMYSQL_DATADIR=/data/mysqldb/ \
-DSYSCONFDIR=/etc \
-DMYSQL_USER=mysql \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITHOUT_MROONGA_STORAGE_ENGINE=1 \
-DWITH_DEBUG=0 \
-DWITH_READLINE=1 \
-DWITH_SSL=system \
-DWITH_ZLIB=system \
-DWITH_LIBWRAP=0 \
-DENABLED_LOCAL_INFILE=1 \
-DMYSQL_UNIX_ADDR=/app/mysql/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci
5 編譯並安裝
make && make install
6 添加path變量
echo 'PATH=/app/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
7 準備配置文件
mkdir /etc/mysql
cp support-files/my-huge.cnf /etc/mysql/my.cnf
vim /etc/mysql/my.cnf
添加:
datadir=/data/mysqldb
8 生成數據庫文件:
chown -R myslq:mysql /app/mysql
cd /app/mysql
./scripts/mysql_install_db --datadir=/data/mysqldb --user=mysql
9 準備啓動腳本
cp ./support-files/mysql.server /etc/init.d/mysqld
chkconfig --add mysqld
10 啓動服務並測試
service mysqld start
mysql刪除過程:------------------------------------------------------------------
1 刪除安裝目錄,rm -rf /app/mysql
2 刪除配置文件,rm -rf /etc/mysql;rm -rf /etc/my.cnf
3 刪除數據目錄,若有須要需提早備份或者轉移數據,rm -rf /data/mysqldb
4 若有須要,刪除二進制日誌目錄,rm -rf /data/mylog
5 刪除服務腳本,rm -rf /etc/init.d/mysqld
6 刪除編譯源碼目錄,rm -rf mariadb-10.2.15
7 刪除壓縮包 rm -rf mariadb-10.2.15.tar.gz
8 刪除mysql帳號和組 userdel -r mysql;groupdel mysql
9 刪除PASH變量
實現mariadb多實例:-------------------------------------------------------------
如今須要data目錄下新建3個多實例,基於端口開放3306,3307,3308
實現流程:
1 安裝mariadb,yum 編譯或者二進制安裝均可以
2 建立所需目錄
mkdir -pv /data/{3306,3307,3308}/{etc,data,pid,log,socket}
chown -R /data/*
3 複製並修改配置文件
cp /etc/my.cnf /data/3306/etc/my.cnf
vim /data/3306/etc/my.cnf
須要修改以下配置:
[mysqld]
port=3306
datadir=/data/3306/data
socket=/data/3306/socket/mysql.sock
[mysql_safe]
log-error=/data/3306/log/mariadb.log
pid-file=/data/3306/pid/mariadb.pid
#!includedir /etc/my.cnf.d 註釋掉此項
cp /data/3306/etc/my.cnf /data/3307/etc/my.cnf
vim /data/3307/etc/my.cnf
將3306改爲3307
cp /data/3306/etc/my.cnf /data/3308/etc/my.cnf
vim /data/3308/etc/my.cnf
將3306改爲3308
4 安裝生成數據庫文件
cd /basedir
./scripts/mysql_install_db --datadir=/data/3306/data --user=mysql
./scripts/mysql_install_db --datadir=/data/3307/data --user=mysql
./scripts/mysql_install_db --datadir=/data/3308/data --user=mysql
5 準配服務啓動腳本:
腳本會在步驟8 提供
cp /root/mysqld /data/3306/mysqld
vim /data/3306/mysqld
須要修改的項目:
port=3306 使用端口
mysql_pwd= 密碼,因爲新裝mairadb,還未安全初始化,密碼爲空
cmd_path="/usr/local/mysql/bin" 安裝二進制程序目錄
mysql_basedir="/data" 3306的父目錄
stop 函數中 -p 選項刪除,由於如今不須要密碼
如需使用,能夠設置密碼以後使用 -p 選項,
cp /data/3306/mysqld /data/3307/
cp /data/3306/mysqld /data/3308/
複製並修改端口號
6 啓動服務,執行
/data/3306/mysqld start |stop
/data/3307/mysqld start |stop
/data/3308/mysqld start |stap
7 鏈接數據庫:使用:
mysql -S /data/3306/socket/mysql.sock
mysql -S /data/3307/socket/mysql.sock
mysql -S /data/3308/socket/mysql.sock
8 啓動服務腳本:
#!/bin/bash
port=3306
mysql_user="root"
mysql_pwd=
cmd_path="/usr/local/mysql/bin"
mysql_basedir="/data"
mysql_sock="${mysql_basedir}/${port}/socket/mysql.sock"
function_start_mysql()
{
if [ ! -e "$mysql_sock" ];then
printf "Starting MySQL...\n"
${cmd_path}/mysqld_safe --defaults-file=${mysql_basedir}/${port}/etc/my.cnf &> /dev/null &
else
printf "MySQL is running...\n"
exit
fi
}
function_stop_mysql()
{
if [ ! -e "$mysql_sock" ];then
printf "MySQL is stopped...\n"
exit
else
printf "Stoping MySQL...\n"
${cmd_path}/mysqladmin -u ${mysql_user} -S ${mysql_sock} shutdown
fi
}
function_restart_mysql()
{
printf "Restarting MySQL...\n"
function_stop_mysql
sleep 2
function_start_mysql
}
case $1 in
start)
function_start_mysql
;;
stop)
function_stop_mysql
;;
restart)
function_restart_mysql
;;
*)
printf "Usage: ${mysql_basedir}/${port}/bin/mysqld {start|stop|restart}\n"
esac
---------------------------------------------------------------------------
MYSQL體系架構:-------------------------------------------------------------------
關係型數據庫的經常使用組件:
經常使用組件:
數據庫: database
表: table
行: row
列: column
索引: index
視圖: view
用戶: user
權限: privilege
存儲過程: proceduce,無返回值
存儲函數: function , 有返回值
觸發器: trigger
時間調度器:event scheduler ,任務計劃
命名規則:
1 必須以字母開頭
2 可包括數字和三個特殊字符( # _ $ )
3 不要使用mysql的保留字
create database select index table 等等
4 同一database (schema)下的對象不能同名
SQL語言歷史:
20世紀70年代,IBM開發出SQL,用於DB2
1981年,IBM推出SQL/DS 數據庫
業內標準:
微軟和Sybase的T-SQL,
Oracle的PL/SQL
SQL做爲關係型數據庫所使用的標準語言,最初是基於IBM的實如今1986年被批准的。
1987年,ISO 把ANSI-SQL 做爲國際標準
SQL:ANSI SQL
版本規範: SQL-86, -89,-92 -99,-03
SQL語法規範:
1 在數據庫系統中,SQL語句不區分大小寫(建議用大寫)
2 但字符串常量區分大小寫
3 SQL語句可單行或多行書寫,以;結尾
4 關鍵詞不能跨多行或簡寫
5 用空格和縮進來提升語句的可讀性
6 子句一般位於獨立行,便於編輯,提升可讀性
7 註釋:
SQL標準:
/*註釋內容*/ 多行註釋,也可單行,可插入
-- 註釋內容 單行註釋,注意有空格
MYSQL:
#
SQL 語句分類:
DDL:Data Defination Language 數據定義語言
CREATE,DROP,ALTER
DML: Data Manipulation Language 數據操做語言
INSERT,DELETE,UPDATE
DCL:Data Control Language 數據控制語言
GRANT,REVOKE
DQL:Data Query Language 數據查詢語言,有時也歸爲DML
SELECT
keyword:
SELECT
FROM
WHERE
SQL 語句構成:
keyword 組成 clause(條目,字句)
多條clause 組成語句
示例:
SELECT * SELECT 子句
FROM students FROM 子句
WHERE age>10 WHERR 子句
SELECT * FROM students WHERE age>10; 完整語句
MYSQL體系架構:------------------------------------------------------------------
mysql組成:
1 Connectors:
指的是不一樣語言中與SQL的交互
2 Management Serveices & Utilities:
系統管理和控制工具,例如備份恢復、Mysql複製、集羣等
3 Connection Pool: 鏈接池:
管理緩衝用戶鏈接、用戶名、密碼、權限校驗、線程處理等須要緩存的需求
4 SQL Interface: SQL接口:
接受用戶的SQL命令,而且返回用戶須要查詢的結果。好比select from就是調用SQL Interface
5 Parser: 解析器,
SQL命令傳遞到解析器的時候會被解析器驗證和解析。
解析器是由Lex和YACC實現的,是一個很長的腳本, 主要功能:
a . 將SQL語句分解成數據結構,並將這個結構傳遞到後續步驟,
之後SQL語句的傳遞和處理就是基於這個結構的
b. 若是在分解構成中遇到錯誤,那麼就說明這個sql語句是不合理的
6 Optimizer:
查詢優化器,SQL語句在查詢以前會使用查詢優化器對查詢進行優化。
他使用的是「選取-投影-聯接」策略進行查詢
7 Cache和Buffer(高速緩存區): 查詢緩存,
若是查詢緩存有命中的查詢結果,查詢語句就能夠直接去查詢緩存中取數據。
8 Engine :存儲引擎。
存儲引擎是MySql中具體的與文件打交道的子系統。也是Mysql最具備特點的一個地方。
Mysql的存儲引擎是插件式的。它根據MySql AB公司提供的文件訪問層的一個抽象接口
來定製一種文件訪問機制(這種訪問機制就叫存儲引擎)
mariadb特性:
插件式存儲引擎:也稱爲"表類型",存儲管理器有多種實現版本,功能和特性可能均略有差異
用戶能夠根據須要靈活選擇,Mysql5.5.5開始默認引擎爲innodb
單線程,多線程
諸多擴展和新特性
提供了較多測試組件
開源
存儲引擎:-----------------------------------------------------------------------
MyISAM 引擎特色:
不支持事務
表級鎖定
讀寫相互阻塞,寫入不能讀,讀時不能寫
只緩存索引
不支持外鍵約束
不支持聚簇索引
讀取數據較快,佔用資源較少
不支持MVCC(多版本併發控制機制)高併發
崩潰恢復性較差
Mysql 5.5.5以前默認的數據庫引擎
適合場景:
只讀(或者寫較少)、表較少(能夠接受長時間進行修復操做)
引擎文件:
tbl_name.frm 表格式定義
tbl_name.MYD 數據文件
tbl_name.MYI 索引文件
InnoDB引擎特色:
支持事務,適合處理大量短時間事務
行級鎖
有多種事務隔離級別,讀寫阻塞與隔離級別相關
可緩存數據和索引
支持聚簇索引
崩潰恢復性更好
支持MVCC高併發
從MYSQL5.5後支持全文索引
從mysql5.5.5開始爲默認的數據庫引擎
innodb數據庫文件:
1 全部innodb表的數據和索引放置於同一個表空間中
表空間文件:datadir定義的目錄下
數據文件:ibddata1,idbdata2,...
2 每一個表單獨使用一個表空間存儲表的數據和索引
啓用: innodb_file_table=ON
mariadb5.5以後默認開啓
兩類文件放在數據庫獨立目錄中:
數據文件(存儲數據和索引):tb_name.ibd
表格式定義:tb_name.frm
其餘存儲引擎:
performance_schema:
performance_schema數據庫
memory:
將全部數據存儲在RAM中,以便在須要快速查找參考和其餘相似數據的
環境中進行快速訪問。使用存放臨時數據,引擎之前被稱爲HEAP引擎
MRG_MyISAM:
是MySQL DBA或開發人員可以對一系列相同的MyISAM表進行邏輯分組,
並將它們做爲一個對象引用。適用於VLDB(Very Large Data Base)環境,如數據倉庫
Archive:爲存儲和檢索大量不多參考的存檔或安全審覈信息,只支持SELECTHE INSERT操做
支持行級鎖和專用緩存區
Federated聯合:
用於訪問其餘遠程mysql服務器一個代理,它經過建立一個遠程mysql服務器的客戶端
鏈接,並將查詢傳輸到遠程服務器執行,然後完成數據存取,提供連接單獨mysql的能力,
以便從多個物理服務器建立一個邏輯數據庫。很是適合分佈式或數據集市環境。
DBD:
可替代innodb的事物引擎,支持commit、rollback和其餘事物特性
cluster/NDB:
mysql的簇式數據庫引擎,尤爲適合於具備高性能查找要求的應用程序
這類查找需求還要求具備最高的正常工做時間和可用性
CSV:
CSV存儲引擎使用逗號分隔值格式將數據庫存儲在文本文件中。可使用
CSV引擎以CSV格式導入和導出其餘軟件的應用程序之間的數據交換
BLACKHOLE:
黑洞存儲引擎接受但不存儲數據,檢索老是返回一個空集。該功能可用於分佈式
數據庫設計,數據自動複製,但不是本地存儲。
example:
"stub"引擎,它什麼都不作,可使用此引擎建立表,但不能將數據存儲
在其中或從中檢索。目的是做爲例子來講明如何開始編寫新的
mariadb支持的其餘存儲引擎:
qqgraph
sphnxse
tokudb
cassandra
connect
squence
管理存儲引擎:
查看mysql支持的存儲引擎:
SHOW ENGINES
查看當前默認的存儲引擎:
SHOW VARIABLES LIKE '%engine%';
default_storage_engine 默認引擎
storage_engine 當前引擎
設置默認的存儲引擎:
[mysqld]
default_storage_engine= innodb;
查看庫中全部使用的存儲引擎:
SHOW TABLES STATUS LIKE'tb_name'\G
SHOW CREATE TABLE tb_name;
設置表的存儲引擎:
CREATE TABLE tb_name() ENGINE=innodb;
ALTER TABLE tb_name ENGINE=innodb;
數據庫操做:-------------------------------------------------------------------------
查看操做: SHOW
HELP SHOW;
SHOW DATABASES;
SHOW TABLES;
SHOW TABLE STATUS FROM db_name; | LIKE 'tb_name';
SHOW CREATE DATABASE 'db_name';
SHOW CREATE TABLE 'tb_name';
SHOW CHARACTER SET;
SHOW COLLATION;
.....
建立數據庫:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_specification] ...
create_specification:
[DEFAULT] CHARACTER SET [=] charset_name 字符集
| [DEFAULT] COLLATE [=] collation_name 排序規則
刪除數據庫:
DROP DATABASE|SCHEMA [IF EXISTS] db_name;
查看支持的全部字符集: SHOW CHARACTER SET;
查看支持的全部排序規則:SHOW COLLATION;
獲取命令使用幫助: HELP keyword;
查看數據庫列表: SHOW DATABASES;
建立表:------------------------------------------------------------------------
查看幫助:HELP CREATE TABLE;
1 直接建立:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
(create_definition,...)
[table_options]
[partition_options]
簡寫爲:
CREATE TABEL [IF NOT EXISTS] tb_name
(col1 type1 修飾符;col2 type2 修飾符,...)
例如:
CREATE TABLE students (sid TINYINT(4) UNSIGNED PRIMARY KEY,
name CHAR(30),gender ENUM('M','F'),age TINYINT(2) UNSIGNED);
使用DESC tb_name查看錶頭,以下
MariaDB [laa]> DESC students;
+--------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+---------------------+------+-----+---------+-------+
| sid | tinyint(4) unsigned | NO | PRI | NULL | |
| name | char(30) | YES | | NULL | |
| gender | enum('M','F') | YES | | NULL | |
| age | tinyint(2) unsigned | YES | | NULL | |
+--------+---------------------+------+-----+---------+-------+
2 經過查詢現存表建立,新表會被直接插入查詢而來的數據
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
select_statement
例如:
CREATE TABLE hello1 SELECT * FROM emp;
CREATE TABLE hello2 SELECT id,sex FROM emp;
3 經過複製現存的表的表結構建立,但不復制數據
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
{ LIKE old_tbl_name | (LIKE old_tbl_name) }
例如:
CREATE TABLE IF NOT EXISTS hello3 LIKE students;
注意: [[STORAGE] ENGINE [=] engine_name]
此項指明建立表時使用的存儲引擎,同一庫中不一樣表可使用不一樣的存儲引擎
可是建議使用同一種
示例:
查看使用的引擎:
SHOW TABLE STATUS FROM db_name\G;|LIKE 'tb_name'\G;
查看全部引擎:
SHOW ENGINES\G;
查看錶:
SHOW TABLES [FROM db_name]
查看錶結構:
DESC [db_name.]tb_name;
刪除表:
DROP TABLE [IF EXISTS] [db_name.]tb_name;
查看錶建立命令:
SHOW CREATE TABLE tb_name;
查看錶狀態:
SHOW TABLE STATUS LIKE 'tb_name';
查看數據庫中全部表狀態:
SHOW TABLE STATUS FROM db_name;
數據類型:----------------------------------------------------------------------
建立表過程:
CREATE TABEL [IF NOT EXISTS] tb_name
(col1 type1 修飾符;col2 type2 修飾符,...)
字段信息:
col:column,列名稱
type: 列使用的數據類型
修飾符:PRIMARY KEY,INDEX,UNIQUE KEY,...
MYSQL支持多種列類型:
數值類型
日期/時間類型
字符串(字符)類型
選擇正確的數據類型對於得到高性能相當重要,三大原則
更小的一般更好,儘可能使用可正確存儲數據的最小數據類型
簡單更好,簡單數據類型的操做一般須要更少的cpu週期
儘可能避免nul,包含爲null的列,對MYSQL更難優化
1 ×××:
TINYINT(m) [UNSIGNED] 1個字節(-128~127)加上UNSIGNED(0~255)
SMALLINT(m) [UNSIGNED] 2個字節(-32768~32767)
MEDIUMINT(m) [UNSIGNED] 3個字節 (-8388608~8388607)
INT(m) [UNSIGNED] 4個字節
BIGINT(m) [] 8個字節
BOOL,BOOLEAN: 布爾型,TINYINT(1)的同義詞,
zero被視爲假,非zero 被視爲真
UNSIGNED 必須直接加在int類型以後,中間不能隔其餘字段
UNSIGNED 表示去掉負值範圍,從0開始計數,最大值翻倍
(m),表示SELECT查詢結果之中的顯示寬度,並不影響實際的取值範圍,規定了MYSQL
的一些交互工具(例如命令行客戶端)用來顯示字符的個數。
對於存儲和計算來講,INT(1)和INT(20) 是相同的
2 浮點型:
float(m,d): 單精度浮點型,4字節(7位精度),m總個數,d小數位
double(m,d):雙精度浮點型,8字節(15位精度),m總個數,d小數位
設一個字段定義爲float(6,3),若是插入一個數123.45678,實際數據庫裏存放
的是123.457,但總個數還以實際爲準,即6位
3 定點數:decimal(m,d)
·在數據庫中存放的是精確值,存爲十進制
·decimal(m,d) 參數m<65 是總個數,d<30且d<m 是小數位
·MYSQL5.0和更高版本將數字打包保存到一個二進制字符串中(每4個字節存9個數字)。
例如:decimal(18,9)小數點兩邊將各存儲9個數字,一共使用9個字節,小數點前
的數字用4個字節,小數點後的數字用4個字節,小數點自己佔一個字節
·浮點類型在存儲一樣範圍的值時,一般比decimal使用更少的空間。flout使用4字節,double使用8字節
·由於須要額外的空間和計算開銷,因此應該儘可能只在對小數進行精確計算時才使用
decimal,例如存儲財務數據。但在數據量比較大的時候,能夠考慮使用bigint代替decimal
4 字符型
CHAR(n) 固定長度,1字節存儲長度,最多255個字符, 不區分大小寫
VARCHAR(n) 可變長度,2字節存儲長度,最多65535個字符, 不區分大小寫
BINARY(M) 固定長度,1字節存儲長度,最多255個字符, 區分大小寫
VARBINARY(M)可變長度,2字節存儲長度,最多65535個字符, 區分大小寫
TINYTEST 可變長度,最多255 1字節 區分大小寫
TEXT 可變長度,最多65535 2字節
MEDIUMTEXT 可變長度,3字節存儲長度
LONGTEXT 可變長度,4字節存儲長度
內建類型: ENUM:枚舉類型
SET:集合
char和varchar:
. char(n)若存入字符數小於n,則以空格補齊,查詢時再將空格去掉。
因此char類型存儲的字符串末尾不能有空格,varchar不限於此。
. char(n),固定長度,char(4)無論是存入幾個字符,都將佔用4個字節,
varchar是存入的實際字符數+1個字節,因此varchar(4),存入3個字符
將佔用4個字節。
. char類型的字符串檢索速度要比varchar類型的快
varchar和text:
. varchar可指定n,text不能指定,內部存儲varchar是存入的實際字符數
+1個字節,text是實際字符數+2個字節。
. text類型不能有默認值
. varchar 可直接建立索引,text建立索引要指定前多少個字符。
varchar查詢熟讀快與text
5 二進制數據:BLOB
BLOB和TEXT存儲方式不一樣,TEXT以文本方式存儲,英文存儲區分大小寫,而blob
是以二進制方式存儲,不區分大小寫
blob存儲的數據只能總體讀出
text能夠指定字符集,blob不用指定字符街
6 日期時間類型
date 日期'2008-12-2' 4字節
time 時間'12:25:36' 3字節
datetime 日期時間'2008-12-2 22:06:44' 8字節
須要手動寫入
timestamp 自動存儲記錄修改時間,使用%s 秒時間記錄 4字節
無需手動寫入,系統本身記錄
year(2),year(4): 年份
TIMESTAMP字段裏的時間數據會隨其餘字段修改的時候自動刷新,這個數據類型的
字段能夠存放這條記錄最後被修改的時間
修飾符:
全部類型:
NULL 數據列可包含null值
NOT NULL 數據列不容許包含null值
DEFAULT XX 默認值
PRIMARY KEY 主鍵
UNIQUE KEY 惟一鍵
CHARACTER SET name 指定一個字符集
數值型:
AUTO_INCREMENT 自動遞增,適用於整數類型
UNSIGNED 無符號
示例:
CREATE TABLE students (id INT UNSIGNED NOT NULL PRIMARY KEY,
name VARCHAR(20) NOT NULL,age TINYINT UNSIGNED);
CREATE TABLE students2 (id INT UNSIGNED NOT NULL,name VARCHAR(30)
NOT NULL,age TINYINT UNSIGNED,PRIMARY KEY(id,name));
修改和刪除表:---------------------------------------------------------------------
刪除表:
DROP TABLE [IF EXISTS] tb_name[,tb_name2...]
[RESTRICT| CASCADE ]; 關聯刪除
修改表:HELP ALTER TABLE;
ALTER TABLE tb_name ...
添加字段(列):
ALTER TABLE age ADD age TINYINT UNSIGNED [FIRST | AFTER col_name];
ALTER TABLE age ADD [COLUMN](age TINYINT UNSIGNED,name...);
....
注意使用()的狀況沒法使用FIRST|AFTER col
()括號內能夠添加多字段,可是會居於末尾
刪除字段(列)
ALTER TABLE age DROP col_name;
一次只能刪除一列
修改字段:
修改列的默認值,
ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
例如:
ALTER TABLE AGE ALTER uid SET DEFAULT 123;
ALTER TABLE AGE ALTER uid DROP DEFAULT;
修改列名稱,並從新定義列屬性和排列位置
CHANGE [COLUMN] old_col_name new_col_name column_definition
[FIRST|AFTER col_name]
例如:
ALTER TABLE AGE CHANGE AGE age TINYINT UNSIGNED AFTER NAME;
修改列屬性
MODIFY [COLUMN] col_name column_definition
[FIRST | AFTER col_name]
例如:
ALTER TABLE AGE CHANGE uid UID INT UNSIGNED UNIQUE;
ALTER TABLE AGE MODIFY UID VARCHAR(10);
修改索引:
添加索引:ADD INDEX
刪除索引:DROP INDEX
示例:
添加key:
ALTER TABLE age ADD UNIQUE KEY(gid);
添加索引:
ALTER TABLE AGE ADD INDEX(gid);
查看錶中已添加索引
SHOW INDEXES FROM AGE;
DML語句:------------------------------------------------------------------------
DML: INSERT,DELETE,UPDATE,SELECT
INSERT:
一次插入一行或多行數據
獲取幫助:HELP INSERT
注意:
添加字符必須使用''
數值不能使用''
語法1:
INSERT [INTO] tb_name [(col_name,..)] VALUE|VALUES
({expr|DEFAULT},...),(...),...
[ON DUPLICATE KEY UPDATE]
例如:
INSERT INTO age VALUES('laly',18),('mike',25);
INSERT INTO newage VALUES(01,'alily',19),(02,'blily',18);
語法2:
INSERT [INTO] tb_name SET col1={expr|DEFAULT},.....
例如:
INSERT INTO age SET NAME='pite',age=34;
一直只能插入一條記錄
語法3:
INSERT [INTO] tb_name [(col_name),..] SELECT...
例如:
INSERT INTO age(NAME,age) SELECT NAME,age FROM AGE WHERE age=19;
INSERT INTO age(NAME,age) SELECT NAME,uid FROM AGE WHERE age=19;
INSERT INTO age(NAME,age) SELECT age,id FROM AGE WHERE age=55;
要求:
插入的列不要求名稱必須相同,如以上將uid這一列插入到了age中
可是數據類型有要求:
數值類型的能夠插入數值和字符類型中
字符類型沒法插入數值類型
UPDATE:
修改一行或多行數據:HELP UPDATE;
語法:
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
例如:
UPDATE age SET NAME='hello' WHERE age=18;
DELETE:
刪除一行或多行數據:
語法:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
例如:
DELETE FROM age WHERE age IS NULL;
其餘:
truncate table emp; 快速刪除表
操做示例:
CREATE TABLE scroe(id INT UNSIGNED PRIMARY KEY,name VARCHAR(20),score INT UNSIGNED);
DROP TABLE scroe;
CREATE TABLE score(id INT UNSIGNED PRIMARY KEY,name VARCHAR(20),score INT UNSIGNED);
ALTER TABLE score ADD gender ENUM('M','F');
ALTER TABLE score ALTER gender SET DEFAULT 'M';
ALTER TABLE score CHANGE id sid INT UNSIGNED;
ALTER TABLE score CHANGE gender sex CHAR(10);
ALTER TABLE score MODIFY sex ENUM('M','F');
ALTER TABLE score ADD fa VARCHAR(20);
ALTER TABLE score DROP fa;
ALTER TABLE score ALTER sex SET DEFAULT 'M';
INSERT score VALUES(1,'lily',96,'F'),(2,'lucy',66,'F');
INSERT score SET sid=3,name='tom',score=87;
DELETE FROM score WHERE sid=3;
SELECT * FROM score;
UPDATE score SET score=100 WHERE sex='F';
DELETE FROM score;
SELECT :-------------------------------------------------------------------------------
語法格式:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[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}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
選項:
1 查詢條件區分大小寫:binary
例如:
MariaDB [hellodb]> SELECT STUID,NAME FROM students WHERE NAME='SHI ZHONGYU';
+-------+-------------+
| STUID | NAME |
+-------+-------------+
| 1 | Shi Zhongyu |
+-------+-------------+
1 row in set (0.00 sec)
MariaDB [hellodb]> SELECT STUID,NAME FROM students WHERE BINARY NAME='SHI ZHONGYU';
Empty set (0.00 sec)
2 字段顯示可使用別名:
col1 AS alias1,col1 AS alias2,...
例如:
SELECT stuid AS id,name as studentname FROM students;
3 WHERE 子句:
指明過濾條件以實現"選擇"的功能:
過濾條件:布爾型表達式
算術操做符:+,-,*,/,%
比較操做符:=,!=,<>,,>,>=,<,<=,<=>(安全比較運算符,用來作 NULL 值的關係運算)
BETWEEN min_num AND max_num
IN (element1,element2,...)
IS NULL
IS NOT NULL
LIKE
%: 任意長度任意字符
_: 任意單個字符
RLIKE: 正則表達式,會使索引失效,如非必要,不建議使用
REGEXP: 匹配字符串可用正則表達式書寫模式,同上
邏輯操做符:
NOT
AND
OR
XOR
例如:
SELECT * FROM students WHERE name='hua rong';
SELECT * FROM students WHERE stuid>5 AND stuid <10;
SELECT stuid,name FROM students WHERE stuid BETWEEN 5 AND 10;
SELECT * FROM students WHERE stuid>5+10;
SELECT * FROM students WHERE name IN ('SHI ZHONGYU','YU TUTONG','XU ZHU');
SELECT * FROM students WHERE name LIKE 'S%';
SELECT * FROM students WHERE name LIKE '%S%';
SELECT * FROM students WHERE name LIKE 'S_I%';
SELECT * FROM students WHERE teacherid IS NULL;
SELECT * FROM students WHERE teacherid IS NOT NULL;
SELECT * FROM students WHERE teacherid IS NOT NULL OR gender='F';
SELECT * FROM students WHERE teacherid IS NULL AND gender='F'
4 GROUP:
根據指定的條件把查詢結果進行「分組」以用於作「聚合」運算
avg(): 均值
max(): 最大值
min(): 最小值
count(): 總數
sum(): 和
HAVING: 對分組聚合運算後的結果指定過濾條件
例如:
SELECT count(stuid),sum(stuid),avg(stuid),gender FROM students GROUP BY gender;
SELECT count(stuid),gender FROM students GROUP BY gender HAVING gender='F';
SELECT count(stuid),gender FROM students WHERE stuid>10 GROUP BY gender HAVING count(stuid)<10;
5 ORDER BY:
根據指定的字段對查詢結果進行排序
升序: ASC
降序: DESC
NULL值處理:
默認null值爲最小,即ASC排序,null值在最前端,DESC排序,null值在最後端
能夠在被排序的列 col 前加"-",單獨對col值反向排序
如 -col DESC 能夠保持null在後的狀況對col 作升序(從小到大)排序
例如:
SELECT id,score FROM scores ORDER BY score DESC;
SELECT stuid,teacherid FROM students ORDER BY -teacherid DESC;
SELECT * FROM students WHERE name LIKE 'X%' ORDER BY -classid DESC;
6 LIMIT [[offset,]row_count]:
對查詢的結果進行輸出行數數量限制
LIMIT 5 只顯示前5行
LIMIT 3,5 跳過3行以後顯示5行
7 對查詢結果中的數據請求施加鎖:
FOR UPDATE: 寫鎖,獨佔或排它鎖,只有一個讀和寫
LOCK IN SHARE MODE: 讀鎖,共享鎖,同時多個讀
練習:
導入hellodb.sql生成數據庫,(表結構會在後面附上)
(1) 在students表中,查詢年齡大於25歲,且爲男性的同窗的名字和年齡
SELECT name,age FROM students WHERE age>25;
(2) 以ClassID爲分組依據,顯示每組的平均年齡
SELECT classid,avg(age) FROM students GROUP BY classid;
(3) 顯示第2題中平均年齡大於30的分組及平均年齡
SELECT classid,avg(age) FROM students GROUP BY classid HAVING avg(age)>30;
(4) 顯示以L開頭的名字的同窗的信息
SELECT * FROM students WHERE name LIKE 'L%';
(5) 顯示TeacherID非空的同窗的相關信息
SELECT * FROM students WHERE teacherid is NOT NULL;
SELECT * FROM students WHERE NOT teacherid='NULL';
(6) 以年齡排序後,顯示年齡最大的前10位同窗的信息
SELECT * FROM students ORDER BY age DESC LIMIT 10;
(7) 查詢年齡大於等於20歲,小於等於25歲的同窗的信息
SELECT * FROM students WHERE age<=25 AND age>=20;
SELECT * FROM students WHERE age BETWEEN 20 AND 25;
SELECT * FROM students WHERE age IN(20,21,22,23,24,25);
SQL JOINS: 多表查詢
1 交叉鏈接:
笛卡爾乘積
兩張表疊加,第一張表的每一行會單獨對應第二張表的每一行
例如:
SELECT * FROM students,classes;
2 內鏈接:inner join(默認)
等值鏈接: 讓表之間的字段以"等值"創建鏈接關係
寫法一:
1 SELECT s.stuid,s.name,s.age,c.class FROM students AS s,classes AS
c WHERE s.classid=c.classid;
2 SELECT * FROM students AS st,scores AS sc WHERE st.stuid=sc.stuid;
3 SELECT s.name AS stu_name,s.age,s.gender,t.name AS tea_name FROM
students AS s,teachers AS t WHERE s.teacherid=t.tid;
寫法二:SELECT .. FROM tb_a INNER JOIN ON tb_b ON tb_a.key=tb_b.key [WHERE] ..
1 SELECT s.stuid,s.name,s.age,c.class FROM students AS s INNER JOIN
classes AS c ON s.classid=c.classid;
2 SELECT * FROM students AS st INNER JOIN scores AS sc ON st.stuid=sc.stuid;
3 SELECT s.name AS stu_name,s.age,s.gender,t.name AS tea_name FROM students AS s
INNER JOIN teachers AS t ON s.teacherid=t.tid ;
[WHERE s.age>30]
天然鏈接:去掉重複列的 INNER JOIN 鏈接,須要兩張表中有相同的column。
使用natural join 鏈接,不須要 "ON",
1 SELECT s.stuid,s.name,s.age,c.class FROM students AS s NATURAL JOIN classes AS c;
2 SELECT * FROM students AS st NATURAL JOIN scores AS sc;
自鏈接:將單張表當成兩張表用,內鏈接
4 SELECT a.name,a.age,b.teacherid FROM students a INNER JOIN students b
ON a.stuid=b.teacherid;
3 外連接
左外鏈接:left join
左表全顯示,右表中沒有對應項會顯示爲NULL
1 SELECT s.stuid,s.name,s.age,c.class FROM students AS s LEFT JOIN
classes AS c ON s.classid=c.classid ;
右外鏈接:right join
右表全顯示,左表中沒有對應項會顯示爲NULL
2 SELECT * FROM students AS st RIGHT JOIN scores AS sc on
st.stuid=sc.stuid;
2 SELECT * FROM students AS st RIGHT JOIN scores AS sc ON
st.stuid=sc.stuid WHERE score>70;
左外半鏈接:
SELECT .. FROM tb_a LEFT JOIN ON tb_b ON tb_a.key=tb_b.key
WHERE b.key IS NULL
左外鏈接加上WHERE b.key is NULL
例如:
SELECT * FROM students s LEFT JOIN teachers t ON s.teacherid=t.tid
WHERE t.tid IS NULL;
右外半鏈接:
左外鏈接加上WHERE a.key is NULL
例如:
SELECT * FROM students AS st RIGHT JOIN scores AS sc on
st.stuid=sc.stuid;
WHERE st.stuid IS NULL
4 子查詢:在查詢語句中嵌套着查詢語句,性能較差。基於某語句的查詢結果再次查詢
a 用在WHERE 子句中的子查詢:
用於比較表達式中的子查詢;子查詢僅能返回單個值
SELECT name,age FROM students WHERE age>(SELECT avg(age) FROM students);
用於IN中的子查詢:子查詢應該單鍵查詢並返回一個或多個值構成列表
SELECT stuid,name,age FROM students WHERE stuid IN (SELECT tid FROM teachers);
b 用於FROM子句中的子查詢:
{ SELECT s.aage,s.classid FROM
(SELECT avg(Age) AS aage,ClassID FROM students WHERE ClassID
IS NOT NULL GROUP BY ClassID) AS s
WHERE s.aage>20;
}
5 聯合查詢:UNION,將查詢的結果上下粘合在一塊兒,要求列的數量必須相同
例如:
SELECT stuid,name FROM students UNION SELECT stuid,score FROM scores;
能夠用來粘合左外鏈接和右外鏈接,實現全鏈接
{ SELECT * FROM students as s LEFT JOIN scores AS c ON s.stuid=c.stuid
UNION
SELECT * FROM students as s RIGHT JOIN scores AS c ON s.stuid=c.stuid;
}
粘合左外半鏈接和 右外半鏈接,實現空心鏈接(全鏈接中去掉內鏈接)
{ SELECT * FROM students as s LEFT JOIN scores AS c ON s.stuid=c.stuid
WHERE c.stuid IS NULL
UNION
SELECT * FROM students as s RIGHT JOIN scores AS c ON s.stuid=c.stuid
WHERE s.stuid IS NULL;
}
SELECT 語句執行過程:
start---> FROM ---> WHERE ---> GROUP BY ---> HAVING ---> ORDER BY
---> SELECT ---> LIMIT ---> end result
練習:
導入hellodb.sql,如下操做在students表上執行(表結構會在後面附上)
一、以ClassID分組,顯示每班的同窗的人數
SELECT classid,count(stuid) FROM students GROUP BY classid ORDER BY -classid DESC;
二、以Gender分組,顯示其年齡之和
SELECT gender,sum(age) FROM students GROUP BY gender;
三、以ClassID分組,顯示其平均年齡大於25的班級
SELECT classid,avg(age) FROM students GROUP BY classid HAVING avg(age)>25;
四、以Gender分組,顯示各組中年齡大於25的學員的年齡之和
SELECT gender,sum(age) FROM students WHERE age>25 GROUP BY gender;
五、顯示前5位同窗的姓名、課程及成績
{ SELECT st.name,c.class,st.score FROM
(SELECT s.name,s.classid,sc.score FROM students AS s LEFT JOIN
scores AS sc ON s.stuid=sc.stuid) AS st
LEFT JOIN classes as c ON st.classid=c.classid ORDER BY score DESC LIMIT 5;
} 錯誤答案,題目前5名同窗應該指的是學號前5.。。
{ SELECT st.name,c.class,st.score FROM
(SELECT s.name,s.classid,sc.score FROM students AS s INNER JOIN
scores AS sc ON s.stuid=sc.stuid WHERE s.stuid BETWEEN 1 AND 5) AS st
INNER JOIN classes as c ON st.classid=c.classid;
}
六、顯示其成績高於80的同窗的名稱及課程;
{ SELECT st.name,c.class FROM (SELECT s.name,s.classid,sc.score FROM
students AS s LEFT JOIN scores AS sc ON s.stuid=sc.stuid) AS st
LEFT JOIN classes as c ON st.classid=c.classid
WHERE score>80;
}
{ SELECT s.name,c.class FROM (SELECT name,classid FROM students WHERE
stuid IN (SELECT stuid FROM scores WHERE score>80)) AS s
LEFT JOIN classes AS c ON s.classid=c.classid;
} 錯誤答案,緣由是兩門課程,這裏去掉了重複stuid
七、求前8位同窗每位同窗本身兩門課的平均成績,並按降序排列
{ SELECT f.stuid,f.name,avg(score),f.class FROM
(SELECT st.stuid,st.name,c.class,st.score FROM
(SELECT s.stuid,s.name,s.classid,sc.score FROM students AS s INNER JOIN
scores AS sc ON s.stuid=sc.stuid) AS st
INNER JOIN classes as c ON st.classid=c.classid) AS f
GROUP BY stuid ORDER BY avg(score) DESC;
} 錯誤答案,結果中同時顯示了班級,過程當中多插入了一張班級表
{ SELECT f.stuid,f.name,avg(score) FROM
(SELECT s.stuid,s.name,s.classid,sc.score FROM students AS s INNER JOIN
scores AS sc ON s.stuid=sc.stuid) AS f
GROUP BY stuid ORDER BY avg(score) DESC;
}
八、顯示每門課程課程名稱及學習了這門課的同窗的個數
SELECT f.course,count(stuid) FROM
(SELECT sc.stuid,co.course FROM scores AS sc INNER JOIN courses
AS co ON sc.courseid=co.courseid) AS f GROUP BY course;
九、顯示其年齡大於平均年齡的同窗的名字
SELECT name FROM students WHERE age>(SELECT avg(age) FROM students);
十、顯示其學習的課程爲第一、2,4或第7門課的同窗的名字
SELECT s.name FROM students AS s INNER JOIN
(SELECT stuid,courseid FROM scores WHERE courseid IN(1,2,4,7)) AS c
ON s.stuid=c.stuid;
十一、顯示其成員數最少爲3個的班級的同窗中年齡大於同班同窗平均年齡的同窗
{ SELECT name,age,avg(age) FROM students WHERE classid IN
(SELECT classid FROM students GROUP BY classid HAVING count(stuid)>=3)
GROUP BY classid HAVING age>avg(age);
} 錯誤答案
{ SELECT s.name,s.age,c.aavg FROM
(SELECT name,age,classid FROM students WHERE classid IN
(SELECT classid FROM students GROUP BY classid HAVING count(stuid)>=3))
AS s INNER JOIN
(SELECT classid,avg(age) AS aavg FROM students GROUP BY classid
HAVING count(stuid)>=3) AS c
ON s.classid=c.classid WHERE age>aavg;
}
十二、統計各班級中年齡大於全校同窗平均年齡的同窗
SELECT name,age,classid FROM students WHERE age>(SELECT avg(age) FROM students);
視圖,函數,存儲過程:---------------------------------------------------------------------
視圖:
視圖: view,虛表,保存有實表的查詢結果(SELECT語句)
建立方法:
CREATE VIEW view_name [(colmun_list)] AS select_statement
[WITH [CASCADED|LOCAL]] CHECK OPTION]
例如:
CREATE VIEW name_score AS SELECT s.stuid,s.name,sc.score FROM
students AS s INNER JOIN scores AS sc ON s.stuid=sc.stuid;
查看視圖定義:
SHOW CREATE VIEW view_name;
刪除視圖:
DROP VIEW [IF EXISTS] view_name [...] [RESTRICT|CASCADE]
注意: 視圖中的數據事實上存儲於"基表"中,所以,其修改操做也會針對基表實現
其修改操做受基表限制
函數:
函數:FUNCTION,分爲系統函數和自定義函數
系統函數: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_name type,[parameter_name type,...])
RETURNS {STRING|INTEGER|REAL}
runtime_body
說明: 參數能夠有多個,也能夠沒有參數
必須有且只有一個返回值
查看UDF函數列表:
SHOW FUNCTION STATUS;
查看函數定義:
SHOW CREATE FUNCTION function_name;
刪除UDF:
DROP FUNCTION function_name
調用自定義函數語法:
SELECT function_name(parameter_value,...)
注意:對於太過簡單的函數,系統默認不予建立,須要設置變量
log_bin_trust_function_creators=ON;
示例:無參UDF
SET GLOBAL log_bin_trust_function_creators=ON;
CREATE FUNCTION simpleFun() RETURNS VARCHAR(20) RETURN "HELLO WORLD!";
示例:有參數UDF
MariaDB [hellodb]> DELIMITER //
MariaDB [hellodb]> CREATE FUNCTION deletebyid(uid SMALLINT UNSIGNED) RETURNS VARCHAR(20)
-> BEGIN
-> DELETE FROM students WHERE stuid = uid;
-> RETURN(SELECT COUNT(uid) FROM students);
-> END//
Query OK, 0 rows affected (0.03 sec)
MariaDB [hellodb]> DELIMITER ;
MariaDB [hellodb]> SELECT deletebyid(4);
+---------------+
| deletebyid(4) |
+---------------+
| 22 |
+---------------+
DELIMITER: 設置語句結束符
自定義函數中定義局部變量語法:
DECLARE 變量1[,變量2,..]變量類型[DEFAULT 默認值]
說明:局部變量的做用範圍是在BEGIN...END 程序中,並且定義局部變量語句必須
在BEGIN...END的第一行定義
示例:
MariaDB [hellodb]> DELIMITER //
MariaDB [hellodb]> CREATE FUNCTION addtwonumber(x SMALLINT UNSIGNED,y SMALLINT UNSIGNED)
-> RETURNS SMALLINT
-> BEGIN
-> DECLARE a,b SMALLINT UNSIGNED DEFAULT 10;
-> SET a = x,b = y;
-> RETURN a+b;
-> END//
DELIMITER ;
MariaDB [hellodb]> SELECT addtwonumber(4,5);
+-------------------+
| addtwonumber(4,5) |
+-------------------+
| 9 |
+-------------------+
爲變量賦值語法:
SET parameter_name = value[,parameter_name=value,..]
SELECT INTO parameter_name
示例:
DECLARE x INT;
SELECT COUNT(id) FROM tb_name INTO x;
RETURN x;
END//
存儲過程:
存儲過程:PROCEDURE 存儲過程保存在mysql.proc表中
建立存儲過程:
CREATE PROCEDURE sp_name ([proc_parameter[,proc_parameter,...]])
routime_body
其中:
proc_parameter:[IN|OUT|INOUT] parameter_name type
IN 表示輸入參數
OUT表示輸出參數
INOUT表示便可以輸入也能夠輸出
parameter_name表示參數名稱;type表示參數的類型
查看存儲過程列表:
SHOW PROCEDURE STATUS;
查看存儲過程定義:
SHOW CREATE PROCEDURE sp_name;
調用存儲過程:
CALL sp_name([proc_parameter,...])
CALL sp_name
說明:當無參數時,能夠省略"()",有參數數不可省略
存儲過程修改:
ALTER語句修改存儲過程只能修改存儲過程的註釋等無關信息
不能修改存儲過程體,因此要修改存儲過程,方法是刪除重建
刪除存儲過程:
DROP PROCEDURE [IF EXISTS] sp_name
示例:建立無參存儲過程:
MariaDB [hellodb]> DELIMITER //
MariaDB [hellodb]> CREATE PROCEDURE showtime()
-> BEGIN
-> SELECT now();
-> END//
MariaDB [hellodb]> CALL SHOWTIME //
+---------------------+
| now() |
+---------------------+
| 2018-06-13 19:53:24 |
+---------------------+
1 row in set (0.00 sec)
示例:建立含參存儲過程:只有一個IN參數
MariaDB [hellodb]> DELIMITER //
MariaDB [hellodb]> CREATE PROCEDURE selebyid(IN id SMALLINT UNSIGNED)
-> BEGIN
-> SELECT * FROM students WHERE stuid = id;
-> END//
MariaDB [hellodb]> DELIMITER ;
MariaDB [hellodb]> CALL selebyid(15);
+-------+---------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------+-----+--------+---------+-----------+
| 15 | Duan Yu | 19 | M | 4 | NULL |
+-------+---------+-----+--------+---------+-----------+
示例:
MariaDB [hellodb]> DELIMITER //
MariaDB [hellodb]> CREATE PROCEDURE dorepeat(p1 INT)
-> BEGIN
-> SET @x = 0;
-> REPEAT SET @x = @x + 1;UNTIL @x > p1
-> END REPEAT;
-> END//
Query OK, 0 rows affected (0.01 sec)
MariaDB [hellodb]> DELIMITER ;
MariaDB [hellodb]> CALL dorepeat(1000);
Query OK, 0 rows affected (0.00 sec)
MariaDB [hellodb]> SELECT @x;
+------+
| @x |
+------+
| 1001 |
+------+
示例:建立含參存儲過程:包含IN參數和OUT 參數
MariaDB [hellodb]> DELIMITER //
MariaDB [hellodb]> CREATE PROCEDURE deletebyid(IN id SMALLINT UNSIGNED,OUT num SMALLINT UNSIGNED)
-> BEGIN
-> DELETE FROM students WHERE stuid = id;
-> SELECT row_count() INTO num;
-> END//
MariaDB [hellodb]> CALL deletebyid(2,@Line);
Query OK, 1 row affected (0.00 sec)
MariaDB [hellodb]> SELECT @line;
+-------+
| @line |
+-------+
| 1 |
+-------+
存儲過程優點:
1 存儲過程把常用的sql語句或業務邏輯封裝起來,預編譯保存在數據庫中,
當須要是從數據庫中直接調用,省去了編譯的過程
2 提升了運行速度
3 同時下降網絡數據傳輸量
存儲過程與自定義函數的區別:
1 存儲過程實現的過程要複雜一些,而函數的針對性較強
2 存儲過程能夠有多個返回值,而自定義函數只有一個返回值
3 存儲過程通常獨立的來執行,而函數每每是做爲其餘sql語句的一部分來使用
流程控制和觸發器:----------------------------------------------------------------
存儲過程和函數中可使用流程控制來控制語句的執行
流程控制:
IF: 用來進行條件判斷。根據是否知足條件,執行不一樣語句
CASE: 用來進行條件判斷,可實現比IF 語句更復雜的條件判斷
LOOP: 重複指定特定的語句,實現一個簡單的循環
LEAVE: 用於跳出循環控制
ITERATE: 跳出本次循環,而後直接進行下一次循環
REPEAT: 有條件控制的循環語句,當知足特定條件時,就會跳出循環語句
WHILE: 有條件控制的循環語句
TRIGGER: 觸發器
觸發器的執行不是由程序調用,也不是由手工啓動,而是由事件來觸發,激活從而實現執行
建立觸發器:
CREATE [DEFINER = {user|CURRENT_USER}] TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body
說明:
trigger_name: 觸發器的名稱
trigger_time: {BEFORE|AFTER},表示在事件以前或以後觸發
trigger_event: {INSERT|UPDATE|DELETE},觸發的具體事件
tbl_name:該觸發器做用在代表
觸發器示例:建立觸發器,在向學生表INSERT 數據時,學生數增長,DELETE學生時,
學生數減小
CREATE TRIGGER trigger_students_count_insert
-> AFTER INSERT
-> ON students FOR EACH ROW
-> UPDATE student_count SET student_count=student_count+1;
CREATE TRIGGER trigger_student_count_delete
-> AFTER DELETE
-> ON students FOR EACH ROW
-> UPDATE student_count SET student_count=student_count+1;
查看觸發器:
1 SHOW TRIGGERS\G
2 查詢系統表information_schema.triggers 的方式指定查詢條件,查看指定
觸發器信息。
use information_schema;
SELECT * FROM triggers WHERE trigger_name='trigger_student_count_delete'\G
刪除觸發器:
DROP TRIGGER trigger_name;
DROP TRIGGER trigger_students_count_insert;