《數據庫基礎語法》16. 數據庫的常見數據類型以及DDL


楔子

上節我們討論了如何進行數據庫的結構設計,並具體介紹了實體關系圖和規范化的技術。

在設計 ERD 時,首先需要定義實體以及實體的屬性,也就是定義表的結構。定義表結構時,首先需要確認表中包含哪些字段以及字段的數據類型。今天我們就來了解一下如何為表中的字段選擇合適的數據類型。

常見數據類型

字段的數據類型定義了該字段能夠存儲的數據值,以及允許執行的操作。

 

字符串類型:

字符串類型用於存儲字符和字符串數據,主要包含三種具體的類型:定長字符串、變長字符串以及字符串大對象。各種數據庫對於字符串類型的支持如下:

CHAR(n) 表示長度固定的字符串,其中 n 表示字符串的長度。常見的定義方式包括:

  • CHAR,長度為 1 的字符串,只能存儲 1 個字符
  • CHAR(5),長度為 5 的字符串

對於定長字符串,如果輸入的字符串長度不夠,將會使用空格進行填充。例如類型為 CHAR(5) 的字段,如果輸入值為 "A",實際存儲的內容為 "A####";# 代表空格,也就是一個字符 "A" 加上 4 個空格。

CHARACTER 和 CHAR 是同義詞,可以通用。

通常來說,只有存儲固定長度的數據時,才會考慮使用定長字符串類型。例如 18 位身份證,6 位郵政編碼等。

VARCHAR(n) 表示長度不固定的字符串,其中 n 表示允許存儲的最大長度。

對於變長字符串,如果輸入的字符串長度不夠,存儲實際的內容。例如類型為 VARCHAR(5) 的字段,如果輸入值為 "A",實際存儲的內容為 "A"。

CHAR VARYING 和 CHARACTER VARYING 是 VARCHAR 的同義詞,可以通用。 Oracle 中使用 VARCHAR2 表示變長字符串類型。

變長字符串類型一般用於存儲長度不固定的內容,例如名字、電子郵箱、產品描述等。

CLOB 表示字符串大對象,通常用於存儲普通字符串類型無法支持的更長的字符串數據。例如整篇文章、備注、評論等。

Oracle 使用 CLOB 類型存儲大型字符串;MySQL 提供了 TINYTEXT、TEXT、MEDIUMTEXT 以及 LONGTEXT 分別用於存儲不同長度的文本數據;SQL Server 使用 VARCHAR( MAX ) 存儲大文本數據;PostgreSQL 提供了 TEXT 類型存儲任意長度的字符串。

CHARACTER LARGE OBJECT 和 CHAR LARGE OBJECT 是 CLOB 的同義詞,可以通用。

在 SQL 中,輸入字符串類型的常量和數據時,需要使用單引號引用:

'S001'
'張飛'
'13512345678'

 

數字類型:

數字類型主要分為兩類:精確數字和近似數字。

精確數字類型用於存儲整數或者包含固定小數位的數字。

其中,SMALLINT、INTEGER 和 BIGINT 都可以表示整數。對於 MySQL、SQL Server 以及 PostgreSQL,SMALLINT 支持 -32768 ~ 32767;INTEGER 支持 -2147483648 ~ 2147483647;BIGINT 支持 -263 ~ 263-1。Oracle 中的 SMALLINT 和 INTEGER 都是NUMBER(38,0) 的同義詞;Oracle 不支持 BIGINT 關鍵字。

INT 是 INTEGER 的同義詞,可以通用。 MySQL 中還提供了 TINYINT,支持 -128 ~ 127;MEDIUMINT 支持 -8388608 ~ 8388607。另外,MySQL 中的所有整型分為有符號類型(例如 INTEGER、INTEGER SIGNED)和無符號類型(例如 INTEGER UNSIGNED),無符號整型支持的正整數范圍擴大了一倍。

NUMERIC(p, s) 和 DECIMAL(p, s) 可以看作相同的類型,用於存儲包含小數的精確數字。

其中,精度 p 表示總的有效位數,刻度 s 表示小數點后允許的位數。例如,123.04 的精度為 5,刻度為 2。p 和 s 是可選的,s 為 0 表示整數。SQL 標准要求 p ≥ s ≥ 0 並且 p > 0。

DEC 是 DECIMAL 的同義詞,可以通用。 Oracle中的 NUMERIC 和 DECIMAL 都是 NUMBER 的同義詞。

整數類型通常用於存儲數字 id、產品數量、課程得分等數字;NUMERIC 用於存儲產品價格、銷售金額等包含小數並且准確度要求高的數據。

近似數字也稱為浮點型數字,一般使用較少,主要用於科學計算領域。

REAL 表示單精度浮點數,通常精確到小數點后 6 位;DOUBLE PRECISION 表示雙精度浮點數,通常精確到小數點后 15 位。浮點數運算更快,但是可能丟失精度;浮點數的比較運算可能會導致非預期的結果。

Oracle 使用 BINARY_FLOAT 和 BINARY_DOUBLE 表示浮點數。 MySQL 使用 FLOAT 表示單精度浮點數,同時區分有符號和無符號的浮點數。

 

日期時間類型:

DATE 存儲年、月、日;TIME 存儲時、分、秒,以及秒的小數部分;TIMESTAMP 同時包含年、月、日、時、分、秒,以及秒的小數部分。

Oracle 中的 DATE 類型包含了額外的時、分、秒,不支持 TIME 類型。 SQL Server 使用 DATETIME2 和 DATETIMEOFFSET 表示時間戳。 MySQL 還支持 DATETIME 表示時間戳。

如果存儲日期信息,例如生日,可以使用 DATE 類型;如果需要更高的時間精度,例如訂單時間、發車時間等,可以使用 TIMESTAMP 類型;TIME 類型使用較少。

在 SQL 中,輸入日期時間類型的常量和數據時,常見的方法如下:

'2019-12-25'
DATE '2019-12-25'
'13:30:15'
TIME '13:30:15'
'2019-12-25 13:30:15'
TIMESTAMP '2019-12-25 13:30:15'

 

二進制類型:

二進制類型用於存儲二進制數據,例如文檔、圖片,視頻等。二進制類型具體包含以下三種:

  • BINARY(n),固定長度的二進制數據,n 表示二進制字符數量;
  • VARBINARY(n),可變長度的二進制數據,n 表示支持的最大二進制字符數量;
  • BLOB,二進制大對象;

Oracle 支持 BLOB 二進制類型;MySQL 支持 BINARY、VARBINARY 以及 TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB 二進制類型;SQL Server 支持 BINARY、VARBINARY 以及 VARBINARY ( MAX ) 二進制類型;PostgreSQL 支持 BYTEA 二進制類型。

 

選擇合適的數據類型:

最后我們來看看如何選擇合適的數據類型。首先,應該滿足存儲業務數據的需求;其次,還需要考慮性能和使用方便。一般來說,先確定基本的類型:

  • 文本數據,只能使用字符串類型;
  • 數值數據,尤其是需要進行數學運算的數據,選擇數字類型;
  • 日期和時間信息,最好使用原生的日期時間類型;
  • 文檔、圖片、音頻和視頻等,使用二進制類型;或者可以考慮存儲在文件服務器上,然后在數據庫中存儲文件的路徑;

接下來需要進一步確定具體的數據類型。在滿足數據存儲和擴展的前提下,盡量使用更小的數據類型,可以節省一些存儲,通常性能也會更好。例如,對於一個小型公司而言,員工編號通常不會超過幾百,使用 SMALLINT 已經足夠。對於 MySQL 而言,不需要支持負數的話可以考慮 UNSIGNED 類型。

如果需要存儲精確的數字,不要使用浮點數類型。對於金額,可以使用 NUMERIC(p, s);或者將數據乘以 10 的 N 次方,例如將 10.35 元存儲為整數 103500,然后在應用程序中進行處理和前端顯示轉換。

對於字符數據,一般使用 VARCHAR 類型;如果數據長度能夠確保一致,可以使用 CHAR;指定最大長度時,滿足存儲需求的前提下盡量使用更小的值。只有在普通字符串類型長度無法滿足時才考慮大字段類型。

不要使用字符串存儲日期時間數據,它們無法支持數據的運算。例如獲得兩個日期之間的間隔,需要依賴應用程序進行轉換和處理。最好也不要使用整數類型存儲當前時間距離 1970 年 1 月 1 日的毫秒數來表示時間,這種方式在顯示時需要進行轉換,不是很方便。

另外,如果一個字段同時出現在多個表中,使用相同的數據類型。例如,員工表中的部門編號(dept_id)字段與部門表的編號(dept_id)字段保持類型一致。

使用 DDL 管理數據庫中的對象

上節我們討論了如何為字段選擇合適的數據類型。選定了字段的數據類型之后,我們就可以開始創建和管理數據庫中的表了。

 

數據庫對象:

數據庫(Database)由一組相關的對象組成,主要包括表、索引、視圖、存儲過程等。為了方便對象的管理和訪問,數據庫通常使用模式(Schema)來組織這些對象;模式是一個邏輯單元,或者一個存儲對象的容器;它們之間的關系如下圖所示:

一個數據庫由多個模式組成,一個模式由許多對象組成;在不同模式中可以創建同名的對象。

MySQL 中的模式和數據庫是相同的概念,一個數據庫對應一個同名的模式。

 

管理數據庫:

當我們連接到數據庫服務器時,需要指定一個目標數據庫。如果需要創建一個新的數據庫,可以使用 CREATE DATABASE 語句:

CREATE DATABASE mydb;

以上語句將會創建一個名為 mydb 的數據庫。對於 Oracle 而言,通常只有一個數據庫;因此很少手動創建數據庫。

我們可以使用命令或語句查看已有的數據庫

-- MySQL 實現
SHOW DATABASES;

SELECT schema_name AS database_name
  FROM information_schema.schemata;
-- information_schema 系統數據庫存儲了 MySQL 服務器中所有數據庫的信息,例如數據庫名稱、表的結構以及訪問權限等。
  
-- SQL Server 實現
SELECT name AS database_name
  FROM sys.databases;
-- sys.databases 是 SQL Server 中的一個系統表,存儲了關於數據庫的信息。


-- PostgreSQL 實現
SELECT datname AS database_name
  FROM pg_database;
-- pg_database 是 PostgreSQL 中的一個系統表,存儲了關於數據庫的信息。  
  
-- Oracle 實現
SELECT name AS database_name
  FROM v$database;
-- v$database 是 Oracle 中的一個系統視圖,提供了關於數據庫的信息。  

如果確認不再需要,可以使用 DROP DATABASE 語句刪除數據庫:

DROP DATABASE mydb;

DROP DATABASE 命令將會刪除該數據庫中的所有對象,而且操作無法恢復,使用時千萬小心!

如果有用戶正在連接,無法刪除數據庫;可以等待用戶斷開連接,或者強制斷開連接后刪除。

 

管理模式:

CREATE SCHEMA 命令用於創建一個新的模式:

-- SQL Server 以及 PostgreSQL 實現
create schema xxx [AUTHORIZATION some_user]

以上語句創建一個名為 xxx 的模式,可選的 AUTHORIZATION 表示為該模式指定一個擁有者 some_user,擁有者是一個已經存在的數據庫用戶。

SQL Server 創建數據庫時會自動創建一個名為 dbo 的模式,PostgreSQL 創建數據庫時會自動創建一個名為 public 的模式。

MySQL 中的模式等價於數據庫,因此 CREATE SCHEMA 等價於 CREATE DATABASE。

Oracle 中的模式等價於用戶,因此使用 CREATE USER 命令創建用戶時就相當於創建一個同名的模式:

CREATE USER some_user
  IDENTIFIED BY xxx;

Oracle 也提供了 CREATE SCHEMA 命令,但不是用於創建模式,而是用於在模式中創建表、視圖以及執行授權操作。

不需要的模式可以使用 DROP SCHEMA 命令刪除:

-- SQL Server 以及 PostgreSQL 實現
DROP SCHEMA xxx;

MySQL 中的模式等價於數據庫,因此 DROP SCHEMA 等價於 DROP DATABASE。

Oracle 中的模式等價於用戶,因此使用 DROP USER 命令創建用戶時就相當於創建一個同名的模式:

-- Oracle 實現
DROP USER hr;

如果模式中存在對象,則無法刪除該模式;可以先刪除其中的對象,再刪除模式。某些數據庫支持級聯刪除:

-- PostgreSQL 實現
DROP SCHEMA xxx CASCADE;

-- Oracle 實現
DROP USER some_user CASCADE;

 

復制表:

像創建表、添加記錄、修改記錄等等比較簡單,我們這里就不提了,可以去菜鳥教程上面搜索,非常簡單。

除了手動創建表之外,也可以基於其他表或者查詢的結果創建一個表:

CREATE TABLE table_name
    AS
SELECT ...;

 

修改表:

對於已經存在的表,可能會由於業務變更或者代碼重構需要修改它的結構。因此,SQL 定義了修改表的語句:

其中的 action 表示執行的操作,常見的操作包括增加列,修改列,刪除列;增加約束,修改約束,刪除約束等。以下語句用於增加一個新的字段:

ALTER TABLE table_name 
  ADD 列名 類型 [約束];
-- 添加字段的內容和創建表時類似,包括字段名、數據類型以及可選的列約束

如果某個字段不再需要,可以使用 DROP COLUMN 操作刪除:

ALTER TABLE table_name drop 列名

 

刪除表:

-- DROP TABLE 語句用於刪除一個表。
DROP TABLE table_name

 

截斷表:

SQL 還提供了一種特殊的操作:截斷表(TRUNCATE),可以用於快速刪除表中的所有數據。

TRUNCATE TABLE table_name

TRUNCATE 用於快速刪除數據,回收表占用的空間,但會保留表的結構。MySQL 和 PostgreSQL 可以省略 TABLE 關鍵字。

小結

今天我們介紹了 SQL 中的基本數據類型以及它們在各種數據庫中的實現,同時分析了選擇數據類型時的一些通用的原則。需要注意的是,同一數據類型在不同數據庫中支持的范圍大小和精確度可能不同;因此,使用任何數據類型之前都應該查看相關的數據庫文檔。

數據定義語言(Data Definition Language)用於定義數據庫中各種對象的結構,例如表、視圖、索引等。常見的 DDL 語句包括創建(CREATE)、修改(ALTER)和刪除(DROP)。雖然各種對象的具體語法細節不同,但都遵循相同的模式;例如,創建索引可以使用 CREATE INDEX 語句;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM