mysql數據庫
數據庫的分類:
分類 | 概念 | 常見的關係型和非關係型數據庫系統 |
關係型數據庫 (SQL) | 採用SQL語言管理,採用"數據表格"存儲數據。(前期必須將表格式設計合理,後期難以修改)通常用於企業的網站、OA信息系統。 | mysql-server(SUN公司-->Oracle公司)、SQL Server(微軟)、Oracle數據庫(商用,銀行、金融公司會用) |
非關係型數據庫 (No SQL) | 不採用SQL語言管理,採用"鍵值對"來存儲數據。(不採用表存儲數據,後期修改很靈活)通常用戶大數據分析處理 | redis、mongodb…… |
數據庫的概念
名稱 | 用Excel類比理解 | |
庫文件(數據庫database/db) | 可以理解成一個Excel文件。 一個庫(database)文件中可以有0~n張表(table)。 | mysql的庫文件默認保存在/var/lib/mysql目錄中,庫文件在linux系統中是以"目錄的形式存在的",庫目錄中存放的是此數據庫的表。 |
表 | 可以理解成Excel文件中的一張表。一張表中可以有1~n個字段。 | 表在linux系統中是以文件名的形式保存在庫的目錄中。 |
字段 | 可以理解成Excel表中表頭的列標題。一個字段可以包含0~n行記錄(record)。 | 字段和記錄是以正文的形式保存在表文件中的。 |
mysql的庫文件、表文件默認的保存路徑 | /var/lib/mysql |
庫文件類型(以什麼類型的文件存儲在硬上) | 以目錄的形式存儲在/var/lib/mysql目錄中 |
表文件 | 以普通文件的形式存儲字庫的目錄中 |
SQL的三種語言
SQL(Structured Query Language 即結構化查詢語言) | ||
SQL語言主要用於存取數據、查詢數據、更新數據和管理關係數據庫系統,SQL語言由IBM開發。 | ||
名稱 | 作用 | 例子 |
DDL語句 數據庫定義語言(Data Definition Language) | 數據庫、表、視圖、索引、存儲過程 | CREATE DROP ALTER |
DML語句 數據庫操縱語言(Data Manipulation Language) | 插入數據INSERT、刪除數據DELETE、更新數據UPDATE、查詢數據SELECT | insert delete …… |
DCL語句 數據庫控制語言(Data Control Language) | 控制用戶的訪問權限GRANT(授予權限)、REVOKE(收回權限) |
MySQL數據類型
在 MySQL 中,有三種主要的類型:文本、數字和日期/時間類型。
庫、表、記錄的操作
庫、表的增、刪、改、查命令?數據記錄的增、刪、改、查命令?
庫(database)的操作 | |
查: 增(創建): 刪: 選擇(打開)數據庫: | show databases; create database 庫名 選項; drop database 庫名; use 數據庫名 |
表(table)的操作 | |
查看錶: 增(創建): 查表結構(表屬性): 查看錶詳細結構: 刪除表: 修改表: 複製表: | show tables; create table 表名(字段名1 數據類型,字段2 數據類型, ...)engine=innodb 編碼設置; desc 表名; 或:( describe 表名;) show create table 表名 drop table 表名; alter table create table ... |
顯示修改表的命令幫助:help alter table;(插入或刪除一列,修改某列的屬性[即字段名和數據類型]) | |
在表中最後新增指定的列字段: 在表中第一列或字段名A列之後新增指定的列字段: 刪除表中的某列字段: | alter table 表名 add 字段名 數據類型; alter table 表名 add 字段名 數據類型 [first| after 字段名A]; alter table 表名 drop 字段名; |
修改某列的屬性[即字段名和數據類型]) | |
修改某列的數據類型:
修改某列的字段名和數據類型: | alter table 表名 modify 字段名 新數據類型 [first| after 字段名A];; alter table 表名 change 舊字段名 新字段名 新數據類型 [first| after 字段名A];; ALTER TABLE 表名 CHANGE 舊字段名 新字段名 舊數據類型 [完整性約束條件…]; |
記錄(record)的操作(插入一行) | |
查: 增(插入): 更新: 刪: | select * from 表名 [where 條件] insert into 表名[(字段1,字段2,...)] values(值1,值2,...),(值1,值2,...); update [庫名.]表名 set 字段名='新值' [where 條件]; delete from [庫名.]表名 [where 條件]; |
MySQL用戶
給mysql-server的root用戶分別設置本地、遠程登錄密碼root 格式: 刷新權限表 | grant all on *.* to root@'localhost' identified by 'root'; grant all on *.* to root@'%' identified by 'root'; grant all on *.* to 用戶名@’主機號/IP’ identified by ‘密碼’ flush privileges; |
更新mysql數據庫中user表中的root用戶的密碼爲01: | update mysql.user set password=password("01") where user="root" and host="localhost"; |
創建一個擁有全部權限的jin用戶賬號 | grant all on *.* to jin@'%' identified by 'jin' with grant option; |
創建允許本地登錄的jin賬號 | grant all on *.* to jin@'localhost' identified by 'jin' with grant option; |
授權管理(用戶安全管理)
常用命令 | 格式 |
查mysql庫中user表的user、host、password字段的數據記錄:(查mysql系統中的用戶賬號) | select user,host,password from mysql.user; |
在mysql中創建一個跟root賬號相同權限的新賬號admin: | grant all on *.* to admin@'%' identified by '密碼' with grant option; |
查看root賬號的授權信息 | show grants for root@'localhost'; |
回收admin賬號的insert、update、delete權限 | revoke insert,update,delete on *.* from admin@'主機名或IP'; |
刪除admin賬號: | drop user admin@'主機名或IP'; |
表的完整性約束
表完整性約束..... | |
作用:用於保證數據的完整性和一致性 | |
約束條件 | 說明 |
主鍵: (可以唯一的標識記錄,不可以爲空) 外鍵: 實現子表與父表之間的關聯 唯一鍵:
索引:
| primary key (PK) UNIQUE + NOT NULL foreign key (FK) NOT NULL unique key (UK) (標識此字段的值是唯一的,可以爲空) index unique... engine=innodb; |
AUTO_INCREMENT: DEFAULT: UNSIGNED: ZEROFILL: | 標識此字段的值自動增長(整數類型,而且爲主鍵),通常用在“序號”字段 爲此字段設置默認值,用戶不填寫此信息是默認填寫此值。 無符號,正數 使用0填充,如填寫0000001這種記錄是可以使用此約束 |
說明: 1、是否允許爲空,默認NULL,可設置NOT NULL,字段不允許爲空,必須賦值。 2、字段是否有默認值,缺省的默認值是NULL,如果插入記錄時不給字段賦值,此字段使用默認值。(default: 指定默認值) 3、唯一約束:控制此列的值不允許重複,必須是唯一的一個值。 4、主鍵約束:primary key字段的值是不允許重複,且不允許爲空NULL(UNIQUE + NOT NULL)。 單列做主鍵 多列做主鍵(複合主鍵)應用場合:需要用兩列的值來標識數據的唯一性。 5、外鍵的作用就是實現在子表中引用父表中某列的值,這樣子表中外鍵的值是依賴於父表的。 注: 1)父表中的主鍵才能作爲子表中的外鍵。 2)當父表中的記錄修改時,子表也會同步修改 3)當父表中刪除記錄時,子表也會同步刪除 |
如何在select查詢時對錶中的某列數據進行排序(升序、降序)?
用order by 字段名 [asc升序|desc降序]
按指定的條件查詢表中的數據記錄。
在where中用like做值的模糊匹配,_匹配任意單個字符,%匹配任意一串字符
update命令語法:
update 庫名.表名 set 字段名=新值(可用mysql函數) where 匹配條件
忘記了MySQL密碼
mysql的root密碼忘了,如何處理?做如下操作:
1、首先,修改/etc/my.cnf主配置文件。
vim /etc/my.cnf
[mysqld]
skip-grant-table 跳過權限表驗證(添加此行)
2、重啓mariadb服務:systemctl restart mariadb
3、在mysql-server服務器本地免密碼登錄,做更新root密碼的操作。
mysql
update mysql.user set password=password("01") where user='root' and host='localhost';
flush privileges;
exit
4、修改/etc/my.cnf主配置文件。
vim /etc/my.cnf
[mysqld]
#skip-grant-table 註釋或刪除此行
5、重啓mariadb服務:systemctl restart mariadb
6、在mysql-server服務器本地使用root賬號和新密碼登錄。
mysql -uroot -p01 登錄成功,就說明密碼重設成功
數據庫的備份
mysql庫和表的邏輯備份工具mysqldump
邏輯備份就是將數據中的表備份成create table、insert into等表和數據記錄的SQL語句。
物理備份就是就是將數據庫、表的源文件(/var/lib/mysql/庫名目錄)複製或tar打包壓縮一份到別的目錄中。
邏輯備份
單庫全表備份 |
mysqldump -uroot -p'密碼' 庫名 > 備份文件名.sql 例: mysqldump -uroot -p01 test > test-all.sql more test-all.sql 注:備份文件中主要是create table、insert into等SQL語句 |
單庫全表恢復: |
1、創建一個空庫:mysql -uroot -p01 -e 'create database 庫名;show databases;' 2、恢復所有表到庫中:mysql -uroot -p01 庫名 < 備份文件名.sql 例: mysql -uroot -p01 -e 'create database test_all;show databases;' mysql -uroot -p01 test_all < test_all.sql mysql -uroot -p01 -e 'use test_all;show tables;' |
單庫單表備份 |
mysqldump -uroot -p'密碼' 庫名 表名 > 備份文件名.sql 例:mysqldump -uroot -p01 test tby > tby.sql more tby.sql 注:備份文件中主要是create table、insert into等SQL語句 |
單庫單表恢復 |
1、創建一個空庫:mysql -uroot -p01 -e 'create database 庫名;show databases;' 2、恢復tby表到ku_tby庫中:mysql -uroot -p01 庫名 < 備份文件名.sql 例: mysql -uroot -p01 -e 'create database ku_tby;show databases;' mysql -uroot -p01 ku_tby < tby.sql mysql -uroot -p01 -e 'use ku_tby;show tables;select * from tby;' |
物理備份的模式:
冷備份:首先,停止數據庫的服務,然後用cp、tar命令對數據庫文件進行備份。
熱備份:直接在數據庫服務運行的狀態下做備份,需要用mysql的第三方備份和恢復工具進行操作。
練習:將192.168.11.11主機上的mysql的所有庫做冷備份,備份到/opt/mysql-2019-03-07目錄中。 grep 'datadir' /etc/my.cnf 查看mysql主配置文件中的數據庫文件存儲路徑 mkdir -pv /opt/data/mysql-$(date +%F) systemctl stop mariadb && systemctl status mariadb cp -arv /var/lib/mysql/* /opt/data/mysql-$(date +%F) |
#刪除mysql的所有庫和表,重啓服務後,查庫、查表,發現test庫中沒有表。 rm -rfv /var/lib/mysql/* systemctl restart mariadb mysql -uroot -e 'show databases;use test;show tables;' |
#冷恢復數據庫、表。 systemctl stop mariadb \cp -afrv /opt/data/mysql-$(date +%F)/* /var/lib/mysql/ systemctl restart mariadb mysql -uroot -p456 -e 'show databases;use test;show tables;' |
MySQL環境的部署
查軟件是否已安裝 安裝mariadb軟件 啓動服務器端的服務 允許開機自動啓動 內測 | rpm -q mariadb-server mariadb yum install -y mariadb-server mariadb systemctl restart mariadb systemctl enable mariadb mysql exit (\q) |
主從複製
作用:
簡稱AB複製,在A主機上做create、update、insert、drop、delete等數據庫、表、記錄的增、刪、改操作,B主機上會自動做數據庫、表、記錄的同步更新。
AB複製的工作原理(即工作過程):
1. 在主庫上把數據更改記錄到二進制日誌(Binary Log)中。
2. 備庫將主庫上的日誌複製到自己的中繼日誌(Relay Log)中。
3. 備庫讀取中繼日誌中的事件,將其重放到備庫數據庫之上。
AB複製的配置思路:
1.在A主機(master)上的/etc/my.cnf主配置文件中開啓binlog二進制日誌文件功能,並且給主機設置server-id唯一標識編號。重啓mariadb服務。
2.在A主機上創建用於AB主從複製的用戶賬號,並查看master狀態中的binlog日誌文件的position位置數值。
3.在B主機上的/etc/my.cnf主配置文件中設置server-id唯一標識編號。。重啓mariadb服務。
4.在B主機上用help change master查命令幫助,並用change master命令告訴B主機他的master主人的正確信息。
5.在B主機上用start slave啓動mariadb的隨從服務,並用show slave status查看AB主從複製的數據同步狀態,要確認兩個線程的yes狀態。
AB複製的一主一從模式工作過程:
A主機: create database db1 ----> 會將此命令自動寫入本機的二進制日誌文件中
B主機:
I/O線程 監測並讀A主機上的二進制日誌文件新增的內容,且將新內容寫入到B主機自己的中繼日誌文件中
SQL線程 讀取B主機上中繼日誌文件中心的SQL語句,並且自動執行這些SQL語句。最終在B主機上創建了db1這個庫。
網絡拓撲:(1主1從)
mysql主服務器(master主人):192.168.11.11
mysql從服務器(slave隨從、奴隸):192.168.11.12
準備工作:
1、停止master、slave主機上的mariadb服務,並且清空/var/lib/mysql的所有數據。
systemctl stop mariadb
rm -rfv /var/lib/mysql/*
2、重啓master、slave主機上的mariadb服務。並且查庫、test庫中是否有表(無表就OK)。
systemctl restart mariadb
mysql -uroot -e 'show databases;use test;show tables;'
AB複製的配置實施:
1、在A主機(master)上的/etc/my.cnf主配置文件中開啓binlog二進制日誌文件功能,並且給主機設置server-id唯一標識編號。重啓mariadb服務。
vim /etc/my.cnf 做如下修改
[mysqld] 找到此行,添加如下藍色字的3行功能選項
server-id=11 指定server-id爲11,通常用本機IP的最後一組數
log-bin=master-bin 添加此行,指定二進制日誌文件名爲master-bin
skip_name_resolv=1 跳過域名解析功能
重啓mariadb服務:
systemctl restart mariadb
2、在A主機上創建用於AB主從複製的用戶賬號,並查看master狀態中的binlog日誌文件的position位置數值。
mysql -uroot -e "grant replication slave on *.* to 'rep'@'192.168.11.%' identified by 'rep';"
mysql -uroot -e 'select user,host,password from mysql.user;
mysql -uroot -e 'reset master;show master status;'
3、在B主機上的/etc/my.cnf主配置文件中設置server-id唯一標識編號。重啓mariadb服務。
vim /etc/my.cnf 做如下修改
[mysqld] 找到此行,添加如下藍色字的3行功能選項
server-id=12 指定server-id爲12,通常用本機IP的最後一組數
#log-bin=slave-bin 添加此行,指定二進制日誌文件名爲slave-bin
skip_name_resolv=1 跳過域名解析功能
重啓mariadb服務:
systemctl restart mariadb
mysql -urep -prep -h192.168.11.11 -e 'status;' 測試rep用戶是否能遠程訪問master主機的數據庫服務
4、在B主機上用help change master查命令幫助,並用change master命令告訴B主機他的master主人的正確信息。
mysql
help change master to;
CHANGE MASTER TO
MASTER_HOST='192.168.11.11',
MASTER_USER='rep',
MASTER_PASSWORD='rep',
MASTER_PORT=3306,
MASTER_LOG_FILE='master-bin.000001',
MASTER_LOG_POS=542,
MASTER_CONNECT_RETRY=10; //是指從和主連不上是重試連接的時間爲10秒
5、在B主機上用start slave啓動mariadb的隨從服務,並用show slave status查看AB主從複製的數據同步狀態,要確認IO和SQL兩個線程的yes狀態。
mysql -uroot -p
start slave;
show slave status\G 注: \G 是分組(group)顯示信息。
6、測試主從複製的數據同步。
首先,在A主機(192.168.11.11)上創建一個名稱爲db1的庫,並查庫。
mysql
create database db1;
show database;
SHOW PROCESSLIST; 查mysql的內部進程(即線程)清單
然後,在B主機上查庫,看到了db1庫,說明AB主機的數據自動同步成功。
mysql -uroot -e 'show databases;'
注:change master to設置的信息默認保存在/var/lib/mysql/master.info文件中,relay中繼日誌的設置信息默認保存在/var/lib/mysql/relay-log.info文件中。
ls /var/lib/mysql/
cat /var/lib/mysql/master.info
cat /var/lib/mysql/relay-log.info
cat /var/lib/mysql/mysql.sock 此套接字設備文件無法查看,是正常現象
讀寫分離
1. 基於程序代碼內部實現
在代碼中根據 select、insert 進行選擇分類; 這類方法也是目前生產環境應用最廣泛的。優點是性能較好,因爲在程序代碼中實現,不需要增加額外的設備作爲硬件開支。缺點是需要開發人員來實現,運維人員無從下手。
2. 基於中間代理層實現
代理一般是位於客戶端和服務器之間, 代理服務器接到客戶端請求後通過判斷然後轉發到後端數據庫。目前主要有兩個代表性程序:
mysql-proxy: mysql-proxy 爲 MySQL 開源項目,通過其自帶的 lua 腳本進行 SQL 判斷,雖然是 MySQL 官方產品,但是 MySQL 官方並不建議將 mysql-proxy 用到生產環境。
amoeba: 由陳思儒開發,作者曾就職於阿里巴巴,現就職於盛大。該程序由 java 語言進行開發,目前只聽說阿里巴巴將其用於生產環境。另外,此項目嚴重缺少維護和推廣。
mysql的讀寫分離集羣架構圖:
client----->mysql-proxy/Atlas代理(數據庫代理商)----->mysql-server服務器A(Read/Write可讀可寫)
----->mysql-server服務器B(ReadOnly可讀)
----->mysql-server服務器C(ReadOnly可讀)
----->mysql-server服務器D(ReadOnly可讀)
採用Atlas實現MySQL讀寫分離
Atlas的優點
(1)、基於mysql-proxy-0.8.2進行修改,代碼完全開源;
(2)、比較輕量級,部署配置也比較簡單;
(3)、支持DB讀寫分離;
(4)、支持從DB讀負載均衡,並自動剔除故障從DB;
(5)、支持平滑上下線DB;
(6)、具備較好的安全機制(IP過濾、賬號認證);
(7)、版本更新、問題跟進、交流圈子都比較活躍。
過程
1、安裝和配置atlas軟件
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
rpm -ql Atlas
echo "PATH=$PATH:/usr/local/mysql-proxy/bin/" > /etc/profile.d/atlas.sh
source /etc/profile.d/atlas.sh 加載環境配置文件
ll /usr/local/mysql-proxy/
cd /usr/local/mysql-proxy/bin/
./encrypt 01 生成加密密碼,並複製此密碼
注:此處的密碼01是mysql-server服務器上admin用戶賬號的密碼,請在後端的mysql-server服務器上用grant all on *.* to admin@'%' identified by '01' with grant option;來創建admin這個用戶。
cd /usr/local/mysql-proxy/conf/ 切換到atlas的配置文件目錄中
cp -av test.cnf test.cnf.bak //備份test.cnf配置文件
vi test.conf 修改後的讀寫分離的完整配置文件內容(以下紅字是要改的內容)
[mysql-proxy]
admin-username = user
admin-password = pwd
proxy-backend-addresses = 192.168.100.25:3306 後端負責讀寫的服務器IP和端口號
proxy-read-only-backend-addresses = 192.168.100.26:3306@1,192.168.100.27:3306@2
#以下的pwds是後端的mysql-server服務器上的用戶賬號和密碼,必須正確,否則mysql-proxyd服務無法啓動。
pwds = admin:VFnEp9P4Vu4=, rep:VFnEp9P4Vu4= //後端MYSQL的用戶名和encrypt命令生成的加密密碼
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log //日誌文件路徑
proxy-address = 0.0.0.0:3306 //Atlas監聽的管理接口IP和端口
admin-address = 0.0.0.0:2345 //Atlas監聽的管理接口IP和端口
啓動atlas服務:/usr/local/mysql-proxy/bin/mysql-proxyd test start
查atlas端口號:lsof -i :3306 和 lsof -i :2345
重啓atlas服務:/usr/local/mysql-proxy/bin/mysql-proxyd test restart
訪問atlas代理服務器的測試:
yum install -y mariadb 安裝mariadb客戶端軟件
mysql -uadmin -p01 -h 192.168.10.11 -P3306
登錄到atlas管理端:mysql -uuser -ppwd -h 192.168.10.11 -P2345
tcpdump抓包: tcpdump -i ens33 port 3306
說明:抓取經過192.168.10.11代理主機的ens33網卡的3306端口的數據包,驗證讀寫分離效果。
MySQL事務
事務:這個詞的字面意思是什麼?
答:要做的一件事情和任務。mysql中採用事務功能可以實現有選擇性胡對錶中數據操作做回滾、提交。
MYSQL默認處理任務的原則:執行增、刪、改操作會自動保存數據到庫、表、記錄中。
MYSQL的事務處理主要有兩種方法
一、用begin , rollback , commit來實現
begin: | 開始一個事務,然後執行create、update、insert等操作 |
rollback: | 事務回滾(相當於word中的ctrl+Z撤消) |
commit: | 事務確認(提交,相當於word中的ctrl+s保存) |
二、直接用set來改變mysql的自動提交模式
MYSQL默認是自動提交的,也就是你提交一個QUERY,它就直接執行!我們可以通過
show variables \G | 查看MYSQL環境變量 |
show variables like 'autocom%'; | 查看autocommit環境變量的狀態 |
set autocommit=0 | 禁止自動提交(臨時設置) (即自動開啓事務功能,並不需要用begin開始事務,但是必須用commit提交操作,或用rollback撤消操作) |
set autocommit=1 | 開啓自動提交(必須用begin開始一個事務,用commit或rollback結束事務) |
MySQL觸發器
觸發器(trigger)是一個特殊的存儲過程,它的執行不是由程序調用,也不是手工啓動,而是由事件(event)來觸發。比如當對A表進行操作事件( insert,delete, update)時就會激活它執行。觸發器經常用於加強數據的完整性約束和業務規則等。
作用
對A表做增insert、刪delete、改update操作,B表自動會執行某個SQL操作。
創建Trigger
語法:
CREATE TRIGGER 觸發器名稱 BEFORE | AFTER 觸發事件
ON 表名 FOR EACH ROW
BEGIN
觸發器程序體;
END
內容 | 解釋說明 |
<觸發器名稱> | 最多64個字符,它和MySQL中其他對象的命名方式一樣 |
{ BEFORE | AFTER } | 觸發器時機 |
{ INSERT | UPDATE | DELETE } | 觸發的事件 |
ON <表名稱> | 標識建立觸發器的表名,即在哪張表上建立觸發器 |
FOR EACH ROW | 觸發器的執行間隔:FOR EACH ROW子句通知觸發器 每隔一行 執行一次動作,而不是對整個表執行一次 |
<觸發器程序體> | 要觸發的SQL語句:可用順序,判斷,循環等語句實現一般程序需要的邏輯功能 |
例:
1、創建表
mysql> use test;
mysql> create table stu(
id int unsigned auto_increment primary key not null,
name varchar(50)
);
mysql> insert into stu(name) values('jack');
mysql> create table stu_total(total int);
mysql> insert into stu_total values(1);
2、創建觸發器stu_insert_trigger
mysql> delimiter $$ 臨時定義命令的結束符爲$$號 (或:\d )
mysql> create trigger stu_insert_trigger after insert
-> on stu for each row
-> BEGIN
-> update stu_total set total=total+1;
-> END$$
mysql> delimiter ; 臨時定義命令的結束符爲;號
3、優化過的正確觸發器
觸發器stu_insert_trigger
drop triggers stu_insert_trigger;
delimiter $$
create trigger stu_insert_trigger after insert
on stu for each row
BEGIN
update stu_total set total=(select count(*) from stu);
END$$
delimiter ;
查看觸發器
1. 通過SHOW TRIGGERS語句查看
SHOW TRIGGERS\G
2. 通過系統表triggers查看
USE information_schema
SELECT * FROM triggers\G
SELECT * FROM triggers WHERE TRIGGER_NAME='觸發器名稱'\G
測試觸發器
說明:插入兩條記錄,然後查stu表、stu_total表中的數據變化,驗證觸發器功能是否生效。
insert into stu values(2,'tom');
insert into stu values(3,'alice');
select * from stu;
select * from stu_total;
delete from stu where id=3;
select * from stu;
select * from stu_total;
刪除觸發器
通過DROP TRIGGERS語句刪除
DROP TRIGGER 解發器名稱
小結
以上案例是在stu表中插入一條記錄,stu_total表中的total字段的值就會自動加1,
在stu表中刪除一條記錄,stu_total表中的total字段的值就會自動減1。
此例的觸發器故障bug:如果stu_total表中的初始統計數據不正確,以上定義的這個觸發器會導致stu_total表中統計的total值跟stu表中的總記錄數信息不對稱,所以這個觸發器是有問題的。正確的解法是用count函數來統計stu表中的記錄數,不應該用加1或減1這種做法。
MySQL視圖
概念
MySQL視圖是一個虛擬表,其內容由查詢定義。同真實的表一樣,視圖包含一系列帶有名稱的列和行數據。但是,視圖並不在數據庫中以存儲的數據值集形式存在。行和列數據來自由定義視圖的查詢所引用的表,並且在引用視圖時動態生成。對其中所引用的基礎表來說,MySQL視圖的作用類似於篩選。
定義視圖的篩選可以來自當前或其它數據庫的一個或多個表,或者其它視圖。通過視圖進行查詢沒有任何限制,通過它們進行數據修改時的限制也很少。
視圖是存儲在數據庫中的SQL查詢語句,它主要出於兩種原因:
安全原因,視圖可以隱藏一些數據,如:一些敏感的信息
使複雜的查詢易於理解和使用。
視圖類似於excel中的篩選功能。
通俗理解:就是將一張表中經常要查詢的列和記錄創建成一張虛擬的表,其實viewer視圖中存放的是select語句。視圖中看到的數據會隨着原始表格的更新而動態更新。
作用
視圖其實就是將一條SQL的select查詢語句取個名字保存起來,當用select語句查詢這個視圖時,數據庫底層就是執行視圖中所保存的select語句。可以用視圖來提高數據庫的安全性。
創建視圖
語法一: |
CREATE [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE} ] VIEW 視圖名 [(字段1,字段2…)] AS SELECT語句 [WITH [CASCADED | LOCAL] CHECK OPTION ]; |
語法二: |
CREATE VIEW 視圖名 AS SELECT語句; |
查看視圖
1、SHOW TABLES 查看視圖名 SHOW TABLES; |
2、 SHOW TABLE STATUS 示例:查看數據庫mysql庫中視圖及所有表詳細信息 SHOW STATUS FROM mysql \G 示例:查看數據庫mysql中視圖名view_user詳細信息 SHOW TABLE STATUS FROM mysql LIKE 'view_user' \G
命令格式:show table status from 庫名 where 條件 例如:show table status from shop where Comment='VIEW'\G |
3. SHOW CREATE VIEW 示例:查看視圖定義信息 SHOW CREATE VIEW 視圖名\G |
4. DESCRIBE 示例:查看視圖結構 DESC 視圖名; |
修改視圖
方法一:刪除後新創建 |
DROP VIEW view_user ; CREATE VIEW view_user AS SELECT user,host FROM mysql.user; SELECT * FROM view_user; |
方法二:ALTER修改視圖 |
語法: ALTER VIEW 視圖名 AS SELECT語句;
示例: ALTER VIEW view_user AS SELECT user,password FROM mysql.user; |
通過視圖操作基表
查詢數據SELECT |
SELECT * FROM view_user; |
更新數據UPDATE |
刪除數據DELETE |
刪除視圖
語法:
DROP VIEW view_name [,view_name]…;
示例:
USE mysql;
DROP VIEW view_user ;
存儲過程
概念
是在大型數據庫系統中,一組爲了完成特定功能的SQL 語句集,存儲在數據庫中,經過第一次編譯後調用不需要再次編譯,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象。
本質作用
定義數據存儲的過程,存儲過程中允許對庫、表、記錄做增、刪、改、查等操作。
\d $$ 等同於delimiter $$,設置命令的界定符(也稱結束符)
例:創建一個名稱爲dba的庫文件,在dba庫中創建一張名稱爲tb1的表,表中有id、name這兩個字段。創建一個名稱爲ad1的存儲過程,ad1存儲過程的功能是插入三條記錄到tb1表中。
mysql>create database dba;
mysql>use dba;
mysql>create table tb1(id int,name char(20));
mysql> \d $$ 等同於delimiter $$,設置命令的界定符(也稱結束符)
mysql> create procedure ad1() 創建ad1這個存儲過程(類似於shell腳本)
-> BEGIN
-> declare i int default 1;
-> while(i<=3)do
-> insert into dba.tb1 values(i,'ccc');
-> set i=i+1;
-> end while;
-> END$$
mysql> \d ;
mysql> select * from tb1;
mysql> call ad1(); 調用此存儲過程
mysql> select * from tb1;
練習:定義一個名稱爲ak的存儲過程,功能是實現創建一個名稱爲dbak的庫,在dbak庫中創建tbak表,tbak表中有id、name這兩個字段,在tbak表中插入2條記錄1、tom和2、alice的信息。測試ak這個存儲過程的調用。
1)首先,創建存儲過程。
\d $$
create procedure ak()
BEGIN
create database dbak;
create table dbak.tbak(id int,name char(20));
desc dbak.tbak;
insert into dbak.tbak values(1,'tom'),(2,'alice');
select * from dbak.tbak;
END$$
2)然後,調用存儲過程:call ak();
常用函數
查看當前的時間:select now();
查看版本號:select version();
存儲過程(procedure)和函數(function)的主要區別:
存儲過程是針對表中的數據記錄進行處理的SQL語句集合,就類似於shell腳本。
函數通常是針對記錄中的某個字段的值進行處理。
索引
概念
索引在MySQL中也叫做“鍵”,是存儲引擎用於快速找到記錄的一種數據結構。索引對於良好的性能非常關鍵,尤其是當表中的數據量越來越大時,索引對於性能的影響愈發重要。
索引優化應該是對查詢性能優化最有效的手段了。索引能夠輕易將查詢性能提高好幾個數量級。
索引相當於字典的音序表,如果要查某個字,如果不使用音序表,則需要從幾百頁中逐頁去查。
我的理解:索引,就是檢索引導的意思。是通過一定的算法將數據庫中的記錄按一定的規律進行分組,查信息時可以縮小數據的搜索範圍,從而提高了查詢效率。
索引爲什麼可以提高數據查詢速度?
索引底層的工作是會將表中的數據記錄按一定算法(規律)進行分組,用戶在查數據時會自動到所對應的組中去查,這樣就縮小了查詢範圍,所以提高了效率。
過程
創建索引
創建表時創建索引
CREATE在已存在的表上創建索引
ALTER TABLE在已存在的表上創建索引
查看並測試索引
刪除索引
分類
普通索引 |
唯一索引 |
全文索引:只有MYISAM存儲引擎支持全文索引,innodb存儲引擎不支持全文索引。 |
單列索引 |
多列索引 |
空間索引 |
創建索引
創建表時
語法:
CREATE TABLE 表名 (
字段名1 數據類型 [完整性約束條件…],
字段名2 數據類型 [完整性約束條件…],
[UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY
[索引名] (字段名[(長度)] [ASC |DESC])
);
CREATE對已存在的表創建索引
語法:
CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名
ON 表名 (字段名[(長度)] [ASC |DESC]) ;
ALTER TABLE在已存在的表上創建索引
語法:
ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL ] INDEX
索引名 (字段名[(長度)] [ASC |DESC]) ;
例1:
CREATE TABLE dept10 (
dept_id INT,
dept_name VARCHAR(30) ,
comment VARCHAR(50),
INDEX index_dept_name (dept_name) 將表中的dept_name字段指定爲普通索引字段
);
例2:創建唯一索引示例:(此方法要指定索引名稱)
CREATE UNIQUE INDEX index_dept_name ON dept6 (dept_name);
例3:
用創建普alter通索引示例:
ALTER TABLE dept ADD INDEX index_dept_name (dept_name);
命令格式:alter table 表名 add index 索引名 (字段名);
管理索引
查看索引: | SHOW CRETAE TABLE 表名\G |
測試示例: | EXPLAIN SELECT * FROM dept WHERE dept_name='hr'; |
刪除索引: | show create table employee6; DROP INDEX 索引名 ON 表名; |
MySQL多表查詢
多表連接查詢
生成笛卡爾積,它不使用任何匹配條件(很少用) | |
內連接: | 只連接匹配的行,需要用where指定條件 |
外連接之左連接: | 會顯示左邊表內所有的值,不論在右邊表內匹不匹配 |
外連接之右連接: | 會顯示右邊表內所有的值,不論在左邊表內匹不匹配 |
全外連接: | 包含左、右兩個表的全部行 |
複合條件連接查詢
例1:以內連接的方式查詢emp6和dept6表,並且emp6表中的age字段值必須大於25
mysql> select emp_id, emp_name, age, dept_name from emp6,dept6 where emp6.dept_id = dept6.dept_id and age>25;
即:找出公司所有部門中年齡大於25歲的員工
子查詢
子查詢是將一個查詢語句嵌套在另一個查詢語句中。
內層查詢語句的查詢結果,可以爲外層查詢語句提供查詢條件。
子查詢中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等關鍵字
還可以包含比較運算符:= 、 !=、> 、<等
將一個select查詢語句的結果作爲另一個select查詢語句的條件。
例:select * from A表 where id in (select id from B表 where id=3)
MySQL常用語句總結
SQL語句總結: |
登錄和退出MySQL mysql -uroot -p密碼 exit 或者:\q 示例: mysql -h192.168.5.240 -P 3306 - u root -p123 mysql -e ‘select user,host from user’ -h 指定主機名 -P MySQL服務器端口 -u 指定用戶名 -p 指定登錄密碼 此處mysql爲指定登錄的數據庫 -e 接SQL語句 |
庫的操作: |
1、查庫:show databases; 2、建庫:create database 庫名 [選項]; 3、開庫:use 庫名; 4、刪庫:drop database 庫名; |
表的操作: |
1、查表(顯示庫中的表文件):show tables; 2、建表:create table 表名(字段1 類型 約束,字段2 類型 約束,...); 3、查表結構:desc 表名; 4、表中新增一列(在最後):alter table 表名 add 字段名 類型 約束; 5、刪除表中的sex這個字段(列):alter table 表名 drop sex; 6、刪除表:drop table 表名; |
記錄操作: |
1、查表中的所有記錄:select * from 表名; 2、查test庫中表tb1的id<=3的所有記錄:select * from test.tb1 where id<=3; 3、在tb1表中插入一行記錄:insert into tb1 values(值1,值2,...); 4、更新tb1表中name爲jack的記錄,將他的name值更新成jacker: update tb1 set name='jacker' where name='jack'; 5、刪除tb1表中id<=3的記錄:delete from tb1 where id<=3; |
授權管理(用戶安全管理): |
1、查mysql庫中user表的user、host、password字段的數據記錄:(查mysql系統中的用戶賬號) select user,host,password from mysql.user;
2、在mysql中創建一個跟root賬號相同權限的新賬號admin: grant all on *.* to admin@'%' identified by '密碼' with grant option;
3、查看root賬號的授權信息: show grants for root@'localhost';
4、回收admin賬號的insert、update、delete權限: revoke insert,update,delete on *.* from admin@'主機名或IP';
5、刪除admin賬號: drop user admin@'主機名或IP';
|