以下內容的一些總結
-
create,alter,drop,show, 用於 表/數據庫
-
DDL CRUD后都要加database/databases/table/tables
-
select database(); -DOS窗口中查詢當前正在使用的數據庫,使用用use。
-
表中數據的增加用insert into,修改update,刪除delete這兩個一般加上限定條件WHERE
-
DQL中NULL不能用“==” 等運算符判讀,需要使用IS/IS NOT
-
where與hanving限定的區別,在分組查詢中,where限定是在分組之前,不滿足條件不參與分組,having限定是在分組之后,不滿足條件不會被查詢出來。
-
where 后不能進行聚合函數的判斷,having可以
-
修改表,進行數據項約束:
alter table 表名 modify 列名 數據類型 NOT NULL;
-
mysql中,唯一約束限定的列的值可以有多個null
-
刪除特例
刪除主鍵約束:ALTER TABLE stu DROP PRIMARY KEY;
刪除唯一約束:ALTER TABLE stu DROP INDEX 列名; -
select now(); 查看mysql系統時間。和當前時間做對比
set global time_zone = '+8:00';設置時區更改為東八區
flush privileges; 刷新權限
MySQL數據庫軟件卸載
-
卸載
- 去mysql的安裝目錄找到my.ini文件
- 復制 datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
- 卸載MySQL
- 刪除C:/ProgramData目錄下的MySQL文件夾。
- 去mysql的安裝目錄找到my.ini文件
-
配置
-
MySQL服務啟動
- 手動。
- cmd--> services.msc 打開服務的窗口
- 使用管理員打開cmd
- net start mysql : 啟動mysql的服務
- net stop mysql:關閉mysql服務
-
MySQL登錄
- mysql -uroot -p密碼
- mysql -hip -uroot -p連接目標的密碼
- mysql --host=ip --user=root --password=連接目標的密碼
-
MySQL退出
- exit
- quit
-
MySQL目錄結構
- MySQL安裝目錄:basedir="D:/develop/MySQL/"
- 配置文件 my.ini
- MySQL數據目錄:datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data/"
- 幾個概念
- 數據庫:文件夾
- 表:文件
- 數據:數據
- 幾個概念
- MySQL安裝目錄:basedir="D:/develop/MySQL/"
-
- 客戶端圖形化工具:SQLYog
SQL
-
什么是SQL?
Structured Query Language:結構化查詢語言
其實就是定義了操作所有關系型數據庫的規則。每一種數據庫操作的方式存在不一樣的地方,稱為“方言”。 -
SQL通用語法
- SQL 語句可以單行或多行書寫,以分號結尾。
- 可使用空格和縮進來增強語句的可讀性。
- MySQL 數據庫的 SQL 語句不區分大小寫,關鍵字建議使用大寫。
- 3 種注釋
- 單行注釋: -- 注釋內容 或 # 注釋內容(mysql 特有)
- 多行注釋: /* 注釋 */
-
SQL分類
- DDL(Data Definition Language)數據定義語言
用來定義數據庫對象:數據庫,表,列等。關鍵字:create, drop,alter 等 - DML(Data Manipulation Language)數據操作語言
用來對數據庫中表的數據進行增刪改。關鍵字:insert, delete, update 等 - DQL(Data Query Language)數據查詢語言
用來查詢數據庫中表的記錄(數據)。關鍵字:select, where 等 - DCL(Data Control Language)數據控制語言(了解)
用來定義數據庫的訪問權限和安全級別,及創建用戶。關鍵字:GRANT, REVOKE 等
- DDL(Data Definition Language)數據定義語言
DDL:操作數據庫
- 操作數據庫:CRUD
C(Create):創建
- 創建數據庫:
- create database 數據庫名稱;
- 創建數據庫,判斷不存在,再創建:
- create database if not exists 數據庫名稱;
- 創建數據庫,並指定字符集
- create database 數據庫名稱 character set 字符集名;
- 練習: 創建db4數據庫,判斷是否存在,並制定字符集為gbk
* create database if not exists db4 character set gbk;
R(Retrieve):查詢
- 查詢所有數據庫的名稱:
- show databases;
- 查詢某個數據庫的字符集:查詢某個數據庫的創建語句
- show create database 數據庫名稱;
U(Update):修改
- 修改數據庫的字符集
- alter database 數據庫名稱 character set 字符集名稱;
D(Delete):刪除
- 刪除數據庫
- drop database 數據庫名稱;
- 判斷數據庫存在,存在再刪除
- drop database if exists 數據庫名稱;
- 使用數據庫
- 查詢當前正在使用的數據庫名稱
- select database();
- 使用數據庫
- use 數據庫名稱;
- 查詢當前正在使用的數據庫名稱
DDL操作表
C(Create):創建
- 語法:
create table 表名(
列名1 數據類型1,
列名2 數據類型2,
....
列名n 數據類型n
);- 注意:最后一列,不需要加逗號(,)
- 數據庫類型:
- int:整數類型
- age int,
- double:小數類型
- score double(5,2)
- date:日期,只包含年月日,yyyy-MM-dd
- datetime:日期,包含年月日時分秒 yyyy-MM-dd HH:mm:ss
- timestamp:時間錯類型 包含年月日時分秒 yyyy-MM-dd HH:mm:ss
- 如果將來不給這個字段賦值,或賦值為null,則默認使用當前的系統時間,來自動賦
- varchar:字符串
- name varchar(20):姓名最大20個字符
- zhangsan 8個字符 張三 2個字符
- int:整數類型
- 創建表
create table student(
id int,
name varchar(32),
age int ,
score double(4,1),
birthday date,
insert_time timestamp
);
- 復制表:
- create table 表名 like 被復制的表名;
R(Retrieve):查詢
- 查詢某個數據庫中所有的表名稱
- show tables;
- 查詢表的結構,字段名,字段屬性等
- desc 表名;
U(Update):修改
- 修改表名
alter table 表名 rename to 新的表名; - 修改表的字符集
alter table 表名 character set 字符集名稱; - 添加一列
alter table 表名 add 列名 數據類型; - 修改列名稱 類型
alter table 表名 change 列名 新列重命名 新數據類型;
alter table 表名 modify 列名 新數據類型; - 刪除列
alter table 表名 drop 列名; - 修改表的字段值為主鍵
ALTER TABLE student ADD PRIMARY KEY(id);
D(Delete):刪除
- drop table 表名;
- drop table if exists 表名 ;
表的約束
-
理解:對數據進行限定,保證數據的正確性,有效性、完整性
-
分類:
- 主鍵約束:primary key
- 非空約束:not null
- 唯一約束:unique
- 外鍵約束:foreign key
非空約束:not null
- 值不能為null
- 創建表時添加約束
CREATE TABLE stu(
id INT,
NAME VARCHAR(20) NOT NULL -- name為非空
);
- 創建表完后,添加非空約束
ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL; - 刪除name的非空約束
ALTER TABLE stu MODIFY NAME VARCHAR(20);
唯一約束:unique
- 值不能重復
- 創建表時,添加唯一約束
CREATE TABLE stu(
id INT,
phone_number VARCHAR(20) UNIQUE -- 添加了唯一約束
);
-- * 注意mysql中,唯一約束限定的列的值可以有多個null
- 刪除唯一約束
ALTER TABLE stu DROP INDEX phone_number; - 在創建表后,添加唯一約束
ALTER TABLE stu MODIFY phone_number VARCHAR(20) UNIQUE;
主鍵約束:primary key。
- 注意:
- 含義:非空且唯一
- 一張表只能有一個字段為主鍵
- 主鍵就是表中記錄的唯一標識
- 在創建表時,添加主鍵約束
create table stu(
id int primary key,-- 給id添加主鍵約束
name varchar(20)
);
- 刪除主鍵
-- 錯誤 alter table stu modify id int ;
ALTER TABLE stu DROP PRIMARY KEY; - 創建完表后,添加主鍵
ALTER TABLE stu MODIFY id INT PRIMARY KEY; - 自動增長:
- 概念:如果某一列是數值類型的,使用 auto_increment 可以來完成值得自動增長
- 在創建表時,添加主鍵約束,並且完成主鍵自增長
create table stu(
id int primary key auto_increment,-- 給id添加主鍵約束
name varchar(20)
); - 刪除自動增長
ALTER TABLE stu MODIFY id INT; - 添加自動增長
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
注意:自動增長也可以自定義賦值,然后自動增長從自定義賦值開始
外鍵約束:foreign key
- 讓表於表產生關系,從而保證數據的正確性。
- 在創建表時,可以添加外鍵
- 語法:
create table 表名( .... 外鍵列 constraint 外鍵名稱 foreign key (外鍵列名稱) references 主表名稱(主表列名稱) );
- 語法:
- 刪除外鍵
ALTER TABLE 表名 DROP FOREIGN KEY 外鍵名稱; - 創建表之后,添加外鍵
ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵字段名稱) REFERENCES 主表名稱(主表列名稱); - 級聯操作
- 添加級聯操作 - 修改外鍵所在表的主鍵會同步更新
語法:ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱
FOREIGN KEY (外鍵字段名稱) REFERENCES 主表名稱(主表列名稱) ON UPDATE CASCADE ;
--刪除外鍵所在表的一條記錄,當前表相應的外鍵所在記錄同步刪除(危險)
語法:ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱
FOREIGN KEY (外鍵字段名稱) REFERENCES 主表名稱(主表列名稱) ON UPDATE CASCADE ON DELETE CASCADE; - 分類:
- 級聯更新:ON UPDATE CASCADE
- 級聯刪除:ON DELETE CASCADE
- 級聯更新:ON UPDATE CASCADE
- 添加級聯操作 - 修改外鍵所在表的主鍵會同步更新
DML:增刪改表中數據
添加數據:
- 語法:
- insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n),(...);
- 注意:
- 列名和值要一一對應。
- 如果表名后,不定義列名,則默認給所有列添加值
insert into 表名 values(值1,值2,...值n); - 除了數字類型,其他類型需要使用引號(單雙都可以)引起來
刪除數據:
- 語法:
- delete from 表名 [where 條件]
- 注意:
- 如果不加條件,則刪除表中所有記錄。
- 如果要刪除所有記錄
- delete from 表名; -- 不推薦使用。有多少條記錄就會執行多少次刪除操作
- TRUNCATE TABLE 表名; -- 推薦使用,效率更高 先刪除表,然后再創建一張一樣的表。
修改數據:
- 語法:
- update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 條件];
- 注意:
- 如果不加任何條件,則會將表中所有記錄全部修改。
DQL:查詢表中的記錄
-
select * from 表名; -查詢表中所有數據
-
語法:
select
字段列表,有幾個顯示幾列
from
表名列表
where
條件列表
group by
分組字段
having
分組之后的條件
order by
排序
limit
分頁限定
基礎查詢
- 多個字段的查詢
select 字段名1,字段名2... from 表名;- 注意:
- 如果查詢所有字段,則可以使用*來替代字段列表。
- 注意:
- 去除重復(若有多個字段,保證多個字段的結果集完全一樣):
- select distinct 字段 from 表名;
- 計算列
- 一般可以使用四則運算計算一些列的值。(一般只會進行數值型的計算)
- ifnull(表達式1,表達式2):null參與的運算,計算結果都為null
- 表達式1:哪個字段需要判斷是否為null
- 如果該字段為null后的替換值。
SELECT NAME,math,English,math+IFNULL(English,0) FROM student;
- 起別名:
- as:as也可以省略
條件查詢
- where子句后跟條件
- 運算符
- " > " 、< 、<= 、>= 、= 、<>
- BETWEEN...AND 與 &&
- IN( 集合) 與 OR
- LIKE:模糊查詢
- 占位符:
- _:單個任意字符
- %:多個任意字符
- 占位符:
- IS NULL
- and 或 &&
- or 或 ||
- not 或 !
-- 查詢年齡大於20歲 SELECT * FROM student WHERE age > 20; -- 查詢年齡等於20歲 SELECT * FROM student WHERE age = 20; -- 查詢年齡不等於20歲 SELECT * FROM student WHERE age != 20; SELECT * FROM student WHERE age <> 20; -- 查詢年齡大於等於20 小於等於30 SELECT * FROM student WHERE age >= 20 && age <=30; SELECT * FROM student WHERE age >= 20 AND age <=30; SELECT * FROM student WHERE age BETWEEN 20 AND 30; -- 查詢年齡22歲,18歲,25歲的信息 SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25 SELECT * FROM student WHERE age IN (22,18,25); -- 查詢英語成績為null SELECT * FROM student WHERE english = NULL; -- 不對的。null值不能使用 = (!=) 判斷 SELECT * FROM student WHERE english IS NULL; -- 查詢英語成績不為null SELECT * FROM student WHERE english IS NOT NULL; -- 查詢姓馬的有哪些? like SELECT * FROM student WHERE NAME LIKE '馬%'; -- 查詢姓名第二個字是化的人 SELECT * FROM student WHERE NAME LIKE "_化%"; -- 查詢姓名是3個字的人 SELECT * FROM student WHERE NAME LIKE '___'; -- 查詢姓名中包含德的人 SELECT * FROM student WHERE NAME LIKE '%德%';
排序查詢
- 語法: order by 字句
- 格式:order by 排序字段1,字段2,... 排序方式1,排序2...
- 默認升序:ASC
SELECT NAME FROM student
ORDER BY age ASC;
- 降序 - DESC
- 練習,先按數學成績排,若成績相同,再按英語成績
SELECT NAME FROM student
ORDER BY math ASC,English ASC;
聚合函數
- 理解:將一列數據作為一個整體,進行縱向(Y軸)的計算。
- MySql中的聚合函數:
- count:計算某字段數據個數,不包括NULL,實際為表中記錄數
- 格式:Count(字段名)
SELECT COUNT(NAME) AS 人數
FROM student;- 加上NULL的個數:1. 用非空字段主鍵 2.count(*) 3.如下
SELECT COUNT(IFNULL(NAME,0) AS 人數
FROM student; - max:計算最大
- min:計算最小
- avg:計算平均
- count:計算某字段數據個數,不包括NULL,實際為表中記錄數
分組查詢
- 理解:把具有相同特征(字段)的一行(記錄)當成整體來查詢
- 語法:group by
- 注意;由於分組,select 后應為聚合函數或分組字段(by后的字段)否則沒有任何意義。
- 練習:按照性別分組,分別查詢男和女的人數,聚合函數的字段使用主確保非NULL
SELECT sex,COUNT(學號) AS 人數
FROM student
GROUP BY sex;
- 練習:選擇滿足條件的記錄參與分組,由字段進行篩選,如下查詢姓王男的人數和女的人數
SELECT sex,COUNT(學號) AS 人數
FROM student
WHERE name = "王"
GROUP BY sex;
- HAVING練習:分別查詢男和女分數在平均分以上的人數,且只顯示人數於2的那一類
SELECT sex,COUNT(id) AS 人數
FROM student
WHERE score >(
SELECT AVG(score)
FROM student
)
GROUP BY sex HAVING COUNT(id) > 2;
分頁查詢
-
語法:limit 開始的索引,每頁查詢的條數
-
練習:顯示第一頁,每頁顯示三條
SELECT * FROM student LIMIT 0,3;
索引位置=(當前頁數碼-1)*顯示條數
顯示第1,2,3條記錄,3為顯示條數 -
分頁操作在不同語言中操作方式不一樣
多表查詢
- select * from 表1,表2; -查詢出來的為笛卡爾積,有冗余
內連接查詢
- 隱式內連接:使用where條件消除無用數據
- 例子:
-- 查詢所有員工信息和對應的部門信息 SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;
-- 查詢員工表的名稱,性別。部門表的名稱 SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`; -- 用別名 SELECT t1.name, -- 員工表的姓名 t1.gender,-- 員工表的性別 t2.name -- 部門表的名稱 FROM emp t1, -- 別名t1 dept t2t1 -- 別名t2 WHERE t1.`dept_id` = t2.`id`;
- 顯式內連接:
- 語法: select 字段列表 from 表名1 [inner] join 表名2 on 條件
- 例如:
SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`; SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`;
外鏈接查詢:
- 左外連接:
- 語法:select 字段列表 from 表1 left [outer] join 表2 on 條件;
- 查詢的是左表所有數據以及其交集部分(On后邊的條件,含null,隱式內連接查詢不顯示鏈接為null的數據)。
- 例子:
-- 查詢所有員工信息,如果員工有部門,則查詢部門名稱,沒有部門,則不顯示部門名稱 SELECT t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`; -- 其中t1為左表,t2為右表
- 右外連接:
- 語法:select 字段列表 from 表1 right [outer] join 表2 on 條件;
- 查詢的是右表所有數據以及其交集部分。
- 例子:
SELECT * FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;
子查詢:
- 概念:查詢中嵌套查詢,稱嵌套查詢為子查詢。
-- 查詢工資最高的員工信息
-- 1 查詢最高的工資是多少 9000
SELECT MAX(salary) FROM emp;
-- 2 查詢員工信息,並且工資等於9000的
SELECT * FROM emp WHERE emp.`salary` = 9000;
-- 一條sql就完成這個操作。子查詢
SELECT * FROM emp WHERE emp.`salary` = (SELECT MA (salary) FROM emp);
- 子查詢不同情況
- 子查詢的結果是單行單列的:
- 子查詢可以作為條件,使用運算符去判斷。 運算符: > >= < <= =
-- 查詢員工工資小於平均工資的人 SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
- 子查詢的結果是多行單列的:
- 子查詢可以作為條件,使用運算符in來判斷
-- 查詢'財務部'和'市場部'所有的員工信息 SELECT id FROM dept WHERE NAME = '財務部' OR NAME = '市場部'; SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2; -- 子查詢 SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '財務部' OR NAME = '市場部');
- 子查詢的結果是多行多列的:
- 子查詢可以作為一張虛擬表參與查詢
-- 查詢員工入職日期是2011-11-11日之后的員工信息和部門信息 -- 子查詢 SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2 WHERE t1.id = t2.dept_id; -- 普通內連接 SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` > '2011-11-11'
- 子查詢的結果是單行單列的:
DCL:用戶權限管理
- DCL:管理用戶,授權,一般由DBA來完成
管理用戶
-
添加用戶:
- 語法:CREATE USER '用戶名'@'主機名(若為%,網絡上的任意主機都可以訪問)' IDENTIFIED BY '密碼';
-
刪除用戶:
- 語法:DROP USER '用戶名'@'主機名';
-
修改用戶密碼:
-- 第一種 UPDATE USER SET PASSWORD = PASSWORD('新密碼') WHERE USER = '用戶名'; UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi'; -- 第二種 SET PASSWORD FOR '用戶名'@'主機名' = PASSWORD('新密碼'); SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');
- mysql中忘記了root用戶的密碼:
- cmd -- > net stop mysql 停止mysql服務
- 需要以管理員身份運行該cmd
- 使用無驗證方式啟動mysql服務: mysqld --skip-grant-tables
- 打開新的cmd窗口,直接輸入mysql命令,敲回車。就可以登錄成功
- use mysql;
- update user set password = password('你的新密碼') where user = 'root';
- 關閉兩個窗口
- 打開任務管理器,手動結束mysqld.exe 的進程
- 啟動mysql服務:net start mysql
- 使用新密碼登錄。
- cmd -- > net stop mysql 停止mysql服務
- mysql中忘記了root用戶的密碼:
-
查詢用戶:
-- 1. 切換到mysql數據庫
USE myql;
-- 2. 查詢user表
SELECT * FROM USER;
- 通配符: % 表示可以在任意主機使用用戶登錄數據庫
權限管理:
- 查詢權限:
-- 查詢權限
SHOW GRANTS FOR '用戶名'@'主機名';
SHOW GRANTS FOR 'lisi'@'%';
- 授予權限:
-- 授予權限,權限列表有SELECT,DELETE,UPDATE
grant 權限列表 on 數據庫名.表名 to '用戶名'@'主機名';
-- 若授予所有權限,則為ALL
-- 給張三用戶授予所有權限,在任意數據庫任意表(*.*)上
GRANT ALL ON *.* TO 'zhangsan'@'localhost';
- 撤銷權限:
-- 撤銷權限:
revoke 權限列表 on 數據庫名.表名 from '用戶名'@'主機名';
-- 撤銷修改權限
REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';
事務
事務的基本介紹
-
概念:
- 如果一個包含多個步驟的業務操作,被事務管理,那么這些操作要么同時成功,要么同時失敗。
-
操作:
- 開啟事務: start transaction;
- 回滾:rollback;
- 提交:commit;
-
例子:資金轉賬
-- 創建一張賬戶表
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
-- 添加數據
INSERT INTO account (NAME, balance) VALUES ('zhangsan', 1000), ('lisi', 1000);
-- 張三給李四轉賬 500 元
-- 0. 開啟事務
START TRANSACTION;
-- 1. 張三賬戶 -500
UPDATE account SET balance = balance - 500 WHERE NAME = 'zhangsan';
-- 2. 李四賬戶 +500
-- 若在這出錯了...會回滾
UPDATE account SET balance = balance + 500 WHERE NAME = 'lisi';
-- 發現執行沒有問題,提交事務,若沒有提交事務會自動回滾
COMMIT;
-- 發現出問題了,回滾事務
ROLLBACK;
MySQL數據庫中事務默認自動提交
- 事務提交的兩種方式:
- 自動提交:
- mysql就是自動提交的,不開啟事務自動提交
- 一條DML(增刪改)語句會自動提交一次事務。
- 手動提交:
- 需要先開啟事務,再提交(commit)
- Oracle 數據庫默認是手動提交事務
- 自動提交:
- 修改事務的默認提交方式:
- 查看事務的默認提交方式:SELECT @@autocommit; -- 1 代表自動提交 0 代表手動提交
- 修改默認提交方式: set @@autocommit = 0;
事務的四大特征:
- 原子性:是不可分割的最小操作單位,要么同時成功,要么同時失敗。
- 持久性:當事務提交或回滾后,數據庫會持久化的保存數據。
- 隔離性:多個事務之間。相互獨立。
- 一致性:事務操作前后,數據總量(例如總金額)不變
- 事務的隔離級別
-
概念:多個事務之間隔離的,相互獨立的。但是如果多個事務操作同一批數據,則會引發一些問題,設置不同的隔離級別就可以解決這些問題。
-
存在問題:
- 臟讀:一個事務,讀取到另一個事務中沒有提交的數據
- 不可重復讀(虛讀):在同一個事務中,兩次讀取到的數據不一樣。
- 幻讀:一個事務操作(DML)數據表中所有記錄,另一個事務添加了一條數據,則第一個事務查詢不到自己的修改。
-
隔離級別:
- read uncommitted:讀未提交
- 產生的問題:臟讀、不可重復讀、幻讀
- read committed:讀已提交 (Oracle)
- 產生的問題:不可重復讀、幻讀
- repeatable read:可重復讀 (MySQL默認)
- 產生的問題:幻讀
- serializable:串行化(鎖表,另一個事務查詢表的時候會等待,只有正在使用表的事務提交以后,另一個事務的查詢才會被執行)
- 可以解決所有的問題
- 注意:隔離級別從小到大安全性越來越高,但是效率越來越低
- 數據庫查詢隔離級別:
- select @@tx_isolation;
- 數據庫設置隔離級別:
- set global transaction isolation level 級別字符串;
- read uncommitted:讀未提交
-
演示:
-- 設置隔離級別 set global transaction isolation level read uncommitted; -- 打開兩個窗口開啟事務,第一個窗口update修改數據,另一個窗口查詢讀到未提交(commit)的數據(數據改變),出現臟讀 -- 然后再第一個事務rollback(轉賬撤銷),另一個窗口再查詢發現數據還原,即不可重復度問題 -- 解決臟讀方案: set global transaction isolation level read committed; -- 第一個窗口修改了數據,第二個窗口查詢發現數據沒有改變 -- 此時第一個窗口commit,第二個窗口查詢發現數據改變,同一個事務查詢的數據不一樣出現不可重復讀問題 -- 解決臟讀和不可重復讀問題 set global transaction isolation level repeatable read; -- 第一個窗口的事務提交改變,不影響第二個窗口事務的數據查詢,只有在第二個窗口也提交事務后,方可正確查詢數據 -- 開啟事務 start transaction; -- 轉賬操作 update account set balance = balance - 500 where id = 1; update account set balance = balance + 500 where id = 2;
-
數據庫的設計
多表之間的關系
-
分類:
- 一對一(了解):
- 如:人和身份證
- 分析:一個人只有一個身份證,一個身份證只能對應一個人
- 一對多(多對一):
- 如:部門和員工
- 分析:一個部門有多個員工,一個員工只能對應一個部門
- 多對多:
- 如:學生和課程
- 分析:一個學生可以選擇很多門課程,一個課程也可以被很多學生選擇
- 一對一(了解):
-
實現關系:
- 一對多(多對一):
- 如:部門和員工
- 實現方式:在多的一方建立外鍵,指向一的一方的主鍵。
- 多對多:
- 如:學生和課程
- 實現方式:多對多關系實現需要借助第三張中間表。表至少包含兩個字段,這兩個字段作為第三張表的外鍵別指向兩張表的主鍵
- 一對一(很少用):
- 如:人和身份證
- 實現方式:一對一關系實現,可以在任意一方添加外鍵指向另一方的主鍵,外鍵需要約束為UNIQUE
- 一對多(多對一):
-
案例
-- 創建旅游線路分類表 tab_category
-- cid 旅游線路分類主鍵,自動增長
-- cname 旅游線路分類名稱非空,唯一,字符串 100
CREATE TABLE tab_category (
cid INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(100) NOT NULL UNIQUE
);
-- 創建旅游線路表 tab_route
/*
rid 旅游線路主鍵,自動增長
rname 旅游線路名稱非空,唯一,字符串 100
price 價格
rdate 上架時間,日期類型
cid 外鍵,所屬分類
*/
CREATE TABLE tab_route(
rid INT PRIMARY KEY AUTO_INCREMENT,
rname VARCHAR(100) NOT NULL UNIQUE,
price DOUBLE,
rdate DATE,
cid INT,
FOREIGN KEY (cid) REFERENCES tab_category(cid)
);
/*創建用戶表 tab_user
uid 用戶主鍵,自增長
username 用戶名長度 100,唯一,非空
password 密碼長度 30,非空
name 真實姓名長度 100
birthday 生日
sex 性別,定長字符串 1
telephone 手機號,字符串 11
email 郵箱,字符串長度 100
*/
CREATE TABLE tab_user (
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) UNIQUE NOT NULL,
PASSWORD VARCHAR(30) NOT NULL,
NAME VARCHAR(100),
birthday DATE,
sex CHAR(1) DEFAULT '男',
telephone VARCHAR(11),
email VARCHAR(100)
);
/*
創建收藏表 tab_favorite
rid 旅游線路 id,外鍵
date 收藏時間
uid 用戶 id,外鍵
rid 和 uid 不能重復,設置復合主鍵,同一個用戶不能收藏 個線路兩次
*/
CREATE TABLE tab_favorite (
rid INT, -- 線路id
DATE DATETIME,
uid INT, -- 用戶id
-- 創建復合主鍵
PRIMARY KEY(rid,uid), -- 聯合主鍵
FOREIGN KEY (rid) REFERENCES tab_route(rid),
FOREIGN KEY(uid) REFERENCES tab_user(uid)
);
數據庫設計的范式
概念:
- 設計數據庫時,需要遵循的一些規范。要遵循后邊的范式求,必須先遵循前邊的所有范式要求。
- 設計關系數據庫時,遵從不同的規范要求,設計出合理的關系型數據庫,些不同的規范要求被稱為不同的范式,各種范式呈遞次規范,越高的范式據庫冗余越小。
- 目前關系數據庫有六種范式:第一范式(1NF)、第二范式(2NF)、第三式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF又稱完美范式)。
分類:
-
第一范式(1NF):每一列都是不可分割的原子數據項
-
第二范式(2NF):在1NF的基礎上,非碼屬性必須完全依賴於碼(1NF基礎上消除非主屬性對主碼的部分函數依賴)
- 幾個概念:
- 函數依賴:A-->B,如果通過A屬性(屬性組)的值,可以確定唯一B屬性的值。則稱B依賴於A
例如:學號-->姓名。 (學號,課程名稱) --> 分數 - 完全函數依賴:A-->B, 如果A是一個屬性組,則B屬性值得確定需要依賴於A屬性組中“所有”的屬性值。
例如:(學號,課程名稱) --> 分數 - 部分函數依賴:A-->B, 如果A是一個屬性組,則B屬性值得確定只需要依賴於A屬性組中“某一些值”即可。
例如:(學號,課程名稱) -- > 姓名
學號就可以決定姓名 - 傳遞函數依賴:A-->B, B -- >C . 如果通過A屬性(屬性組)的值,可以確定唯一B屬性的值,在通過B屬性(屬性組)的值可以確定唯一C屬性的值,則稱 C 傳遞函數依賴於A
例如:學號-->系名,系名-->系主任 - 碼:如果在一張表中,一個屬性或屬性組,被其他所有屬性所完全依賴,則稱這個屬性(屬性組)為該表的碼
例如:該表中碼為:(學號,課程名稱)- 主屬性:碼屬性組中的所有屬性
- 非主屬性:除過碼屬性組的屬性
- 函數依賴:A-->B,如果通過A屬性(屬性組)的值,可以確定唯一B屬性的值。則稱B依賴於A
- 幾個概念:
-
第三范式(3NF):在2NF基礎上,任何非主屬性不依賴於其它非主屬(在2NF基礎上消除傳遞依賴)
-
具體實現如下
-
元數據
-
經1NF規范后 -保證了原子性
-
經2NF規范后 -消除部分依賴(拆分表)
- 此處主屬性為(學號,課程名稱)
- 規范后刪除了冗余數據
-
經3NF規范后 -消除傳遞依賴(繼續拆分)
數據庫的備份和還原 - 一般由DBA來完成
- 命令行操作
- 語法:
- 備份格式: mysqldump -u用戶名 -p密碼 數據庫名稱 > 保存的路徑
- 還原:
- 登錄數據庫 - mysql -uroot -p密碼
- 創建數據庫 - create database 數據庫名稱;
- 使用數據庫 - use 數據庫名稱;
- 執行文件。
- 語法格式:source 文件路徑