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