數據庫表之間關係
一對一
一對一關係的實現,可以在任意一方添加外鍵指向兩一方的主鍵,讓外鍵唯一UNIQUE
一對多
員工跟部門的關係
在多的一方建立外鍵關聯一的一方的主鍵
多對多
學生跟課程的關係
多對多關係實現需要藉助第三章中間表,中間表至少包含兩個字段,這兩個字段作爲第三張表的外鍵,分別指向兩張表的主鍵
多對多中間表的設計:
Create table stu_course{
stuId int ,—學生id
DATE DATETIME,
courseId int, —課程id
-創建複合主鍵
PRIMARY KEY(stuId,courseId),--聯合主鍵
FOREIGN KEY(stuId) REFERENCES student(sId),
FOREIGN KEY(courseId) REFERENCES course(cId)
}
數據庫設計的範式
概念:設計數據庫時,需要遵循的一些規則。
第一範式(1NF):每一列都是不可分割的原子數據項
第二範式(2NF):在1NF的基礎上,非碼屬性必須完全依賴於碼(在1NF基礎上消除非主屬性對主碼的部分函數依賴)
概念:
1.函數依賴:A-->B,如果通過A屬性的值(屬性組)的值,可以確定唯一B屬性的值,則稱B依賴於A.
例如:學號-->姓名。 (學號,課程名稱)-->分數
2.完全依賴函數:A-->B,如果A是一個屬性組,則B屬性值的確定需要依賴A屬性組中所有的屬性值。
例如:(學號,課程名稱)-->分數
3.部分依賴函數:A-->B,如果A是一個屬性組,則B屬性值的確定只需要依賴A屬性組中某一些屬性值即可。
例如:(學號,課程名稱)-->姓名
4.傳遞函數依賴:A-->B,B-->C,如果通過A屬性的值(屬性組)的值,可以確定唯一B屬性的值,再通過B屬性的值(屬性組)的。 值,可以確定唯一C屬性的值,則稱C傳遞函數依賴於A.
例如:學號-->系名,系名-->系主任
5.碼:如果在一張表中,一個屬性或屬性組,被其他所有屬性所完全依賴,則稱這個屬性(屬性組)爲該表的碼
例如:該表中碼爲(學號,課程名稱)
主屬性:碼屬性組中的所有屬性
非主屬性:除過碼屬性組的屬性
第三範式(3NF):在2NF的基礎上,任何非主屬性不依賴於其他非主屬性(在2NF基礎上消除傳遞依賴)
數據庫的備份和還原
1.命令行的方式:
語法:
備份:mysqldump -u用戶名 -p密碼 數據庫名稱 > 保存的路徑
還原:
1.登陸數據庫
2.創建數據庫
3.使用數據庫(use 數據庫名稱)
4.執行sql (source sql的保存的路徑)
多表查詢
笛卡爾積:
有兩個集合A,B,取這兩個集合的所有組成情況
要完成多表查詢,需要消除無用的數據
多表查詢的分類:
1.內連接查詢:
1>隱式內連接:
語法: select 字段列表 from 表名 表名2 where 條件
select t1.name,t1.gender,t2.name from emp t1,dept t2 where t1.dept_id=t2.id
2>顯式內連接:
語法: select 字段列表 from 表名 [inner] join 表名2 on 條件. (中括號表示可以省略)
select t1.name,t1.gender,t2.name from emp t1 inner join dept t2 on t1.dept_id=t2.id
3>內連接查詢:
1)從哪些表中查詢數據
2)條件是什麼
3)查詢哪些字段
2.外連接查詢:
1>左外連接:
語法:select 字段列表 from 表1 left [outer] join 表2 on 條件
查詢的是左表所有數據以及其交集部分
2>右外連接:返回所有右表數據,即使沒有與左表匹配的信息
語法:select 字段列表 from 表1 right [outer] join 表2 on 條件
查詢的是右表所有數據以及其交集部分
3.子查詢:
概念:查詢中嵌套查詢,稱嵌套查詢的語句爲子查詢
例子:
--查詢工資最高的員工信息
--1 查詢最高的工資是多少 9000
select max(salary) from emp;
--2 查詢員工信息,工資等於 9000
select * from emp where emp.salary=9000;
--一條sql就完成這個操作
select * from emp where emp.salary=(select max(salary) from emp);
子查詢的不同情況:
1.子查詢的結果是單行單列
子查詢可以作爲條件,使用運算符去判斷。運算符:<,>,=>,<= 等
例子:
--查詢員工工資小於平均工資的人
select * from emp where emp.salary<(select avg(salary) from emp);
2.子查詢的結果是多行單列的
例子:
--查詢財務部和市場部所有的員工信息
--1 查詢財務部和市場部的部門id
select * from dept where name=“財務部” OR name=“市場部”;
--2根據部門id查詢員工
select * from emp where dept_id=3 OR dept_id=2;
--3組合查詢
select * from emp where dept_id IN(select * from dept where name=“財務部” OR name=“市場部”;)
3.子查詢的結果是多行多列的
--查詢2011-11-11之後入職的員工信息和部門信息
select * from dept t1 ,(select * from emp where emp.join_data > ‘2011-11-11’) t2 where t1.id=t2.dept_id
select * from emp t1,dept t2 where t1.dept_id=t2.id AND emp.join_data > ‘2011-11-11’;
事務:
1.事務的基本介紹
1.概念:如果一個包含多個步驟的業務操作,被事務管理,那麼這些操作要麼全部成功,要麼全部失敗
2.操作:
1.開啓事務:start transaction
2.回滾:rollback
3.提交: commit
4. mySql數據庫中事務默認自動提交
一條DML語句自動提交一次事務
自動提交 :mysql自動提交
手動提交:需要先開啓事務,在提交;oracle默認手動提交
查看提交方式:select @@autocommit; 1代表自動提交,0代表手動提交
修改提交方式:set @@autocommit =0;改爲手動提交
2.事務的四大特徵
1.原子性:是不可再分割的最小操作單位,要麼同時成功,要麼同時失敗
2.持久性:當事務提交或會滾後,數據庫會持久化的保存數據
3.隔離性:多個事務之間。相互獨立。
4.一致性:事務操作前後,數據總量不變。
3.事務的隔離級別(瞭解)
概念:多個事務之間是隔離的,相互獨立的,但是如果多個事務操作同一批數據,則會引發一些問題,設置不同的隔離級別就可以解決這些問題。
存在問題:
1.髒讀:一個事務,讀取到另一個事務中沒有提交的數據
2.不可重複讀:在同一個事務中,兩次讀取到的數據不一樣。
3.幻讀:一個事務操作(DML)數據表中所有記錄,另一個事務添加了一條數據,則第一個事務查詢不到自己的修改。
隔離級別:
1.read uncommitted:讀未提交:
同時開啓兩個事務,A事務執行操作未提交,B事務可以讀到一執行操作的結果
產生的問題:髒讀,不可重複讀,幻讀
2.read committed:讀已提交(Oracle)
產生的問題:不可重複讀,幻讀
3.repeated read :可重複讀(MySql默認)
產生的問題:幻讀
4.serializable :串行化
可以解決所有的問題
注意:隔離級別從小到大安全性越來越高,但是效率越來越低
數據庫查詢隔離級別:
select @@tx_islation
數據庫設置隔離級別:
set global transaction isolation level 級別字符串;例如:級別字符串爲read committed
演示:
set global transaction isolation level read uncommitted;
start transaction;
update account set balance =balance-500 where id=1;
update account set balance =balance+500 where id=2;
read uncommitted情況下:A執行上述操作未提交,則B事務可以查看到已經發生的轉賬情況賬戶1,賬戶2的金額已經變化。
read committed情況下:A執行上述操作未提交,則B事務可以查看到已經發生的轉賬情況賬戶1,賬戶2的金額未發生變化。
repeated read情況下:A執行上述操作,B事務在不提交的情況下讀取多次讀到的數據都是同一個結果,不會重複去讀數據,只有提交結束當前的事務,重新查詢纔可查詢到變化的數據。
serializable情況下:A執行上述操作,B事務執行查詢,不會出現數據表,只有當A提交數據或者回滾之後,B事務會同時顯示出查詢結果。
DCL:
SQL分類:
1.DDL:操作數據庫和表
2.DML:增刪改表中的數據
3.DQL:查詢表中數據
4.DCL:管理用戶,授權 :數據庫管理員(DBA)來操作
DCL:管理用戶,授權
1.管理用戶
1.添加用戶
語法: CREATE USER ‘用戶名’@‘主機名’ IDENTIFIED BY ‘密碼’;
例如:
CREATE USER ‘zhangsan’@‘localhost’ IDENTIFIED BY ‘123’;//在當前本機可以登錄
CREATE USER ‘lisi’@‘%’ IDENTIFIED BY ‘123’;//在任意主機可以登錄
2.刪除用戶
語法: DROP USER ‘用戶名’@‘主機名’;
3.修改用戶
語法: UPDATE USER SET PASSWORD =PASSWORD(‘新密碼’) WHERE USER=‘用戶名’;//方法1
SET PASSWORD FOR ‘用戶名’@‘主機名’ =PASSWORD(‘新密碼’);//DCL特有方式方法2
mysql中忘記root用戶的密碼?
1.cmd. —>net stop mysql //停止mysql服務 必須以管理員身份運行改cmd
2.使用無驗證方式啓動mysql服務:mysqld --skip grant -tables
3.再打開一個新的cmd窗口(上一個cmd窗口不關閉),直接按Enter鍵則可直接進入MySql,
4.user mysql;
5.update user set password=password(‘新密碼’) where user=‘root’;
6.關閉兩個窗口
7.打開任務管理器,手動結束mysql.exe的進程
8.打開新的cmd任務窗口手動啓動mysql:net start mysql
9.使用新密碼登陸
4.查詢用戶
1>切換到mysql數據庫
USE mysql
2>查詢user表
SELECT * from user;
通配符:%表示可以在任意主機使用用戶登錄數據庫
2.權限管理:
1.查詢權限
語法:SHOW GRANTS FOR ‘用戶名’@‘主機名’;
例如:SHOW GRANTS FOR ‘zhangsan’@‘%’;
2.授予權限
語法:grant 權限列表 on 數據庫名.表名 TO ‘用戶名’@‘主機名’;
例如:
//lisi可對數據庫db3的account表可查詢,刪除
grant SELECT,DELETE on db3.account TO ‘lisi’@‘%’;
//給lisi用戶授予所有權限,在任意數據庫任意表上
grant ALL on *.* TO ‘lisi’@‘%’;
3.撤銷權限
語法:revoke 權限列表 on 數據庫名.表名 FROM ‘用戶名’@‘主機名’;
例如:
//lisi可對數據庫db3的account表可查詢,刪除
revoke SELECT,DELETE on db3.account FROM ‘lisi’@‘%’;
//給lisi用戶授予所有權限,在任意數據庫任意表上
revoke ALL on *.* FROM ‘lisi’@‘%’;