上篇文章,我們基於『數據庫』做了一個宏觀上的介紹,你應當了解到數據庫是在何種背景下,為了解決什么樣的問題而誕生的,以及在具體實現下又可以划分哪些中類型。
非關系型數據庫的種類很多,我們會在后續的篇章中進行介紹,數據庫這塊我們還是以目前當下主流的關系型數據庫進行學習。
SQL 是什么
我們看看
SQL(結構化查詢語言)是一種特定目的編程語言,用於管理關系數據庫管理系統(RDBMS),或在關系流數據管理系統(RDSMS)中進行流處理
簡而言之,SQL 是一門編程語言,它很特殊,它是一門幫助我們管理數據的標准語言。
為什么強調標准語言?
關系型數據的主要三大實現者分別是,Mysql,MS SQLServer,Oracle。
它們實現數據存儲的底層引擎或許不同,但提供出來管理數據的編程語言必須遵循 SQL 規范,但可以定制添加屬於自己的額外語法,這些額外的、SQL 之外的語法又被稱作它們各自的『SQL方言』。
記得遇到過很多新手,拿着 SqlServer 的方言跑到 Mysql 里去執行,怎么都報錯,怎么都解決不了。其實還是沒了解到這一層。
數據庫管理
一個數據庫系統里是可以同時存在多個數據庫的,也就是說一個數據庫引擎可以服務多個數據庫。
當你成功登陸數據庫系統之后,你可以通過這么一個命令查看系統中存在的數據庫集合。
SHOW DATABASES;
除此之外,你也可以創建數據庫,使用以下這個命令。
CREATE DATABASE [DATABASENAEM];
如果你想要刪除某個數據庫:
DROP DATABASE [DATABASENAEM];
如果你需要選中某個數據庫,這里說明一下,數據庫由多張數據表構成,如果你想要操作數據表,你就必須先選中某個數據庫,不然系統怎么知道你這一頓猛如虎的操作是基於的哪個數據庫下的表呢。
USE[DATABASENAEM];
數據庫的管理其實沒什么太復雜的,它就像一個容器一樣,創建后就意味着占有了一塊磁盤空間,具體的數據存儲還是在表結構中,所以接下來我們來看看數據庫表管理情況。
表管理
關系型數據庫中對於數據的存儲采用一種符合人的思維邏輯的結構進行存儲,那就是表格結構。
表格是一個二維的結構,有行和列,我們管一行數據叫做『一條記錄』或是『一條數據』,每一列都是一條數據的一部分,我們管某一列的數據叫做『字段』,在數據庫中它們可以具有不同的數據類型。
SQL 規范了以下一些通用的數據類型:
但是實際上,SQLServer,Oracle,MySQL 等數據庫的具體實現上也大多都支持這些類型,只不過在不同的數據庫中,同一種數據類型可能有不同的名稱。
舉個例子吧,數據類型 Integer,在 Oracle 里使用 Number 描述,SQLServer 里使用 int 來描述,而 MySQL 里既可以使用 int 也可以使用 Integer 進行描述。
所以,在我看來,既然大家都不是那么遵守規范,那么就沒必要謹記規范,你用到哪個數據庫,你去了解他的數據類型就是了。
我以 MySQL 來說,他主要的數據類型大致可以分為三類,Text(文本)、Number(數字)和 Date/Time(日期/時間)。
Text 類型:
Number 類型:
Date 類型:
有了數據類型,我們的列也就有了類型約束了,也即限定了每一列該存放什么類型的數據,那么我們的表結構也就由此確定了。
現在我們來看看如何在一個數據庫中創建一張表:
CREATE TABLE table_name(
column1 datatype,
column2 datatype,
column3 datatype,
.....
columnN datatype
);
這是最基本的創建表語句,例如我們可以這樣創建一張表:
CREATE TABLE person(
id int,
name varchar(16),
phone char(11),
);
當然,這種方式創建的表結構還是太簡單了,現實中我們的字段往往具有更加嚴格的約束。
1、NULL 非空約束
NULL 約束用來指定當前字段的值是否允許為空,這里的空並不是空字符串,空格字符串,而是未對該字段賦值就判定為空。
create table person(
id,int NOT NULL,
uName,varchar(16) NOT NULL,
phone,char(11) NUll
)
NULL 則指定該字段的值可以為空,NOT NULL 指定該字段不可以為空。
2、DEFAULT 默認約束
DEFAULT 約束用於指定某一列在允許為 NULL 的前提下,如果在插入數據時未賦值該字段時,數據庫統一賦的默認值。
create table person(
id int DEFAULT 12,
uName VARCHAR(16)
)
當我們向表 person 插入數據時,如果你不為 id 字段賦值,那么該條數據記錄的 id 值就會是 12 。
3、UNIQUE 唯一約束
UNIQUE 約束用於限制表的某一字段不可重復,也即唯一,一張表中可以有很多記錄,每條記錄的該字段的值必須各不相同。
create table person(
id int,
uName VARCHAR(16) UNIQUE
)
這樣,無論你向 person 表中插入多少條數據記錄,uName 這個字段的是必須各不相同,也即當你嘗試向 person 表插入一條數據時,如果檢測到你將要插入的這條數據的 uName 字段的值在表中已知記錄中存在,你將不能成功插入。
4、PRIMARY KEY 主鍵約束
『主鍵』就是能夠唯一確定一條具體數據記錄的一個或多個字段的組合,也就是說,主鍵是表數據中一行記錄的標記,通過它可以唯一定位到一行數據記錄。
它與我們的 UNIQUE 看起來是一樣的,我們可以通過 UNIQUE 指定表的一個或多個字段唯一不可重復,看似 UNIQUE 也可以唯一確定一行數據?
但時,UNIQUE 是不能唯一確定一行數據的,那是因為 UNIQUE 對空值無法約束。
你不讓我將字段的值賦值為表中已知行數據的該字段值,那我可以不賦值,該字段的值為空。
所以,存在一種情況就是,已經對表的某一字段進行了 UNIQUE 約束,但時表中大量行數據的該字段值為空,你還能通過該字段唯一確定一行嗎?
有人認為我們的主鍵約束就等同於 UNIQUE + NOT NULL 兩個約束的集合,但其實我認為這並不准確,因為有時我們的主鍵可以由多個字段共同構成,只要他們組合起來能夠唯一確定一行數據,單個字段是否遵守上述兩個約束就成為非必要條件了。
例如:我有一張 person 表,里面保存了很多數據,已知可以通過姓名的手機號碼唯一確定一條數據,那么我們的主鍵就是姓名和手機號碼兩個字段的組合,而至於姓名是否唯一,是否允許為空,我們不需要關心。
這其實就是主鍵約束和 UNIQUE 約束的一個主要的區別所在,你只要記住主鍵是用於唯一確定一行數據的,UNIQUE 用於約束某一字段的值不可重復出現。
關於主鍵約束的語法,
create table person(
id int primary key,
uName varchar(16)
)
如果需要多個字段組合構成主鍵,語法是這樣的:
create table person(
id int,
uName varchar(16),
primary key(id,uName)
)
5、FOREIGN KEY 約束
最后我們講講外鍵約束,關系型數據庫的一個核心特點就是表與表之間可以存在關系,而如何關聯到另外一張表呢?這就用到一個鍵叫『外鍵』,兩張表之間的微妙關系我們可以叫做外鍵約束。
舉個例子吧,自己畫圖太丑,網上隨便找的表結構示意圖:
這里涉及到兩張表,第一張訂單表記錄交易記錄數據,其中也需要記錄下創建這筆訂單的消費者,一種做法是把 persons 表中的所有字段重新定義一遍,追加到 Orders 表中,這顯然繁瑣、字段冗余。
另一種做法就是我只增加一個字段,該字段存儲的值是 persons 表的主鍵,也就是當我需要關聯到某一個具體的 person 時,我只保存它的主鍵值,而不去保存它所有的字段信息,因為我是可以通過主鍵值定位到 persons 表的某條具體數據的。
上述示例中,我們管訂單表中的 Id_P 字段叫做『外鍵』,它其實又是 persons 表的『主鍵』。
因此,構建一個外鍵約束,可以使用如下語法:
CREATE TABLE Orders
(
Id_O int NOT NULL,
OrderNo int NOT NULL,
Id_P int,
PRIMARY KEY (Id_O),
FOREIGN KEY (Id_P) REFERENCES Persons(Id_P)
)
前提是,Persons 表已經存在,否則將創建 Orders 表失敗。
以上,我們講了創建表所涉及到的一些基本的內容,包括基本的字段類型、約束限制等,
但有的時候,表結構已經創建出來了,由於一些需求變更需要更改表結構,我們總不能 drop table 再重新定義一遍吧,SQL 規范中也提供了動態修改表結構的語句語法,我們一起來看看:
1、為表新增列
ALTER TABLE [tableName] ADD [columName] [列數據類型]
例如:
alter table person add email varchar(24)
為 person 表新增一列 email,varchar 類型。
2、修改表列屬性
列屬性包括,列名、列數據類型,我們分別來看下修改它們的 SQL 語法。
修改列名:
alter table 表名 change column 舊列名 新列名 新列名格式;
例如:
alter table person change column uName userName varchar(123)
修改列數據類型:
MySQL:
alter table 表名 modify column 列名 列類型
例如:
alter table person modify column userName varchar(16)
SQLServer:
alter table 表名 alter column 列名 列類型
修改數據類型這塊,各個應用數據庫實現語法稍有差異,但僅限於關鍵字不同,格式上大體相似。
3、刪除列
alter table 表名 drop column 列名
例如:
ALTER TABLE person DROP COLUMN email
刪除 person 表列 email。
關於表的刪除,就更加簡單了:
drop table 表名
注意,這里的表刪除是連同表結構加表數據全部刪除,謹慎使用。
關於表管理,大體上就介紹到這,看似很多,但實際上並沒有什么特別復雜的點,無非是創建、刪除、修改表。
創建表的時候可以同時指定約束,修改表結構又分為修改列名和修改列的數據類型,而同時我們要小心謹慎使用 drop 刪除表。
雖然本篇寫很多,但並未涉及到復雜的 SQL 語句,僅限於簡單的創建 DDL 語句,下一篇我們看較為復雜的 DML 語句,進一步了解 SQL 對表的增刪改查。