數據存儲優化,SQL中的數據類型和規范化
在當今世紀,數據就是新的石油。優化數據存儲對于獲得良好的性能始終至關重要。選擇合適的數據類型并應用正確的規范化過程對于決定其性能至關重要。
本文將研究最重要和最常用的數據類型,并了解規范化過程。
SQL中的數據類型
SQL中主要有兩種數據類型:字符串和數字。除此之外,還有其他數據類型,如布爾型、日期和時間、數組、區間、XML等。
字符串數據類型
這些數據類型用于存儲字符串。字符串通常作為數組數據類型實現,并包含一系列元素,通常是字符。
- CHAR(n):
它是一個固定長度的字符串,可以包含字符、數字和特殊字符。n表示它可以容納的字符串的最大長度(以字符為單位)。
它的最大范圍是從0到255個字符,這種數據類型的問題是,即使實際字符串的長度小于指定的長度,它也會占用全部指定的空間。額外的字符串長度會用額外的內存空間填充。
- VARCHAR(n):
Varchar與Char類似,但可以支持大小可變的字符串,并且沒有填充。該數據類型的存儲大小等于字符串的實際長度。
它最多可以存儲65535個字符。由于其大小可變的特性,它的性能不如CHAR數據類型好。
- BINARY(n):
它類似于CHAR數據類型,但只接受二進制字符串或二進制數據。它可以用于存儲圖像、文件或任何序列化對象。還有另一種數據類型VARBINARY(n),它類似于VARCHAR數據類型,但也只接受二進制字符串或二進制數據。
- TEXT(n):
這種數據類型也用于存儲字符串,但最大大小為65535字節。
- BLOB(n):
代表二進制大對象,可以容納最多65535字節的數據。
除此之外,還有其他數據類型,如LONGTEXT和LONGBLOB,它們可以存儲更多字符。
數字數據類型
- INT():
它可以存儲一個4字節(32位)的整數數字。這里的n表示顯示寬度,最大可以達到255。它指定了用于顯示整數值的最小字符數。
范圍:
- a) -2147483648<=Signed INT<=2147483647
- b) 0<=Unsigned INT<=4294967295
- BIGINT():
它可以存儲一個大小為64位的大整數。
范圍:
- a) -9223372036854775808<=Signed BIGINT<=9223372036854775807
- b) 0<=Unsigned BIGINT<=18446744073709551615
- FLOAT():
它可以存儲浮點數,其小數點位以一定精度近似。它存在一些小的舍入誤差,因此在需要精確精度的情況下不適用。
- DOUBLE():
這種數據類型表示雙精度浮點數。與FLOAT數據類型相比,它可以存儲具有更高精度的小數值。
- DECIMAL(n, d):
該數據類型表示精確的十進制數,精度固定,用d表示。參數d指定小數點后的位數,參數n表示數字的大小。d的最大值為30,其默認值為0。
一些其他數據類型
- BOOLEAN:
這種數據類型只存儲True或False兩種狀態。它用于執行邏輯操作。
- ENUM:
它代表枚舉。它允許你從預定義選項列表中選擇一個值。它還能確保存儲的值僅來自指定的選項。
例如,考慮一個只能是“紅色”、“綠色”或“藍色”的屬性顏色。當我們將這些值放入ENUM中時,顏色的值只能是這些指定的顏色之一。
- XML:
XML代表可擴展標記語言(eXtensible Markup Language)。這種數據類型用于存儲XML數據,XML數據用于結構化數據表示。
- AutoNumber:
它是一個整數,當每條記錄被添加時,它會自動遞增其值。它用于生成唯一或連續的數字。
- Hyperlink:
它可以存儲文件和網頁的超鏈接。
關于SQL數據類型的討論到此為止。其他數據類型還有很多,但本文所討論的是最常用的數據類型。
SQL中的規范化
規范化是從數據庫中移除冗余、不一致和異常的過程。冗余表示相同數據的重復值存在,而數據庫中的不一致表示相同數據以多種格式存在于多個表中。
數據庫異常可以定義為數據庫中不應存在的任何突然變化或不一致。這些變化可能是由于各種原因引起的,例如數據損壞、硬件故障、軟件錯誤等。異常情況可能導致嚴重后果,如數據丟失或不一致,所以盡快檢測和修復異常情況至關重要。主要有三種類型的異常情況。本文將簡要討論每種類型,但如果想了解更多信息,請參閱以下鏈接。
【異常情況】:https://www.geeksforgeeks.org/anomalies-in-relational-model/
- 插入異常:
當新插入的行在表中導致不一致時,就會發生插入異常。例如,我們想要將一個員工添加到組織中,但是他的部門沒有分配給他。那么我們就無法將該員工添加到表中,這就產生了一個插入異常。
- 刪除異常:
當我們想要從表中刪除某些行,并且還需要刪除數據庫中的其他數據時,就會發生刪除異常。
- 更新異常:
當我們想要更新某些行并導致數據庫的數據不一致時,就會發生這種異常。
規范化過程包含一系列準則,可使數據庫設計高效、優化,并且不含冗余和異常。有幾種常見的規范化形式,如第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、BCNF等。
1. 第一范式(1NF)
第一范式確保表中不包含復合或多值屬性。這意味著單個屬性中只有一個值。如果每個屬性都是單值的,那么關系就符合第一范式。
例如:
圖片
在表1中,屬性STUD_PHONE包含多個電話號碼。但是在表2中,該屬性被分解為第一范式。
2. 第二范式(2NF)
表格必須符合第一范式,并且關系中不能存在任何部分依賴關系。部分依賴意味著非主屬性(不是候選鍵的一部分的屬性)部分依賴于候選鍵的任何一個真子集。為了使關系符合第二范式,非主屬性必須完全依賴于整個候選鍵。
例如,考慮一個名為Employee的表,具有以下屬性:
EmployeeID (Primary Key)
ProjectID (Primary Key)
EmployeeName
ProjectName
HoursWorked
在這里,EmployeeID和ProjectID共同構成主鍵。不過,你可以注意到EmployeeName和EmployeeID之間存在部分依賴關系。這意味著EmployeeName只依賴于主鍵的一部分(即EmployeeID)。要實現完全依賴,EmployeeName必須同時依賴于EmployeeID和ProjectID。因此,這違反了第二范式的原則。
為了使這種關系符合第二范式,我們必須將表拆分成兩個獨立的表。第一個表包含所有雇員的詳細信息,第二個表包含所有項目的詳細信息。
因此,Employee表具有以下屬性:
EmployeeID (Primary Key)
EmployeeName
而Project表具有以下屬性:
Project ID (Primary Key)
Project Name
Hours Worked
現在可以看到,通過創建兩個獨立的表,部分依賴關系已經被消除。而且兩個表的非主屬性依賴于完整的主鍵集合。
3. 第三范式(3NF)
在第二范式之后,關系仍然可能存在更新異常。如果我們只更新了一個元組而不更新其他元組,就會出現這種情況。這將導致數據庫的不一致性。
第三范式的條件是表應該符合第二范式,并且非主屬性不存在傳遞依賴關系。傳遞依賴發生在非主屬性不直接依賴于主屬性,而是依賴于另一個非主屬性的情況下。主屬性是候選鍵的一部分。
考慮一個關系R(A,B,C),其中A是主鍵,B和C是非主屬性。假設A→B和B→C是兩個函數依賴關系,那么A→C就是傳遞依賴關系。這意味著屬性C不是由屬性A直接確定的。B在它們之間起中間人的作用。
如果一個表存在傳遞依賴關系,那么我們可以通過將表拆分為獨立的關系來將其轉化為第三范式。
4.Boyce-Codd范式
盡管第二范式和第三范式消除了大部分冗余,但仍然沒有完全消除冗余。如果函數依賴關系的左側不是候選鍵或超鍵,就可能存在冗余。候選鍵由主屬性形成,超級鍵是候選鍵的超集。為了解決這個問題,還存在另一種類型的函數依賴關系,稱為Boyce-Codd范式(BCNF)。
對于一個表來說,要達到BCNF,函數依賴關系的左側必須是候選鍵或超鍵。例如,對于一個函數依賴關系X→Y,X必須是候選鍵或超鍵。
考慮一個包含以下屬性的Employee表:
- 員工ID(主鍵)
- 員工姓名
- 部門
- 部門負責人
EmployeeID是唯一標識每一行的主鍵。Department屬性表示特定員工所在的部門,而Department Head屬性表示擔任該特定部門負責人的員工的EmployeeID。
現在,我們將檢查這個表是否符合BCNF。條件是函數依賴關系的左側必須是超鍵。下面是該表的兩個函數依賴關系。
- 函數依賴關系1:員工ID→員工姓名,部門,部門負責人
- 函數依賴關系2:部門→部門負責人
對于FD1,員工ID是主鍵,也是超鍵。但對于FD2,部門不是超鍵,因為多個員工可能屬于同一個部門。
因此,這個表違反了BCNF的條件。為了滿足BCNF的屬性,我們需要將該表拆分為兩個獨立的表:Employee表和Department表。Employee表包含員工ID、員工姓名和部門,而Department表則包含部門和部門負責人。
圖片
圖片
現在我們可以看到,在這兩個表中,所有的函數依賴關系都依賴于主鍵,即不存在非三維依賴關系。
我們已經介紹了所有知名的規范化技術,但除此之外,還有兩種更高級的范式,分別是第四范式(4NF)和第五范式(5NF)。如果想了解更多信息,可以參閱以下鏈接。
【鏈接】:https://www.geeksforgeeks.org/difference-between-4nf-and-5nf/
總結
本文討論了SQL中最常用的數據類型以及數據庫管理系統中重要的規范化技術。在設計數據庫系統時,我們的目標是使其具有可擴展性,最小化冗余并確保數據完整性。
通過選擇適當的數據類型,我們可以在存儲、精度和內存消耗之間取得微妙的平衡。同時,規范化過程有助于消除數據異常并使數據庫模式更有組織性。