如今互聯網的主流關係型數據庫是mysql,掌握其基本的增、刪、改、查是每個測試人員必備的技能。 html
一、DDL語句(數據庫定義語言): 數據庫、表、視圖、索引、存儲過程,例如:CREATE、DROP、ALTER python
二、DML語句(數據庫操縱語言): 插入數據INSERT、刪除數據DELETE、更新數據UPDATE、查詢數據SELECT mysql
三、DCL語句(數據庫控制語言): 控制用戶的訪問權限GRANT、REVOKE sql
咱們能夠把庫看作是文件夾。數據庫
mysql自帶的庫:性能優化
information_schema: 虛擬庫,不佔用磁盤空間,存儲的是數據庫啓動後的一些參數,如用戶表信息、列信息、權限信息、字符信息等服務器
performance_schema: MySQL 5.5開始新增一個數據庫:主要用於收集數據庫服務器性能參數,記錄處理查詢請求時發生的各類事件、鎖等現象函數
mysql: 受權庫,主要存儲系統用戶的權限信息性能
test: MySQL數據庫系統自動建立的測試數據庫測試
鏈接數據庫,查看已有的數據庫,show databases;
展現了已有的全部庫(包含了我本身建立的數據庫),若是隻看到部分數據庫,解決方案參考:http://www.javashuo.com/article/p-xlchatlo-hs.html
建立庫,指定編碼,create database qzcsbj charset utf8;
庫的存放位置
show create database qzcsbj;
show databases;
查看當前所在的庫
select database();
修改編碼,alter database qzcsbj charset gbk;
drop database qzcsbj;
咱們能夠把表看作是文件
切換數據庫(文件夾):use qzcsbj ;
查看當前所在數據庫(文件夾):select database();
create table 表名( 字段名1 類型[(寬度) 約束條件], 字段名2 類型[(寬度) 約束條件], 字段名3 類型[(寬度) 約束條件] );
增長前,只有一個opt文件
create table test(id int, name varchar(255));
增長後,多了一個frm文件,frm是表結構
show create table test \G; # \G表示按行顯示錶的詳細結構
show tables;
desc test; # 等價於describe test;
insert test(id,name) values(1,'qzcsbj1'),(2,'qzcsbj2'),(3,'qzcsbj3');
複製表結構+記錄:
create table test2 select * from test;
只複製表結構:
create table test3 select * from test where 1=2;
或者:
create table test4 like test;
ALTER TABLE 表名 # 修改表名 RENAME 新表名; # 增長字段 ADD 字段名 數據類型 [完整性約束條件…]; ADD 字段名 數據類型 [完整性約束條件…] FIRST; # 添加到第一個字段 ADD 字段名 數據類型 [完整性約束條件…] AFTER 字段名; # 添加到某個字段以後 # 刪除字典 DROP 字段名; # 修改字段 MODIFY 字段名 數據類型 [完整性約束條件…]; CHANGE 舊字段名 新字段名 舊數據類型 [完整性約束條件…]; CHANGE 舊字段名 新字段名 新數據類型 [完整性約束條件…];
MODIFY,能夠改字段屬性
CHANGE,能夠改字段名、字段屬性
alter table test modify name varchar(256);
desc test;
alter table test change name NAME varchar(257);
desc test;
drop table test;
show tables;
記錄能夠看作文件夾中文件的內容
全字段插入
INSERT INTO 表名(字段1,字段2,字段3…字段n) VALUES(值1,值2,值3…值n); # into能夠省略
多條數據逗號分隔
INSERT INTO 表名 VALUES (值1,值2,值3…值n), (值1,值2,值3…值n), (值1,值2,值3…值n);
指定字段插入
INSERT INTO 表名(字段1,字段2,字段3…) VALUES (值1,值2,值3…);
插入查詢結果
INSERT INTO 表名(字段1,字段2,字段3…字段n) SELECT (字段1,字段2,字段3…字段n) FROM 表2 WHERE …;
create table test(id int, name varchar(255));
insert test(id,name) values(1,'qzcsbj1'),(2,'qzcsbj2'),(3,'qzcsbj3');
select * from test;
若是在其它庫查test,表前必須加庫做爲前綴。
select * from qzcsbj.test;
UPDATE 表名 SET 字段1=值1 WHERE 約束條件;
update test set name='qzcsbj' where id=2;
delete from test where id=3;
delete,用於刪除數據,自增加字段的值未重置
truncate,用於清空表,自增加字段的值也被重置
注意:delete不能給表取別名
參考:https://www.runoob.com/mysql/mysql-data-types.html
年:year
年月日:date
時分秒:time
年月日時分秒:datetime
create table student( id int, name char(6), # 最大存儲6個字符 born_year year, # 年 birth_date date, # 年月日 class_time time, # 時分秒 reg_time datetime # 年月日時分秒 );
插入數據
insert into student values(1,'jack',now(),now(),now(),now()); insert into student values(2,'tom',"2017","2017-12-12","12:12:12","2017-12-12 12:12:12");
now()是mysql提供的函數
# 寬度指的是字符的個數 create table test(name char(5)); create table test(name varchar(5));
char:按指定長度存,存取速度快,可是當存的數據的長度小於字段定義的長度時浪費空間
varchar:存數據更精簡,更加節省空間(是在存的數據的長度小於字段定義的長度時;不然必char浪費空間,由於多少了頭,要花1個byte),缺點,存取速度慢,要先存頭,再存數據;先取頭,再取數據;
現現在,存儲空間已經不是限制了,要追求存取速度,大部分用char,與查詢無關的用varchar
建表的時候,定長的數據往前放,變長的日後放,並且,一張表中,不要char和varchar混用
enum 單選,只能在給定的範圍內選一個值,如性別
sex enum('male','female','other'),
set 多選,在給定的範圍內能夠選擇一個或一個以上的值(愛好1,愛好2,愛好3...)
hobbies set('play','music','read','run')
drop table test;
create table test( id int, name char(16), sex enum('male','female','other'), hobbies set('play','music','read','run') );
插入
insert into test values(1,'jack','male','music,read'); # 集合多個值用逗號分隔
分類
一、InnoDB 存儲引擎 二、MyISAM 存儲引擎 三、NDB 存儲引擎 四、Memory 存儲引擎 五、Infobright 存儲引擎 六、NTSE 存儲引擎 七、BLACKHOLE
詳見mysql性能調優篇。
做用:保證數據的完整性和一致性
分類
PRIMARY KEY (PK),標識該字段爲該表的主鍵,能夠惟一的標識記錄 FOREIGN KEY (FK),標識該字段爲該表的外鍵 NOT NULL,標識該字段不能爲空 UNIQUE KEY (UK),標識該字段的值是惟一的 AUTO_INCREMENT, 標識該字段的值自動增加(整數類型,並且爲主鍵) DEFAULT, 爲該字段設置默認值
#方法一:在某一個字段後用primary key
drop table test; create table test( id int primary key, name char(255) );
#方法二:not null+unique
建立表時未指定主鍵,會找不爲空且惟一的字段做爲主鍵
drop table test; create table test( id int not null unique, name char(255) );
#方法三:在全部字段後單獨定義primary key
drop table test; create table test( id int, name varchar(255), constraint pk_name primary key(id) );
創建表之間的關係
create table student( id int primary key, name char(255), age int ); # 關聯的表 create table class( id int primary key, name char(255), stu_id int, foreign key(stu_id) references student(id) on delete cascade # 刪除同步 on update cascade # 修改同步 );
drop table test;
create table test( id int, name char(255), sex enum('male','female') not null default 'male' );
單列惟一:方式一
drop table test; create table test( id int unique, name char(255) unique );
單列惟一:方式二
drop table test; create table test( id int, name char(255), unique(id), unique(name) );
聯合惟一
drop table test; create table test( id int, name char(255), unique(id,name) );
複合主鍵
drop table test; create table test( id int, name char(255), primary key(id, name) );
約束字段爲自動增加,增加字段必須設置爲key,primary key,unique key
drop table test; create table test( id int primary key auto_increment, name char(255) );
一對一:身份證號與姓名
一對多:一個班級有多個學生
多對多:一個老師給多個班級授課,一個班級有多位授課老師
一個單表複雜且完整的sql格式是以下的樣子,若是是多表,加個join及鏈接條件就能夠了,很簡單。
select distinct 字段1,字段2,字段3 # 要查詢的字段或者分組字段聚合函數 from 庫.表 # 從哪一個表查,若是當前所在的庫不是這個表所在的庫,表的前面須要加上庫名 where # 約束條件 group by # 分組 having # 過濾 order by # 排序 limit # 限制條數
select distinct 字段1,字段2,字段3 # 要查詢的字段或者分組字段聚合函數
去重
from 庫.表 # 從哪一個表查,若是當前所在的庫不是這個表所在的庫,表的前面須要加上庫名
where是分組以前過濾,後面是普通條件
1.比較運算符:><>= <= <> != 2.邏輯運算符:在多個條件直接可使用邏輯運算符 and or not 3.between 10 and 100 值在10到100之間 4.in(80,90) 值是80或90 5.like 'qzcsbj%',除了%還能夠_,%表示任意多字符,_表示一個字符
通常來講,「每」這個字後面的字段,就是咱們分組的字段
having是分組以後過濾,後面是聚合條件
聚合函數(以組爲單位進行統計)
max,最大
min,最小
avg,平均
sum,和
count,數量
默認升序,asc
降序,desc
也能夠先按某個字段升序,再按某個字段降序,例如:select * from test order by id asc, name desc;
limit n,默認初始位置爲0,從1開始取,取n條,若是不足n條記錄,那麼有多少條就取多少條
limit m,n,表示位置m,從m+1開始取,取n條記錄,若是不足n條記錄,那麼有多少條就取多少條
5 select
6 distinct 1 from 庫.表 2 where 3 group by 4 having 7 order by 8 limit
咱們不可能把數據都存在一個表中,而是存多個表中,這就涉及到多表查詢了
生成笛卡爾積,不適用任何匹配條件。
只取兩張表的共同部分,join on
顯示左表所有記錄,在內鏈接的基礎上增長左邊有右邊沒有的結果,left join on
顯示右表所有記錄,在內鏈接的基礎上增長右邊有左邊沒有的結果,right join on
顯示左右兩個表所有記錄,在內鏈接的基礎上增長左邊有右邊沒有的和右邊有左邊沒有的結果,
union,其與union all的區別是,union會去掉相同的紀錄,另外,mysql不支持full join on
建立新用戶:CREATE USER 'test'@'localhost' IDENTIFIED BY '123456';
新用戶受權:GRANT ALL PRIVILEGES ON *.* TO 'test'@'%'IDENTIFIED BY '123456' WITH GRANT OPTION;
受權(只能root操做) *.* # 全部庫下的全部表(以及表下的全部字段)都有權限 qzcsbj.* # test庫下的全部表(qzcsbj數據庫下全部表,以及表下的全部字段) qzcsbj.test # qzcsbj庫下test表(某一張表,以及該表下的全部字段) columns_priv字段:id,name # 字段(某一個或幾個字段),grant select(id,name),update(name) on qzcsbj.test to 'test'@'localhost'; 收回權限 revoke select on qzcsbj.test from 'test'@'localhost';
刷新受權:flush privileges;
(待補充)
數值函數
字符串函數
日期時間函數
流程控制函數
系統信息函數
見性能優化篇
參考:http://www.javashuo.com/article/p-mwptzawp-cx.html
表關係: 下面每一個表的第一個字段是主鍵,未創建外鍵,使用邏輯外鍵
班級表
DROP TABLE IF EXISTS `class`; CREATE TABLE `class` ( `cid` int(11) NOT NULL AUTO_INCREMENT, `caption` varchar(255) NOT NULL, `grade_id` int(11) NOT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
年級表
DROP TABLE IF EXISTS `class_grade`; CREATE TABLE `class_grade` ( `gid` int(11) NOT NULL AUTO_INCREMENT, `gname` varchar(255) NOT NULL, PRIMARY KEY (`gid`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
課程表
DROP TABLE IF EXISTS `course`; CREATE TABLE `course` ( `cid` int(11) NOT NULL, `cname` varchar(255) NOT NULL, `teacher_id` int(11) NOT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
成績表
DROP TABLE IF EXISTS `score`; CREATE TABLE `score` ( `sid` int(11) NOT NULL AUTO_INCREMENT, `student_id` int(11) NOT NULL, `course_id` int(11) NOT NULL, `score` varchar(255) DEFAULT NULL, PRIMARY KEY (`sid`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
學生表
DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `sid` int(11) NOT NULL AUTO_INCREMENT, `sname` varchar(255) NOT NULL, `gender` enum('女','男') NOT NULL DEFAULT '男', `class_id` int(11) NOT NULL, PRIMARY KEY (`sid`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
老師表
DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` ( `tid` int(11) NOT NULL, `tname` varchar(255) DEFAULT NULL, PRIMARY KEY (`tid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
班級任職表
DROP TABLE IF EXISTS `teacher2cls`; CREATE TABLE `teacher2cls` ( `tcid` int(11) NOT NULL AUTO_INCREMENT, `tid` int(11) NOT NULL, `cid` int(11) NOT NULL, PRIMARY KEY (`tcid`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
你們本身完成,這樣能夠熟悉表關係。
1.查詢「生物」課程和「物理」課程成績都及格的學生id和姓名;
2.查詢每一個年級的班級數,取出班級數最多的前三個年級;
3.查詢每位學生的學號,姓名,選課數,平均成績;
4.查詢每一個年級的學生人數;
(文末加羣獲取參考答案)