導讀
MySql是我們常用的數據庫,javaEE常用幾款(Oracle,PostgreSQL,DB2或IBM),SQLite是用於嵌入式設備裏的小型數據庫,例如Android或IOS,而掌握SQL語句,就相當於掌握了所有的常見關係化數據庫,需要同學們重點掌握以及經常複習
MySQL數據庫服務器、數據庫和表的關係
- 一般一個項目建一個數據庫,數據庫中又有一張張的table,table中的一條數據庫語句,相當於java中的實體bean類
- 一個java類 對應數據庫中一張數據表,一個java對象 對應數據表中一條數據記錄
SQL語言
Structured Query Language(SQL語言),結構化查詢語言
非過程性語言爲加強SQL的語言能力,各廠商增強了過程性語言的特徵
- 如Oracle的PL/SQL 過程性處理能力
- SQL Server、Sybase的T-SQL
SQL是用來存取關係數據庫的語言,具有查詢、操縱、定義和控制關係型數據庫的四方面功能
SQL分類
DDL (數據定義語言)
- 數據定義語言 - Data Definition Language
- 用來定義數據庫的對象,如數據表、視圖、索引等
- 即操作數據庫或表結構的
- 所有數據庫相關操作語句,數據庫表結構操作語句都屬於DDL
DML (數據操縱語言)
- 數據處理語言 - Data Manipulation Language
- 在數據庫表中更新,增加和刪除記錄
- 如 update, insert, delete
DCL (數據控制語言)
- 數據控制語言 – Data Control Language
- 指用於設置用戶權限和控制事務語句
- 如grant,revoke,if…else,while,begin transaction
DQL (數據查詢語言)
- 數據查詢語言 – Data Query Language
- select
SQL語句(重點)
掌握SQL語句,相當於掌握了所有的常見關係化數據庫,需要重點掌握以及經常複習
數據庫操作建議先在.txt文件,寫好再把光標移動語句最後,shift+home複製整句過去
編寫sql語句沒有大小寫之分,注意不要拼錯單詞
MySQL5中文參考手冊 -> 部分不知道的字段可以通過這個文檔查詢
數據庫操作:
一 . 創建數據庫
- 語法 : create database 數據庫名稱; (創建數據庫採用數據庫服務器默認字符集)
- 複雜寫法 : create database 數據庫名稱 character set 字符集 collate 比較規則;
練習:
1. 創建一個名稱爲mydb1的數據庫。 create database mydb1;
2. 創建一個使用utf8字符集的mydb2數據庫。 create database mydb2 character set utf8;
3. 創建一個使用utf8字符集,並帶校對規則的mydb3數據庫。create database mydb3 character set utf8 collate utf8_bin;
==**補充: 每次創建一個數據庫在 數據存放目錄中生成一個文件夾 , 每個文件夾中存在 db.opt 存放默認字符集和校對規則
datadir=”C:/Documents and Settings/All Users/Application Data/MySQL/MySQL Server 5.5/Data/”**==
二 . 查詢數據庫
- 語法 : show databases; —– 查看所有數據庫,沒有數據庫則返回沒數據null
- 語法 : show create database 數據庫名; —— 查看數據編碼集
練習:
1. 查看當前數據庫服務器中的所有數據庫 show databases;
2. 查看前面創建的mydb2數據庫的定義信息 show create database mydb2;
三 . 刪除數據庫
- 語法 : drop database 數據庫名稱;
練習:
1. 刪除前面創建的mydb1數據庫 drop database mydb1;
四 . 修改數據庫
- 語法 : alter database 數據庫名稱 character set 字符集 collate 比較規則;
練習:
1. 修改mydb2字符集爲gbk; alter database mydb2 character set gbk;
==補充:==
1. 切換數據庫 use db_name; -> 當有多個數據庫的情況,需要use db_name; 先切換到要操作的數據庫
2. 查看當前正在使用數據庫: select database();
數據表操作:
一 . 創建數據表
- 語法 : create table 表名(列名 類型(長度),列名 類型(長度)… );
格式 :
create table 表名(
列名稱1 列名稱1值類型,
列名稱2 列名稱2值類型,
列名稱3 列名稱3值類型,
列名稱4 列名稱4值類型
);
列名稱1值類型 是 mysql 中運行的值的類型
注意最後一句沒有 ,
- MySQL 常用數據類型:
類型 | 說明 |
---|---|
字符串型—String | Varchar(可變值)、char(固定值) ->若兩者最大值都爲30,varchar如果數據只有20,最後就爲20;char如果數據只有20,會自動補齊,char比varchar效率高點 |
大數據類型—字節流,字符流 | BLOB、TEXT |
數值型–數值類型 (bit,byte,short,int,long,float,double) | TINYINT 、SMALLINT、INT、BIGINT、FLOAT、DOUBLE |
邏輯型 | BIT 存放以爲數值 0 或者 1 |
日期型 | DATE(只有日期)、TIME(只有時間)、DATETIME(日期和時間)、TIMESTAMP時間可以自動跟新(當前時間) |
練習 :
創建一個員工表employee ---- 查看錶結構: desc 表名;
字段 屬性
id 整形 int
name 字符型 varchar(30)
gender 字符型 varchar(10)
birthday 日期型 date
entry_date 日期型 date
job 字符型 varchar(50)
salary 小數型 double
resume 大文本型 varchar(255)
create table employee(
id int,
name varchar(30),
gender varchar(10),
birthday date,
entry_date date,
job varchar(50),
salary double,
resume varchar(255)
);
==補充:==
1. 創建表時沒有指定字符集,將採用數據庫默認字符集
2. 創建表之前 必須使用use db_name 語法指定操作數據庫
3. 查看錶結構: desc 表名
4. 創建數據表時,只有字符串類型必須寫長度,而其他類型都有默認長度
5. 一個java類 對應數據庫中一張數據表,一個java對象 對應數據表中一條數據記錄
二 . 定義單表字段的約束
約束用來保證數據有效性和完整性
- 有效性: 類似日常生活防止姓名一樣,給個身份證號以保證身份的唯一性
- 完整性: 類似生活中一個人不告訴我們姓名就不讓他存數據,保證數據的完整性
定義主鍵約束(唯一,並且非空):
primay key -> 信息記錄某個字段可以唯一區分其他信息記錄,這個字段就可以是主鍵
如果列的類型爲數值型(int bigint),並且聲明爲主鍵,那麼通常會加上auto_increment,表示自動增長
唯一約束(不能重複,可以爲空):
unique -> 一張表中可以有很多個唯一約束,只能有一個(兩個)作爲主鍵約束
非空約束(可以重複,不能爲空):
not null
練習:
create table employee2(
id int primary key auto_increment,
name varchar(30) not null,
gender varchar(10) not null,
birthday date,
entry_date date,
job varchar(50),
salary double not null,
resume varchar(255) unique
);
三 . 修改數據表結構
- 增加列 語法: alter table 表名 add 列名 類型(長度) 約束;
- 修改現有列類型、長度和約束 語法:alter table 表名 modify 列名 類型(長度) 約束;
- 修改現有列名稱 語法:alter table 表名 change 舊列名 新列名 類型(長度) 約束;
- 刪除現有列 語法:alter table 表名 drop 列名;
- 修改表名 rename table 舊錶名 to 新表名;
練習:
1. 修改表的字符集:—-alter table student character set utf8;
2. 在上面員工表的基本上增加一個image列: —-alter table employee add image varchar(100);
3. 修改job列,使其長度爲60。 —-alter table employee modify job varchar(60) not null;
4. 刪除gender列。 —-alter table employee drop gender ;
5. 表名改爲user。 —-rename table employee to user;
6. 修改表的字符集爲utf8 —- alter table user character set utf8;
7. 列名name修改爲username —– alter table user change name username varchar(20) unique not null;
==補充:==
1. 查看當前數據庫內所有表:show tables;
2. 查看當前數據表字符集 : show create table user;
3. 查看錶結構 : desc 表名;
四 . 刪除數據表
- 語法:drop table 表名;
練習:
1. 刪除employee2表:drop table employee2;
數據表中數據記錄的增刪改查操作:
一 . 插入數據:
語法一(全寫) :insert into 表名(列名,列名,列名…) values(值,值,值…);
- 如:insert into employee2(id,name,gender,birthday,entry_date,job,salary,resume) values(1,’zs’,’female’,’1995-09-09’,’2015-12-09’,’developer’,15000,’a good developer’);
語法二(只寫部分,字段值屬性爲空的可以不寫,不爲空的值要寫)
- 如:insert into employee2 (id,name,gender,salary,resume) values(null,’haojie’,’male’,17000,’a hansome boy’);
語法三(不寫字段名稱,只寫字段值,但是所有的字段值都要寫)
- 如:insert into employee2 values(null,’linpeng’,’male’,’1994-09-09’,’2015-12-22’,’programmer’,16000,’a lady killer’);
==補充:==
1. 插入值 類型必須和 列類型匹配
2. 值長度不能超過 列定義長度
3. 值的順序和 列順序對應
4. 字符串和日期型值 必須寫 單引號
5. 插入空值 可以寫 null
6. 插入記錄後,使用select * from 表名; 查看錶信息
可能出現的bug:
插入一條中文記錄
insert into employee(id,name,job,salary) values(4,'小明','清潔員',1500);
出錯了:
ERROR 1366 (HY000): Incorrect string value: '\xC3\xF7' for column 'name' at row 1 ;
錯誤原因:mysql client 採用默認字符集編碼 gbk
查看系統所有字符集 : show variables like 'character%';
解決:修改客戶端字符集爲gbk
MYSQL中共有6個地方字符集 :client connetion result 和客戶端相關 、database server system 和服務器端相關
第一種:
當前窗口臨時修改 set names gbk ;
* 只對當前窗口有效,關閉後就會失效
第二種:
配置mysql/my.ini 文件
[mysql] 客戶端配置
[mysqld] 服務器端配置
修改客戶端字符集 [mysql] 後字符集 default-character-set=gbk
使用mysql -u root -p 密碼連入數據庫後,如果進行數據庫操作,直接操作,如果要進行數據表結構和數據記錄操作,必須先切換到操作的數據庫 use db;
二 . 數據記錄更改操作:
- 語法: update 表名 set 列名=值,列名=值…. where條件語句;
- 如果沒有where條件語句,默認修改所有行數據
練習:
1. 將所有員工薪水修改爲5000元。 —– update employee set salary = 5000;
2. 將姓名爲’zhangsan’的員工薪水修改爲3000元。 ——- update employee set salary = 3000 where name=’zhangsan’;
3. 將所有員工薪水修改爲5000元。 ——- update employee set salary=4000, job=’ccc’ where name=’lisi’;
4. 將wangwu的薪水在原有基礎上增加1000元。 ———— update employee set salary = salary+1000 where name =’wangwu’;
三 . 數據記錄的刪除操作:
語法:delete from 表名 where條件語句;
- 如果沒有where語句,將刪除表中 所有記錄
語法: truncate table 表名;
練習:
1. 刪除表中名稱爲’zs’的記錄。—-delete from employee2 where name=’zs’;
2. 刪除表中所有記錄(DML語句)。—-delete from employee2;
3. 使用truncate刪除表中記錄。(先將表摧毀,然後再創建, 屬於DDL語句)—-truncate table employee2;
==補充:==
truncate 與 delete區別
1. truncate 刪除數據,過程先將整個表刪除,再重新創建
2. delete 刪除數據,逐行刪除記錄
3. truncate 屬於DDL,delete屬於DML——-事務管理只能對DML有效,被事務管理SQL語句可以回滾到SQL執行前狀態
4. truncate 效率要好於 delete
四 . 數據表記錄的查詢(DQL語句):
- 語法一 : select [distinct] * | 列名,列名… from 表名;
- select * from 表名; 查詢該表中所有列信息
- select 列名,列名… from 表名; 查詢表中指定列的信息
- distinct 用於去重
練習:
create table exam(
id int primary key auto_increment,
name varchar(20) not null,
chinese double,
math double,
english double
);
insert into exam values(null,'關羽',85,76,70);
insert into exam values(null,'張飛',70,75,70);
insert into exam values(null,'趙雲',90,65,95);
查詢表中所有學生的信息。 --------- select * from exam;
查詢表中所有學生的姓名和對應的英語成績。 ----- select name,english from exam;
過濾表中重複數據 (查詢英語成績,排除完全相同重複數據) ---- select distinct english from exam;
- 語法二 : select 列名 as 別名 from 表名;
練習:
1. 在所有學生分數上加10分特長分。 —- select name,chinese+10,math+10,english+10 from exam;
2. 統計每個學生的總分。——- select name,chinese+math+english from exam;
3. 使用別名表示學生分數。—– select name,chinese+math+english as 總分 from exam;
4. 在對列起別名時,as可以省略 select name,chinese+math+english as 總分 from exam; —— select name,chinese+math+english 總分 from exam;
5. select name,math from exam; 查詢name和math兩列的值
6. select name math from exam; 查詢name列值,起別名math
- 語法三 : select 列名 from 表名 where條件語句
練習:
1. 查詢姓名爲關羽的學生成績 ——-select * from exam where name=’關羽’;
2. 查詢英語成績大於90分的同學 —– select * from exam where english > 90;
3. 查詢總分大於200分的所有同學 —– select * from exam where chinese+math+english > 200;
- 語法四 : select * from 表名 order by 列名 asc|desc; —- asc升序 desc降序
練習:
1. 對數學成績排序後輸出。———– select * from exam order by math; 默認asc升序
2. 對總分排序按從高到低(降序)的順序輸出 ———— select * from exam order by math+chinese+english desc;
3. 對學生成績按照英語進行降序排序,英語相同學員按照數學降序 ————- select * from exam order by english desc,math desc;
- 語法五:select 分組函數 from exam group by 列名; 按照某列進行分組統計 分組操作,就是具有相同數據記錄分到一組中,便於統計
練習:
create table orders(
id int,
product varchar(20),
price float
);
insert into orders(id,product,price) values(1,'電視',900);
insert into orders(id,product,price) values(2,'洗衣機',100);
insert into orders(id,product,price) values(3,'洗衣粉',90);
insert into orders(id,product,price) values(4,'桔子',9);
insert into orders(id,product,price) values(5,'洗衣粉',90);
對訂單表中商品歸類後,顯示每一類商品的總價 ---- 需要按照商品名稱進行分組
select product,sum(price) from orders group by product;
在group by 語句後面 添加having 條件語句 ---- 對分組查詢結果進行過濾
查詢購買了幾類商品,並且每類總價大於100的商品
select product,sum(price) from orders group by product having sum(price) > 100;
運算符:
相等= 不等 <>
between …and… 在兩者之間取值 between 70 and 80 等價於 >=70 <=80 —– 注意前面那個數要比後面那個數要小
in(值,值,值) 在指定值中任取一個 in(70,80,90) 值可以是70、80或者90
**like ‘模糊查詢pattern’ 進行模糊查詢 ,表達式有兩個佔位符 % 任意字符串 _ 任意單個字符 例如: name like ‘張%’ 所有姓張學員
name like ‘張_’ 所有姓張名字爲兩個字學員**is null 判斷該列值爲空
and 邏輯與 or 邏輯或 not 邏輯非
練習:
查詢英語分數在 90-100之間的同學。 -------- select * from exam where english>=90 and english <= 100; select * from exam where english between 90 and 100;
查詢數學分數爲65,75,85的同學。 ---- select * from exam where math in(65,75,85);
查詢所有姓趙的學生成績。---- select * from exam where name like '趙%';
查詢英語分>80,語文分>80的同學。 ---- select * from exam where english > 80 and chinese > 80;
insert into exam values(null,'劉備',null,55,38);
查詢語文沒有成績學員 select * from exam where chinese is null;
查詢語文有成績學員 select * from exam where chinese is not null;
聚集函數 指SQL語句中內置函數 ———- 分組函數(用於統計):
- count 統計查詢結果記錄條數 select count(*)|count(列名) from 表名;
練習:
1. 統計一個班級共有多少學生?———— select count( * ) from exam;
2. 統計英語成績大於90的學生有多少個? ——- select count( * ) from exam where english > 90;
3. 統計總分大於220的人數有多少? ——–select count( * ) from exam where chinese+math+english > 220;
- sum 統計某一列數據的和 select sum(列名) from 表名;
練習:
1. 統計一個班級數學總成績? —– select sum(math) from exam;
2. 統計一個班級語文、英語、數學各科的總成績 —- select sum(chinese),sum(math),sum(english) from exam;
3. 統計一個班級語文、英語、數學的成績總和 select sum(chinese+math+english) from exam; select sum(chinese)+sum(math)+sum(english) from exam;
4. **劉備語文null ,null進行所有運算 結果都是null
select sum(chinese)+sum(math)+sum(english) from exam; 含有劉備英語和數學成績
select sum(chinese+math+english) from exam; 不含劉備英語和數學成績**
5. **使用ifnull函數處理 null情況
select sum(ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0)) from exam; 含有劉備英語和數學成績**
6. 統計一個班級語文成績平均分 —— select sum(chinese)/count( * ) from exam;
- avg 統計某一列平均值 select avg(列名) from 表名;
練習:
1. 求一個班級數學平均分? —- select avg(math) from exam;
2. 求一個班級總分平均分?—- select avg(ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0)) from exam;
- max 統計一列最大值 min 統計一列最小值
練習:
1. 求班級最高分和最低分(數值範圍在統計中特別有用)select max(chinese+math+english) ,min(ifnull(chinese,0)+ifnull(math,0)+ifnull(english,0)) from exam;
==補充:==
where 和 having 條件語句的區別?
1. where 是在分組前進行條件過濾,having 是在分組後進行條件過濾 2. 使用where地方都可以用 having替換,但是having可以使用分組函數,而where後不可以用分組函數
小結select語句:
**S-F-W-G-H-O 組合 select … from … where … group by… having… order by … ;
順序不能改變**解析順序 : from - where - group by - having - select - order by
多表設計:
多表設計(外鍵約束):
create table emp (
id int primary key auto_increment,
name varchar(20),
job varchar(20),
salary double
);
insert into emp values(null,'小麗','人力資源',4500);
insert into emp values(null,'小張','Java工程師',5000);
insert into emp values(null,'老李','財務經理',8000);
insert into emp values(null,'小劉','項目經理',10000);
create table dept(
id int primary key auto_increment,
name varchar(20)
);
insert into dept values(null,'人力資源部');
insert into dept values(null,'財務部');
insert into dept values(null,'技術研發部');
讓員工表和部門表發生關係,知道員工屬於哪個部門 ,在員工表添加部門id字段
alter table emp add dept_id int ;
update emp set dept_id = 1 where name = '小麗';
update emp set dept_id = 2 where name = '老李';
update emp set dept_id = 3 where name = '小劉';
update emp set dept_id = 3 where name = '小張';
假設公司因爲財政問題,解散技術研發部 delete from dept where name ='技術研發部'; ----- 小張和小劉 失去了組織
emp表 中dept_id字段 引用 dept表 id 字段 ------- 添加外鍵約束 (保證數據有效和完整性)
將emp表中dept_id 設置爲外鍵約束 alter table emp add foreign key(dept_id) references dept(id) ;
無法刪除技術研發部,因爲小劉和小張信息 依賴技術研發部 記錄 !!!!!
多表設計原則(瞭解):
- 多對多關係 : 僱員和項目關係
- 一個僱員可以參與多個項目 , 一個項目可以由多個僱員參與
- 建表原則:必須創建第三張關係表,在關係表中引用兩個實體主鍵 作爲外鍵
- 關係表中每條記錄,代表一個僱員參與了一個項目
- 一對多關係: 用戶和博客關係
- 一個用戶可以發表多篇博客 , 一個博客只能由一個作者
- 建表原則:不需要創建第三方關係表,只需要在多方添加 一方主鍵作爲 外鍵
- 一對一關係 : 這種關係很少見到 負責人和工作室
- 一個負責人 管理一個工作室 , 一個工作室 只有一個負責人
- 建表規則:在任一方添加對方主鍵 作爲外鍵
笛卡爾積的學習:
多表查詢——笛卡爾積
將A表中每條記錄 與 B表中每條記錄進行 匹配 獲得笛卡爾積
select * from emp;
select * from dept;
select * from emp,dept; 顯示結果就是笛卡爾積
笛卡爾積結果 就是 兩個表記錄乘積 例如A 表3條 B表4條 ---- 笛卡爾積 12條
笛卡爾積結果是無效的,必須從笛卡爾積中選取有效的數據結果 !!!
多表查詢 連接查詢 內連接查詢
從A表中選擇一條記錄,去B表中找對應記錄 ----- 內連接
必須A表和B表存在對應記錄纔會顯示
create table A(A_ID int primary key auto_increment,A_NAME varchar(20) not null);
insert into A values(1,'Apple');
insert into A values(2,'Orange');
insert into A values(3,'Peach');
create table B(A_ID int primary key auto_increment,B_PRICE double);
insert into B values(1,2.30);
insert into B values(2,3.50);
insert into B values(4,null);
使用內連接 select * from a,b where a.a_id = b.a_id; 從笛卡爾積中篩選出有效的數據
* 內連接查詢結果條數 一定小於 兩個表記錄較多哪個表 ----- 例如 A表3條 B表5條 ---- 內連接結果條數 <= 5
select * from emp,dept where emp.dept_id = dept.id ; 將emp 表和dept 表進行內連接
在內連接查詢時 添加條件,
查詢人力資源部有哪些 員工 ??
select * from emp,dept where emp.dept_id = dept.id and dept.name ='人力資源部';
查詢工資大於7000員工來自哪個部門?
select * from emp,dept where emp.dept_id = dept.id and emp.salary > 7000;
select * from emp,dept where emp.dept_id = dept.id ; 寫法一
select * from emp inner join dept on emp.dept_id = dept.id ; 寫法二
擴展內容
MySQL 數據庫的備份和恢復
- 備份命令 mysql/bin/mysqldump 將數據庫SQL語句導出
- 語法:mysqldump -u 用戶名 -p 數據庫名 > 磁盤SQL文件路徑
例: 備份day12數據庫 — c:\day10.sql
cmd > mysqldump -u root -p day10 > c:\day10.sql 回車輸入密碼**
- 恢復命令 mysql/bin/mysql 將sql文件導入到數據庫
- 語法: mysql -u 用戶名 -p 數據庫名 < 磁盤SQL文件路徑
注意:導入SQL 必須手動創建數據庫,SQL不會創建數據庫
例: 將c:\day10.sql 導入 day10數據庫
cmd > mysql -u root -p day10 < c:\day10.sql 回車密碼
==補充知識==: 恢復SQL也可以在數據庫內部執行 source c:\day10.sql