【數據庫】SQL新手完整筆記(2020.04)

學習時間:2020/4/17-18
使用:①廖雪峯SQL教程SQL_菜鳥教程 ③《數據庫系統原理》

1、關係數據庫概述

1.1 筆記(課程)介紹

什麼是SQL?

簡單地說,SQL就是訪問和處理關係數據庫的計算機標準語言。也就是說,無論用什麼編程語言(Java、Python、C++……)編寫程序,只要涉及到操作關係數據庫,比如,一個電商網站需要把用戶和商品信息存入數據庫,或者一個手機遊戲需要把用戶的道具、通關信息存入數據庫,都必須通過SQL來完成。

現代程序離不開關係數據庫,要使用關係數據庫就必須掌握SQL。

注意: 廖雪峯教程講解如何使用SQL操作數據庫,以及一種最流行的開源數據庫MySQL的基本安裝和使用方法。

補充: NoSQL —— 非SQL的數據庫

包括MongoDB、Cassandra、Dynamo等等,它們都不是關係數據庫。有很多人鼓吹現代Web程序已經無需關係數據庫了,只需要使用NoSQL就可以。但事實上,SQL數據庫從始至終從未被取代過!!今天,SQL數據庫仍然承擔了各種應用程序的核心數據存儲,而NoSQL數據庫作爲SQL數據庫的補充,兩者不再是二選一的問題,而是主從關係。所以,無論使用哪種編程語言,無論是Web開發、遊戲開發還是手機開發,掌握SQL,是所有軟件開發人員所必須的。

1.2 關係數據庫概述

數據庫是一門專門管理數據的軟件。應用程序不需要自己管理數據,而是通過數據庫軟件提供的接口來讀寫數據。至於數據本身如何存儲到文件,那是數據庫軟件的事情,應用程序自己並不關心。

1.2.1 數據模型(3種)

數據庫按照數據結構來組織、存儲和管理數據,實際上,數據庫一共有三種模型:

1.層次模型
2.網狀模型
3.關係模型

  1. 層次模型
    層次模型就是以“上下級”的層次關係來組織數據的一種方式,層次模型的數據結構看起來就像一顆樹。
    在這裏插入圖片描述
  2. 網狀模型
    網狀模型把每個數據節點和其他很多節點都連接起來,它的數據結構看起來就像很多城市之間的路網——
    在這裏插入圖片描述
  3. 關係模型
    關係模型把數據看作是一個二維表格任何數據都可以通過行號+列號來唯一確定,它的數據模型看起來就是一個Excel表!
    在這裏插入圖片描述
    基於關係模型的關係數據庫,是當下的主流。

1.2.2 關係模型簡介

這一塊爲簡要介紹,在1.4裏會更詳細的介紹~

關係數據庫的關係模型是基於數學理論建立的。

案例——以學校班級爲例,一個班級的學生就可以用一個表格存起來,並且定義如下:
在這裏插入圖片描述
其中,班級ID對應着另一個班級表:
在這裏插入圖片描述
通過給定一個班級名稱,可以查到一條班級記錄,根據班級ID,又可以查到多條學生記錄,這樣,二維表之間就通過ID映射建立了“一對多”關係。

如果我們把班級表分拆得細一點,例如,單獨創建一個教師表:
在這裏插入圖片描述
班級表只存儲教師ID:
在這裏插入圖片描述
這樣,一個班級總是對應一個教師,班級表和教師表就是“一對一”關係。

1.2.3 數據類型

對於一個關係表,除了定義每一列的名稱外,還需要定義每一列的數據類型
在這裏插入圖片描述
★通常來說,BIGINT能滿足整數存儲的需求,VARCHAR(N)能滿足字符串存儲的需求,這兩種類型是使用最廣泛的。

1.2.4 SQL——結構化查詢語言

爲啥要學SQL ?

SQL語句既可以查詢數據庫中的數據,也可以添加、更新和刪除數據庫中的數據,還可以對數據庫進行管理和維護操作。不同的數據庫,都支持SQL,這樣,我們通過學習SQL這一種語言,就可以操作各種不同的數據庫。

SQL的功能拓展 :

雖然SQL已經被ANSI組織定義爲標準,不幸地是,各個不同的數據庫對標準的SQL支持不太一致。並且,大部分數據庫都在標準的SQL上做了擴展。也就是說,如果只使用標準SQL,理論上所有數據庫都可以支持,但如果使用某個特定數據庫的擴展SQL,換一個數據庫就不能執行了。例如,Oracle把自己擴展的SQL稱爲PL/SQL,Microsoft把自己擴展的SQL稱爲T-SQL。各個數據庫支持的各自擴展的功能,通常我們把它們稱之爲“方言”。

總的來說,SQL語言定義了這麼幾種操作數據庫的能力:

DDL:Data Definition Language

DDL允許用戶定義數據,也就是創建表、刪除表、修改表結構這些操作。通常,DDL由數據庫管理員執行。

DML:Data Manipulation Language

DML爲用戶提供添加、刪除、更新數據的能力,這些是應用程序對數據庫的日常操作。

DQL:Data Query Language

DQL允許用戶查詢數據,這也是通常最頻繁的數據庫日常操作。

1.2.5 SQL語法特點

SQL語言關鍵字不區分大小寫!!!但是,針對不同的數據庫,對於表名和列名,有的數據庫區分大小寫,有的數據庫不區分大小寫。同一個數據庫,有的在Linux上區分大小寫,有的在Windows上不區分大小寫。

廖雪峯教程約定:
SQL關鍵字總是大寫,以示突出,表名和列名均使用小寫

1.3 MySQL

MySQL是目前 應用最廣泛 的開源關係數據庫。MySQL最早是由瑞典的MySQLAB公司開發,該公司在2008年被SUN公司收購,緊接着,SUN公司在2009年被Oracle公司收購,所以MySQL最終就變成了Oracle旗下的產品

和其他關係數據庫有所不同的是,MySQL本身實際上只是一個SQL接口,它的內部還包含了多種數據引擎,如——
InnoDB:不知道應該採用哪種引擎,記住總是選擇InnoDB就好了。

//警告:第一次安裝的時候看錯了下了32位,配置完以後setup程序就卡死了…求穩的話直接走廖雪峯的這個教程

1.4 關係模型詳解

關係數據庫是建立在關係模型上的,而關係模型本質上就是若干個存儲數據的二維表,可以把它們看作很多Excel表。

表的每一行稱爲記錄(Record),記錄是一個邏輯意義上的數據。

表的每一列稱爲字段(Column),同一個表的每一行記錄都擁有相同的若干字段。

字段定義了數據類型(整型、浮點型、字符串、日期等),以及是否允許爲NULL。注意NULL表示字段數據不存在。一個整型字段如果爲NULL不表示它的值爲0,同樣的,一個字符串型字段爲NULL也不表示它的值爲空串’’。

通常情況下,字段應該避免允許爲NULL。不允許爲NULL可以簡化查詢條件,加快查詢速度,也利於應用程序讀取數據後無需判斷是否爲NULL。

關係數據庫的表和表之間需要建立“一對多”,“多對一”和“一對一”的關係,這樣才能夠按照應用程序的邏輯來組織和存儲數據。

在關係數據庫中,關係是通過主鍵和外鍵來維護的

1.4.1 主鍵

一張表中的每一行數據被稱爲一條記錄。一條記錄就是由多個字段組成的。每一條記錄都包含若干定義好的字段。同一個表的所有記錄都有相同的字段定義。

對於關係表,有個很重要的約束:任意兩條記錄不能重複。即:
能夠通過某個字段唯一區分出不同的記錄,這個字段被稱爲主鍵

例如,假設我們把name字段作爲主鍵,那麼通過名字小明或小紅就能唯一確定一條記錄。但是,這麼設定,就沒法存儲同名的同學了,因爲插入相同主鍵的兩條記錄是不被允許的。

對主鍵的要求,最關鍵的一點是:記錄一旦插入到表中,主鍵最好不要再修改,因爲主鍵是用來唯一定位記錄的,修改了主鍵,會造成一系列的影響。

選取主鍵的一個基本原則是:不使用任何業務相關的字段作爲主鍵。

(廖雪峯大佬)如果我們以學生的身份證號作爲主鍵,似乎能唯一定位記錄。然而,身份證號也是一種業務場景,如果身份證號升位了,或者需要變更,作爲主鍵,不得不修改的時候,就會對業務產生嚴重影響。因此,身份證號、手機號、郵箱地址這些看上去可以唯一的字段,均不可用作主鍵。

★作爲主鍵最好是完全業務無關的字段,我們一般把這個字段命名爲id。常見的可作爲id字段的類型有:

  1. 自增整數類型
    數據庫會在插入數據時自動爲每一條記錄分配一個自增整數,這樣我們就完全不用擔心主鍵重複,也不用自己預先生成主鍵。對於大部分應用來說,通常自增類型的主鍵就能滿足需求

廖:我們在students表中定義的主鍵也是BIGINT NOT NULL AUTO_INCREMENT類型。使用BIGINT自增類型則可以最多約922億億條記錄!

  1. 全局唯一GUID類型
    使用一種全局唯一的字符串作爲主鍵,類似8f55d96b-8acc-4636-8cb8-76bf8abc2f57。GUID算法通過網卡MAC地址、時間戳和隨機數保證任意計算機在任意時間生成的字符串都是不同的,大部分編程語言都內置了GUID算法,可以自己預算出主鍵

~總結:應該使用BIGINT自增或者GUID類型。

關於聯合主鍵——

關係數據庫允許通過多個字段唯一標識記錄,即兩個或更多的字段都設置爲主鍵,這種主鍵被稱爲聯合主鍵。對於聯合主鍵,允許一列有重複,只要不是所有主鍵列都重複即可
在這裏插入圖片描述
注意:沒有必要的情況下,我們儘量不使用聯合主鍵,因爲它給關係錶帶來了複雜度的上升!!

最後補充:主鍵也不應該允許NULL。

1.4.2 外鍵

關係數據庫通過外鍵可以實現一對多、多對多和一對一的關係。外鍵既可以通過數據庫來約束,也可以不設置約束,僅依靠應用程序的邏輯來保證。

1.4.2.1 一對多關係

當我們用主鍵唯一標識記錄時,我們就可以在students表中確定任意一個學生的記錄:
在這裏插入圖片描述
我們還可以在classes表中確定任意一個班級記錄:
在這裏插入圖片描述
但是我們如何確定students表的一條記錄,例如,id=1的小明,屬於哪個班級呢 ?????????

由於一個班級可以有多個學生,在關係模型中,這兩個表的關係可以稱爲“一對多”,即一個classes的記錄可以對應多個students表的記錄。爲了表達這種一對多的關係,我們需要在students表中加入一列class_id,讓它的值與classes表的某條記錄相對應:
在這裏插入圖片描述
這樣,我們就可以根據class_id這個列直接定位出一個students表的記錄應該對應到classes的哪條記錄。(理解!)

上述內容中: 在students表中,通過class_id的字段,可以把數據與另一張表關聯起來,這種列稱爲外鍵。即class_id是外鍵!

外鍵並不是通過列名實現的。外鍵是通過定義外鍵約束實現的

ALTER TABLE students
ADD CONSTRAINT fk_class_id    #外鍵約束的名稱
FOREIGN KEY (class_id)        #指定class_id作爲外鍵
REFERENCES classes (id);      #指定了這個外鍵將關聯到classes表的id列

通過定義外鍵約束,關係數據庫可以保證無法插入無效的數據!即如果classes表不存在id=99的記錄,students表就無法插入class_id=99的記錄。

廖: 由於外鍵約束會降低數據庫的性能,大部分互聯網應用程序爲了追求速度,並不設置外鍵約束,而是僅靠應用程序自身來保證邏輯的正確性。這種情況下,class_id僅僅是一個普通的列,只是它起到了外鍵的作用而已。

刪除一個外鍵約束,也是通過ALTER TABLE實現的:

ALTER TABLE students
DROP FOREIGN KEY fk_class_id;

刪除外鍵約束並沒有刪除外鍵這一列!刪列是通過DROP COLUMN …實現的。

1.4.2.2 多對多關係

引入:通過一個表的外鍵關聯到另一個表,我們可以定義出一對多關係。有些時候,還需要定義“多對多”關係。例如,一個老師可以對應多個班級,一個班級也可以對應多個老師,因此,班級表和老師表存在多對多關係。

★實現:多對多關係實際上是通過兩個一對多關係實現的,即通過一箇中間表,關聯兩個一對多關係,就形成了多對多關係——
在這裏插入圖片描述
中間表teacher_class關聯兩個一對多關係:(理解!!)
在這裏插入圖片描述
對上面的中間表的解釋:
在這裏插入圖片描述

1.4.2.3 一對一關係

一對一關係是指,一個表的記錄對應到另一個表的唯一一個記錄。例如,students表的每個學生可以有自己的聯繫方式,如果把聯繫方式存入另一個表contacts,我們就可以得到一個“一對一”關係。

引出疑問:爲啥不給students表增加一個mobile列,這樣就能合二爲一了?
在這裏插入圖片描述
如果業務允許,完全可以把兩個表合爲一個表。但是,有些時候,如果某個學生沒有手機號,那麼,contacts表就不存在對應的記錄。實際上,一對一關係準確地說,是contacts表一對一對應students表

★作用——有些應用會把一個大表拆成兩個一對一的表,目的是把經常讀取和不經常讀取的字段分開,以獲得更高的性能! 例如:

把一個大的用戶表分拆爲用戶基本信息表user_info和用戶詳細信息表user_profiles,大部分時候,只需要查詢user_info表,並不需要查詢user_profiles表,這樣就提高了查詢速度。

1.4.3 索引

查找記錄的時候,想要獲得非常快的速度,就需要使用索引。

索引是關係數據庫中對某一列或多個列的值進行預排序的數據結構。通過使用索引,可以讓數據庫系統不必掃描整個表,而是直接定位到符合條件的記錄,這樣就大大加快了查詢速度

例如,對於students表:
在這裏插入圖片描述
如果要經常根據score列進行查詢,就可以對score列創建索引

ALTER TABLE students           
ADD INDEX idx_score (score);  #創建名爲idx_score,使用列score的索引

(索引名稱是任意的)

引如果有多列,可以在括號裏依次寫上,例如:

ALTER TABLE students
ADD INDEX idx_name_score (name, score);

索引的效率取決於索引列的值是否散列,即該列的值如果越互不相同,那麼索引效率越高。反過來,如果記錄的列存在大量相同的值,例如gender列,大約一半的記錄值是M,另一半是F,因此,對該列創建索引就沒有意義!

注意使用索引的代價:索引的優點是提高了查詢效率,缺點是在插入、更新和刪除記錄時,需要同時修改索引,因此,索引越多,插入、更新和刪除記錄的速度就越慢

對於主鍵,關係數據庫會自動對其創建主鍵索引。使用主鍵索引的效率是最高的,因爲主鍵會保證絕對唯一。

關於唯一索引 —— UNIQUE

review:在設計關係數據表的時候,看上去唯一的列,例如身份證號、郵箱地址等,因爲他們具有業務含義,因此不宜作爲主鍵。

but:這些列根據業務要求,又具有唯一性約束:即不能出現兩條記錄存儲了同一個身份證號。這個時候,就可以給該列添加一個唯一索引!!

例如,我們假設students表的name不能重複:

ALTER TABLE students
ADD UNIQUE INDEX uni_name (name); #通過UNIQUE關鍵字添加一個唯一索引

補充:也可以只對某一列添加一個唯一約束而不創建唯一索引——

ALTER TABLE students
ADD CONSTRAINT uni_name UNIQUE (name);

這種情況下,name列沒有索引,但仍然具有唯一性保證!!!

//廖雪峯解釋如何合理使用索引:

無論是否創建索引,對於用戶和應用程序來說,使用關係數據庫不會有任何區別。這裏的意思是說,當我們在數據庫中查詢時,如果有相應的索引可用,數據庫系統就會自動使用索引來提高查詢效率,如果沒有索引,查詢也能正常執行,只是速度會變慢。因此,索引可以在使用數據庫的過程中逐步優化。

1.5 SQL語言的註釋方法

主要有三種。列舉如下:

  1. 使用"#"進行單行註釋
#單行註釋
select * from students;
  1. 使用 "-- " ★注意,–後跟有一個空格!!
-- MySQL單行註釋方法二
select * from students
  1. 多行註釋: 使用/* */
/*
此處爲註釋....
哈哈哈哈嘿嘿嘿嘿
*/
select * from students;

2、查詢數據

(2020.4.17會更完!!莫慌!)

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