數據表
數據表簡稱表,是數據庫的最主要組成成分。數據庫建好以后里面沒有任何內容,通過在數據庫中添加表插入記錄后,數據庫中才會有內容。表由若干欄目(即列或者字段)和若干行組成,每一行稱為一條記錄。每個欄目均需要設置其名稱(即列名、字段名)、數據類
型、長度、約束,列名必須符合標識符的要求,數據類型由系統規定,長度是一個整數,表示這個列最大可以輸入多少個字符,而約束是對這個列的值設置的限制條件。
數據類型
數據類型表達的功能是當前列的值是什么類型的,建立表時決定各個列的數據類型的唯一依據是這個列的所有可能取值。
字符型
varchar 和 char 類型的主要區別是:數據填充后實際占用的長度不同。如果 varchar(20) 類型的值為有 5 個字符,物理上只存儲 5 個字節,但如果數據類型為 char(20) 則將使用全部 20 個字節。nvarchar 和 nchar 的工作方式與對應的 varchar 數據類型和 char 數據類型相同,這兩種數據類型都可以處理國際性的 Unicode 通用字符。
數據類型 | 格式 | 描述 |
---|---|---|
char | char(n) | 1~8000 字符 |
varchar | varchar(n) | 1~8000 字符 |
nchar | nchar(n) | 1~4000 個 Unicode 字符 |
nvarchar | nvarchar(n) | 最多為 2^30-1 個 Unicode 字符 |
整數型
整數型簡稱整型,可用於存儲精確的整數,幾種的區別在於表示數據的范圍不同。
數據類型 | 描述 | 存儲空間 |
---|---|---|
bit | 0、1、null | 1字節 |
tinyint | 0~255 之間的整數 | 1字節 |
smallint | -32768~32767 之間的整數 | 2字節 |
int | -231~231-1 之間的整數 | 4字節 |
bigint | -263~263-1 之間的整數 | 8字節 |
精確實數型
表示能夠精確存儲的實數值,由總長度和小數位數構成,總位數不得小於小數位數。
數據類型 | 格式 | 描述 |
---|---|---|
十進制型 | decimal(n,m) | n 表示總長度,m 表示小數位數 |
數值型 | numeric(n,m) | n 表示總長度,m 表示小數位數 |
時間型
在 SQLServer 中日期時間型表示日期或者時間,其值要以字符串的形式表示,包括 4 種類型。
數據類型 | 描述 | 范圍 | 格式 |
---|---|---|---|
date | 日期型 | 1753.1.1 ~ 9999.12.31 | MM/DD/YYYY 或 MM-DD-YYYY |
time | 時間型 | 12 小時或 24 小時制時間 | hh:mm:ss AM/PM |
datetime | 日期和時間 | 1753.1.1 00:00:00 ~ 9999.12.31 23:59:59 | MM/DD/YYYY hh:mm:ss AM/PM |
smalldatetime | 小日期時間型 | 1900.1.1 00:00:00 ~ 2079.6.6 23:59:59 | MM/DD/YYYY hh:mm:ss AM/PM |
文本型
文本型數據類型主要是用於存儲超大長度的文本內容,即用 char、varchar、nchar、nvarchar四種類型還不足以表示的大數據。
數據類型 | 描述 | 范圍 |
---|---|---|
text | 字符型,用來存儲大量的非統一編碼型字符數據 | 最多可以有 2^31-1 或 20 億個字符 |
nchar | 統一編碼字符型,用來存儲定長統一編碼字符型數據 | 最大容量為 2^30-1 字節 |
二進制型
二進制數據類型用於存儲二進制數據,包括 binary、varbinary、image 三種類型。當表中各條記錄這個列的內容接近相同的長度時,使用 binary 比較合理。當各條記錄此列的內容長短不一,變化較大時,使用 varbinary 有利於節省存儲空間。類似於照片、頭像、證書等這樣的字段可以采用 image 類型,支持JPG、TIFF、PNG、GIF 等格式。
數據類型 | 描述 | 范圍 |
---|---|---|
binary | 二進制數據類型 | 存儲最長 8000 字節長的定長的二進制數據 |
varbinary | 可變長二進制數據類型 | 用來存儲最長 8000 字節的二進制數據 |
image | 圖像型,用來存儲變長的二進制數據 | 最大可達 2^31-1 字節 |
特殊數據類型
數據類型 | 描述 |
---|---|
timestamp | 時間戳類型,表示 SQL Server 活動的先后順序 |
unigueidentifier | 唯一標識型類型,根據網卡地址和 CPU 時鍾產生 |
完整性約束
建立表的時候,還需要設置表的完整性約束,完整性約束指的是按照其值的內在邏輯或完整性而確定的限制條件。比如年齡必須是正整數、Email 中必須有 @ 符號,性別只能是“男”或者“女”等。約束分兩種,一種是列級約束,即約束條件只對某一列有效,另一種是表級約束,指涉及兩個以上的列。
約束類型 | 語法 | 解釋 |
---|---|---|
主鍵約束 | PRIMARY KEY 或 PRIMARY KEY(列名1,列名2,…) | 主鍵是指能夠唯一代表一條記錄的鍵,可能是一列或多列的組合 |
非空約束 | NOT NULL | 這個列的值是否可以不填寫,系統默認可以不填寫 |
唯一性約束 | UNIQUE | 某一列的值是否必須不同,這個列是表的一個候選鍵但不是主鍵 |
默認值約束 | DEFAULT(默認值) | 輸入記錄的此列沒有賦值時,系統會自動使用默認值 |
檢查約束 | CHECK(表達式) | 檢查約束用於檢查列的值是否符合要求,比如是否在指定的范圍內 |
外鍵約束 | FOREIGN KEY | 反映兩個表之間的相互聯系,保證數據的唯一性 |
SQL 語句
創建表
建立表的 SQL 命令是 CREATETABLE,可以逐一將列名、數據類型、長度和列約束添加進來,還可以在命令的后面部分添加表約束。
CREATE TABLE 表名
(
列名 類型(長度){列約束}
[,…n]
[表約束]
)
SELECT INTO 子句
SELECT INTO 語句創建一個表,並在同一操作中往表里插入行。
創建約束
為表創建約束有兩種方法,一種是聲明當前列時,在數據類型后面直接加上約束內容,另一種方法是利用 CONSTRAINT 命令添加約束。第一種方法適合於比較簡單的約束,第二種單獨用一行命令完成,需要給出約束名,可以對約束進行修改、刪除等管理操作,但書寫要復雜一些。其格式是:
CONSTRAINT 約束名 約束內容
約束名是用戶定義的一個標識符,一般是“約束類型_表名_列名”這樣的格。約束類型通常用簡寫,PK 代表主鍵、UQ 表示唯一性約束、CK 代表檢查約束、FK 代表外鍵、DF 表示默認值約束。
刪除表
DROP TABLE 表名 [,…n]
添加、刪除和修改列
修改表結構的命令是 ALTER TABLE,其格式是:
ALTER TABLE 表名
{
ALTER COLUMN 列名 類型 [列約束]
ADD 列名 類型 [列約束]
ADD CONSTRAINT 約束名 約束內容
DROP COLUMN 列名
[,…n]
}
添加列時的各個選項和創建表時的列選項相同,向表中添加新列時 SQL Server 在列中為表中每個現有的數據行插入一個值。這個值為默認值或為 NULL,如果新列不允許空值,則 SQL Server 向其中插入空值時將返回錯誤。
ALTER TABLE 表名 ADD 列名 數據類型 [NULL | NOT NULL]
刪除列時,不能刪除正在復制的列、用在索引中的列、用在 CHECK、FOREIGN KEY、UNIQUE 或 PRIMARY KEY 約束中的列和與 DEFAULT 定義關聯或綁定到某一默認對象的列。
ALTER TABLE 表名 DROP 列名 [,…n]
修改列時,需要給出列名和需要修改的數據類型。
ALTER TABLE STU ALTER COLUMN 列名 數據類型
樣例
創建簡單表
選擇合適的數據類型,創建學生表、課程表、成績表。
CREATE TABLE STU
(
SNO CHAR(10) NOT NULL, --學號
SNAME VARCHAR(20), --姓名
DEPA VARCHAR(20),
AGE INT, --年齡
SEX NCHAR(1), --性別
TEL CHAR(11) --電話
)
CREATE TABLE CLASS
(
CNO CHAR(3) NOT NULL, --課程號
CNAME VARCHAR(20), --課程名
cpno char(3), --先修課程號
credit int --學分
)
CREATE TABLE SC
(
SNO CHAR(10) NOT NULL, --學號
CNO CHAR(10) NOT NULL, --課程號
GRADE DECIMAL(4,1) --成績
)
修改表
將創建簡單表樣例的 STU 增加聯系地址列,設置合適的類型。並把 sname 改為 nchar(4),最后刪除tel 列。
ALTER TABLE STU DROP COLUMN TEL
ALTER TABLE STU ALTER COLUMN SNAME NCHAR(4)
ALTER TABLE STU ADD ADDRESS CHAR(100)
創建帶約束的表
選擇合適的數據類型,創建學生表、課程表、成績表,並使用約束。
create table Student
(
Sno char(6) primary key check(Sno like'[1-9][0-9][0-9][0-9][0-9][0-9]'), --主鍵,學號為 6 位數字且第一位非 0
Sname varchar(20) UNIQUE, --姓名唯一
Ssex char(2) check(Ssex in('男', '女')), --性別為男或女
Sage int check(Sage > 0), --年齡大於 0
Sdept varchar(6) check(Sdept in('計算機','軟件','網絡','信息')) --專業為計算機、軟件、網絡、信息之一
)
create table Course
(
Cno char(4) primary key check(Cno like'[1-9][0-9][0-9][0-9]'), --主鍵,課程號為 4 位數字且第一位非 0
Cname varchar(10) not null, --課程名非空
Cpno char(4) foreign key references Course(Cno), --選修課課程號和 Cno 子段有外鍵約束
credit int default '2' --學分默認為 2
)
create table SC
(
Sno char(6) foreign key references Student(Sno) ON DELETE CASCADE ON UPDATE CASCADE, -- 主鍵,外鍵,當 Student 表中的學號修改或刪除時,自動修改或刪除;
Cno char(4) foreign key references Course(Cno) ON DELETE NO ACTION, -- 主鍵,外鍵,當有該課程成績時,禁止 Course 修改或刪除;
primary key(Sno,Cno),
Pscj decimal (4,1) check (Pscj>=0 AND Pscj<=100) default '0', --平時分,0 ~ 100,默認為 0 的一位小數
Qkcj decimal (4,1) check (Qkcj>=0 AND Qkcj<=100) default '0', --考試分,0 ~ 100,默認為 0 的一位小數
Zpcj as ((0.3)*[Pscj]+(0.7)*[Qkcj]) --最終得分
)
修改約束
修改表 STU 把 Sname 設為主鍵,同時保持 SC 的外鍵 Sno -> STU.Sno。由於原本的主鍵是 Sno,因此首先需要刪除 Sno 的主鍵。然而 Sno 和表 SC 具有外鍵約束關系,所以要刪除 SC 的 Sno 外鍵。
ALTER TABLE SC
DROP FK__SC__Sno__6FE99F9F
接着刪除主鍵 Sno 約束。
ALTER TABLE STU
DROP PK__STU__CA1FE4646F74CBE6
接着把 Sname 設為主鍵,不過 Sname 之前被設置為 unique,相當於存在主鍵約束。因此想要把 Sname 設為主鍵,就先要取消掉 unique。
ALTER TABLE STU
DROP UQ__STU__52723D2730EB7AE8;
此時由於 Sname 是可以為空的,然而主鍵不能為空,因此需要把 Sname 修改為 NOT NULL。
ALTER TABLE STU
ALTER COLUMN Sname VARCHAR(20) NOT NULL
現在可以把 Sname 設為主鍵了。
ALTER TABLE STU
ADD PRIMARY KEY(Sname)
由於還要保持 Sno 的 SC 和 STU 的外鍵關系,因此現在就把外鍵加回來。
ALTER TABLE SC
ADD FOREIGN KEY (Sno) REFERENCES STU(Sno)
由於外鍵的設置,需要 2 張表中的屬性要完全一致,而這時 STU 中的 Sno 字段已經不是主鍵和 SC 的Sno不一致。因此需要先將 STU 的 Sno 修改為 unique 才可以。
ALTER TABLE STU
ADD CONSTRAINT UN_Sname unique(Sno)
現在可以設置外鍵了。
ALTER TABLE SC
ADD FOREIGN KEY (Sno) REFERENCES STU(Sno)
SELECT INTO 創建
假設 Student 和 Score 已經有了一些數據,可以使用 SELECT 查出並通過 INTO 子句放入新表中。
SELECT * INTO Student2 FROM Student
SELECT * INTO Score2 FROM Score WHERE Degree < 0
INSERT Score2 SELECT * FROM Score
參考資料
《SqlServer 2014 數據庫技術實用教程》,胡伏湘、肖玉朝 主編,清華大學出版社