MySQL-DML、約束、索引

2.2DML

2.2.1 insert

#數據插入格式
insert into '表名'('字段1','字段2','字段3')values('','','');
#省略字段名插入
insert into '表名' values(所有的字段值);

#一次插入多行數據
insert into '表名'('字段1','字段2','字段3') values('','',''),
										 values('','',''),
										 values('','','');
										 
#將查詢結果插入表中,要求表結構與數據類型一致
insert into '表名' select * from t_user;

2.2.2 update

#數據修改格式
update '表名' set '字段1'='value','字段2'='value' where 指定更新的條件(不指定會全部更新爲相同值)

2.2.3 delete

#刪除記錄格式
delete from '表名' where 條件
#沒有條件會默認刪除全部
#delete 刪除效率低,因爲沒有釋放空間,還可以回滾恢復數據

#如何快速刪除大表?
truncate table '表名';#數據永久丟失

2.3DDL

2.3.1 create

#建表格式
create table '表名'(
	'字段1' 數據類型 (屬性 默認值),
    '字段2' 數據類型 (屬性 默認值),
    '字段3' 數據類型 (屬性 默認值),
    ....
);

#表複製
create table '表名' as select * from t_user;

2.4約束Constraint

在創建表時,可以給表的字段添加相應的約束,添加約束的目的是爲了保證表中數據的合法性、有效性、完整性

常見約束:

  • 非空約束(not null):約束字段不能爲null
  • 唯一約束(unique):約束字段值不重複
  • 主鍵約束(primary key):約束字段即不能爲空,也不能重複
  • 外鍵約束(foreign key):
  • 檢查約束:mysql暫不支持

2.4.1 not null

create table t_student(
	id int not null,
	username varchar(20) not null,
	passwordcvarchar(255)
);

2.4.2 unique

#唯一性約束脩飾的字段具備唯一性,不能重複,但是可以爲空
create table t_student(
	id int not null,
	username varchar(20) unique,#列級約束
	passwordcvarchar(255)
);
#組合式多個字段聯合唯一約束
create table t_student(
	id int not null,
	username varchar(20),
	password varchar(255),
    unique(username,password)#表級約束,表示只要兩個字段不是都相等都可以
);

2.4.3 primary key

#主鍵約束要求,數據不能爲null也不能重複
create table t_student(
	id int primary key,#列級約束
	username varchar(20),
	password varchar(255)
);
#主鍵約束要求,數據不能爲null也不能重複
create table t_student(
	id int primary key auto_increment,#列級約束,字段值從1開始自增
	username varchar(20),
	password varchar(255)
);
create table t_student(
	id int primary key,
	username varchar(20),
	password varchar(255),
    primary key(id)#表級約束
);

主鍵有什麼作用?

  • 表的設計三範式有要求,第一範式就要求任何一張表都應該有主鍵
  • 主鍵值是這行記錄在表中的唯一標識

主鍵分類:

  • 單一主鍵:常用方式
  • 複合主鍵:多個字段聯合起來添加一個主鍵約束,不建議使用,違反三範式
  • 自然主鍵:單純表示一條唯一記錄屬性
  • 業務主鍵:與系統業務掛鉤,存在修改、刪除的可能性,不建議使用

2.4.4foreign key

#外鍵約束表示該字段與另外一張表的字段聯繫
create table t_class(
	cno int primary key auto_crement,
    cname varchar(20)
);
create table t_student(
	sno int primary key auto_crement,
    sname varchar(20),
    cno int,
    foreign key(cno) references t_class(cno)#references 表示引用某張表的某個字段,該字段不一定是主鍵,但是必須具備唯一性
);
t_class 班級表
cno(pk)		cname
101			高三1班
102			高三2班

t_student 學生表
sno(pk)			sname		 cno(fk)
1				李明		    101
2				周翔			102

此時t_student引用t_class,t_class稱爲父表,t_student稱爲子表
- 創建表時,先建父表再建子表
- 刪除表時,先刪除子表再刪除父表
- 增加數據時,先增加父表,再增加子表
- 刪除數據時,先刪除子表,再刪除父表

2.5存儲引擎(瞭解)

存儲引起只在mysql中存在,默認存儲引擎InnoDB,默認字符集UTF8

查看當前支持的存儲去引擎

show engines \G

2.5.1 MyISAM存儲引擎

  • 使用三個文件表示每個表:
    • 格式文件 — 存儲表結構的定義(mytable.frm)
    • 數據文件 — 存儲錶行的內容(mytable.MYD)
    • 索引文件 — 存儲表上的索引(mytable.MYI)
  • 靈活的AUTO_INCREMENT字段處理
  • 可別轉換爲壓縮、只讀表來節省空間
  • 不支持事務

2.5.2 InnoDB存儲引擎

  • 默認的MySQL存儲引擎
  • 每個表在數據庫均以(.frm)格式文件表示
  • InnoDB表空間tablespace被用於存儲表的內容
  • 提供一組用來記錄事務性活動的日誌文件
  • 用commit提交、savapoint及ROLLBACK回滾支持事務處理
  • 提供全ACID兼容
  • 在MySQL服務器崩潰後提供自動恢復
  • 多版本MVCC和行級鎖定
  • 支持外鍵及引用的完整性,包括級聯刪除和更新

2.5.3 MEMORY

  • 不支持事務
  • 數據索引存儲在內存中
  • 數據易丟失
  • 查詢數據快

2.6 練習題

數據參照前文的sql文件

2.6.1取得每個部門最高薪水的人員名稱

#1、取得每個部門最高薪資
select deptno,max(sal) maxsal from emp group by deptno;
#2、將最高薪資表作爲臨時表t,t表和emp表聯合條件查詢
select 
	e.ename,t.* 
from 
	(select deptno,max(sal) maxsal from emp group by deptno) as t 
join 
	emp e 
on 
	t.deptno=e.deptno and t.maxsal=e.sal;
/*
+-------+--------+---------+
| ename | deptno | maxsal  |
+-------+--------+---------+
| BLAKE |     30 | 2850.00 |
| SCOTT |     20 | 3000.00 |
| KING  |     10 | 5000.00 |
| FORD  |     20 | 3000.00 |
+-------+--------+---------+
*/

2.7事務

2.7.1什麼是事務

一個事務就是一個完整的業務邏輯單元,不可再分

比如銀行轉賬,從A賬戶轉到B賬號1000元,需要執行兩條update語句

update A -1000

update B+1000

要麼同時成功,要麼同時失敗

2.7.2DML事務相關

與事務有關的語句只用DML語句(insert,delete,update)

事務機制:假設需要執行insert into>>update>>delete

  1. 開啓事務機制
    • 執行insert into 語句,操作成功後,執行記錄記錄到數據庫的操作歷史當中,並不會向文件中保存一條數據,不會真正修改硬盤上的數據
    • 執行update
    • 執行delete
  2. 提交事務或回滾事務,修改硬盤數據

MySQL事務默認情況自動提交,start transaction關閉自動提交

#MySQL事務默認自動提交
start transaction;#將自動提交關閉,開啓一個事務
insert into tablename values();#插入新數據
select * from tablename;#查出剛插入的數據
rollback;#回滾,取消剛插入的數據,事務結束

2.7.3 事務特性ACID

  • Atomic 原子性:事務是最小工作單元,不可分割
  • Consistency 一致性:事務必須保證多條DML語句要麼成功要麼失敗
  • Isolation 隔離性:事務A與事務B之傢俱有隔離
  • Durability 持久性:持久性說的是最終數據必須持久化到硬盤中

2.7.3.1隔離級別

第一級別:讀未提交(read uncommitted)存在髒讀想象

​ 對方事務還沒有提交,我們當前事務可以讀到對方未提交的數據

#設置事務的的全局隔離級別
mysql> set global transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.01 sec)
#查看當前全局隔離級別
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| READ-UNCOMMITTED      |
+-----------------------+
1 row in set, 1 warning (0.00 sec)
#設置完成退出登錄重新登錄

#窗口1創建事務
start transaction;
insert into t_user(name) values('libo');#此時事務沒有提交

#窗口2查看窗口1創建的事務未提交的數據
select * from t_user;

mysql> select * from t_user;
+----+-------+
| id | name  |
+----+-------+
|  1 | smith |
|  2 | libo  |
+----+-------+
2 rows in set (0.09 sec)

第二級別:讀已提交(read committed)解決髒讀,出現不可重複讀

​ 對方事務提交之後的數據我方可以讀到

#重新設置全局隔離級別
set global transaction isolation level read committed;
#exit 重新登錄數據庫後,窗口1開啓事務
start transaction;
insert into t_user(name) values('bobo');#插入數據,但是當前不提交事務
commit;#執行事務提交,這樣窗口2才能看到數據

#窗口2嘗試查看窗口1未提交的數據,並沒有數據。

#窗口1提交後,窗口2查看,libo並沒有提交,所以那個事務已經失效
start transaction;
mysql> select * from t_user;
+----+-------+
| id | name  |
+----+-------+
|  1 | smith |
|  3 | bobo  |
+----+-------+
2 rows in set (0.07 sec)

第三級別:可重複讀(repeatable read)解決不可重複讀,存在讀取到的數據是幻象

第四級別:序列化讀/串行化讀 解決所有問題,效率低,事務需要排隊

Oracle數據庫默認的隔離級別是:讀已提交

MySQL數據庫默認的隔離界別是:可重複讀

2.8索引

什麼是索引?有什麼用?

​ 索引就相當於書的目錄,通過目錄縮小掃描範圍,找到對應的資源;

​ 查詢表的檢索方式:

- 全表掃描,效率低
- 根據索引檢索,效率高

索引雖然可以提高檢索效率,但是不能隨意添加索引,因爲索引也是數據庫當中的對象,也需要數據庫不斷的維護。如果表中的數據經常修改,就不適合添加索引,索引字段數據修改後索引需要重新排序,進行維護。

怎麼創建索引對象?怎麼刪除索引對象?

#創建索引
create index '索引名稱' on '表名(表字段)';

#刪除索引
drop indes '索引名稱' on '表名';

什麼時候考慮給字段添加索引?

  • 數據量龐大
  • 該字段很少進行DML操作
  • 該字段經常出現在where查詢條件中

注意:主鍵和具有unique約束的字段會自動添加索引,儘量使用主鍵查詢記錄提高效率

查看sql語句的查詢計劃

explain sql語句

2.8.1索引底層實現

索引底層數據結構B+樹,底層索引進行排序,分區,索引會攜帶數據表中的物理地址(磁盤地址),最終通過索引關聯的物理地址,通過物理地址實現高效查詢

select * from user where name='SMITH'
#將被物理地址替換
select * from user where 物理地址=0x3..

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-kpoYDB46-1578031399661)(D:\文件\Java筆記文檔\深入理解java8\Java面試Acces\360截圖18340808109138105.png)]

2.8.2索引分類

單一索引:

複合索引:多個字段添加索引

主鍵索引:主鍵上會自動添加索引

唯一索引:在unique約束的字段上自動添加索引

2.8.3索引什麼時候失效

採用模糊查詢的時候。

3、數據庫設計三範式

  1. 什麼是設計範式

    設計表的依據。按照這個三範式設計的表減少數據冗餘。

  2. 三範式具體有哪些?

    • 第一範式:任何一張表中必須有主鍵,並且每個字段原子性不可再分

    • 第二範式:建立在第一範式基礎上,另外要求所有非主鍵字段完全依賴主鍵,不能產生部分依賴

      多對多,三張表,兩個外鍵

    • 第三範式:建立在第二範式基礎上,所有非主鍵不能傳遞依賴於主鍵的字段

      一對多,兩張表,多的加外鍵

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章