文章主要分為以下兩個部分:
- 數據庫分類
- MySQL 基礎
數據庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫,每個數據庫都有一個或多個不同的 API 用於創建,訪問,管理,搜索和復制所保存的數據。相對於文件存儲數據,數據庫中存儲數據效率更高。
結構化查詢語言(Structured Query Language)簡稱 SQL,是上世紀 70 年代由 IBM 公司開發,用於對數據庫進行操作的語言。用於存取數據以及查詢、更新和管理數據庫系統,同時也是數據庫腳本文件的擴展名。
數據庫分類
目前數據庫主要分為傳統的關系型數據庫(SQL)和非關系型數據庫(NoSQL),還有最近幾年出現的 NewSQL 新型數據庫、分布式數據庫等。
關系型數據庫
關系型數據庫把數據以表的形式進行存儲,然后在各個表之間建立聯系,通過表之間的關系來操作不同表之間的數據。
關系型數據庫依據關系模型來創建數據庫,關系模型是指“一對一,一對多,多對多”,通過關系模型來構建二維表格。
- 一對一:身份證號,校園卡
- 一對多:班級-學生,部門-職員
- 多對多:課程-學生,書籍-作者
常見的關系型數據庫有 MySQL,Oracle,MariaDB,SqlServer,Access,PostgreSQL 等。
優點:
- 數據安全,數據一致性
- 二維表結構直觀,易理解
- 使用 SQL 語句操作非常方便,可用於比較復雜的查詢
缺點:
- 讀寫性能較差
- 不擅長處理較復雜的關系
非關系型數據庫
傳統的關系型數據庫因為無法支持大規模數據和訪問量而成為整個系統的瓶頸,非關系型數據庫的關鍵在於放棄了傳統關系型數據庫的強事務保證和關系模型,通過所謂最終一致性和非關系數據模型(例如鍵值對,圖,文檔)來提高 Web 應用所注重的高可用性和可擴展性。
NoSQL 沒有固定的表結構,其數據之間不存在表與表之間的關系,數據之間可以是獨立的,因此 NoSQL 可以用於分布式系統上。
NoSQL 大致可以分為四種:
| 分類 | 數據模型 | 優勢 | 舉例 |
|---|---|---|---|
| 鍵值數據庫(key-value) | 哈希表 | 查詢快,易部署,高並發 | Redis,Memcached |
| 列存儲數據庫 | 列式數據存儲 | 查詢快,數據壓縮率高,不需要額外建立索引 | HBase,Cassandra |
| 文檔型數據庫 | 鍵值對擴展 | 將數據以文檔的形式存儲,數據結構不定 | MongoDB,CouchDB |
| 圖數據庫 | 節點和關系組成的圖 | 利用圖結構的相關算法 | Neo4j,JanusGraph |
鍵值數據庫
鍵值數據庫類似於傳統語言中使用的哈希表,通過 key 來添加、刪除、查詢數據。因為使用 key 主鍵來訪問,所以鍵值數據庫具有很高的性能及拓展性。
例如 Redis,由於其數據是存儲於內存,讀寫速度非常快。Redis 在一秒內讀寫可以超過十萬個鍵值。它雖然是作為數據庫來開發的,現在更廣泛的應用於緩存、消息隊列。

列存儲數據庫
列存儲數據庫將數據存儲在列族中,一個列族存儲經常被查詢的相關數據。
列存儲數據庫主要用於海量數據分析。在進行數據分析時,通常只會查詢表中的一列或幾列,這時只需要把這幾列拿出來就可以了,不需要查詢的不關心,大大提高了檢索效率。列存儲數據庫每一列存儲的數據類型相同,壓縮率較高。

文檔型數據庫
文檔型數據庫與鍵值數據庫是類似的,只不過將數據用文檔的形式存儲,數據存儲可以是 XML, JSON 等多種形式。

圖數據庫
圖數據庫將數據以圖的方式存儲。實體作為頂點,實體之間的關系作為邊。圖模型比較靈活,可以拓展到多個服務器上,圖數據庫沒有標准的查詢語言。
圖數據庫一般用於推薦系統,處理社交網絡等等。

MySQL 基礎
MySQL 是流行的關系型數據庫管理系統,在 WEB 應用方面 MySQL 是最好的 RDBMS (Relational Database Management System:關系數據庫管理系統)應用軟件之一。MySQL 使用 SQL 語言進行操作。
前置知識
配置文件 /etc/my.cnf

該文件默認配置如下:

登錄
mysql -uroot -p
******** # 輸入密碼
# 退出
mysql>exit/quit
管理數據庫
# 查看數據庫
SHOW DATABASES;
# 使用數據庫
USE 數據庫名;
# 查看數據庫中表名
SHOW TABLES;
# 查看表中列名
SHOW COLUMNS FROM 數據表名;
數據類型
MySQL 支持多種類型,大致可以分為三類:數值,日期/時間和字符串類型。
數值類型
| 數據類型 | 大小(字節) | 用途 |
|---|---|---|
| INT | 4 | 整數 |
| FLOAT | 4 | 單精度浮點數 |
| DOUBLE | 8 | 雙精度浮點數 |
日期時間類型
| 類型 | 大小(字節) | 用途 | 格式 |
|---|---|---|---|
| DATE | 3 | 日期 | YYYY-MM-DD |
| TIME | 3 | 時間至或持續時間 | HH:MM:SS |
| YEAR | 1 | 年份值 | YYYY |
| DATETIME | 8 | 混合日期和時間值 | YYYY-MM-DD HH:MM:SS |
字符串類型
| 類型 | 大小(字節) | 用途 | 格式 |
|---|---|---|---|
| CHAR | 0-255 | 定長字符串 | |
| VARCHAR | 0-65535 | 變長字符串 | |
| BLOB | 0-65535 | 二進制行形式的長文本數據 | |
| TEXT | 0-65535 | 長文本數據 | |
| ENUM | -- | 單選,比如性別 | ENUM('a','b','c') |
| SET | -- | 多選 | SET('1','2','3') |
CHAR 和 VARCHAR 的區別:CHAR 的長度是固定的,而 VARCHAR 的長度是可以變化的。比如,存儲字符串 “abc”,對於 CHAR(10),表示存儲的字符將占 10 個字節(包括 7 個空字符),而同樣的 VARCHAR(12) 則只占用 4 個字節的長度,增加一個額外字節來存儲字符串本身的長度,12 只是最大值,當存儲字符小於 12 時,按實際長度。
EMUN 和 SET 的區別:EMUN 類型的數據的值,必須是定義時枚舉的值的其中之一,即單選,而 SET 類型的值可以多選。
約束
約束是一種限制,通過對表的行或列的數據做出限制,來確保表的數據完整性、唯一性。
比如規定一個用戶的用戶名不能為空值且沒有重復的記錄,這就是一種約束
在 MySQL 中,通常有這幾種約束:
| 約束類型 | 主鍵 | 默認值 | 唯一 | 外鍵 | 非空 |
|---|---|---|---|---|---|
| 關鍵字 | PRIMARY KEY | DEFAULT | UNIQUE | FOREIGN KEY | NOT NULL |
- 主鍵:數據表中的一行數據的唯一標識符,不能重復記錄且不能為空
- 默認值:當有 DEFAULT 約束的列,插入數據為空時,將使用默認值
- 唯一:規定一張表中指定的一列的值必須不能有重復值
- 外鍵:確保數據完整性,每個外鍵必須參考另一個表的主鍵,被外鍵約束的列,取值必須在它參考的列中有對應值
- 非空:在插入值時必須非空
基本操作
創建數據庫
CREATE DATABASE 數據庫名;
創建數據表
CREATE TABLE 數據表名(
字段1 數據類型(數據長度)
字段2 數據類型(數據長度)
);
增加
往數據表中插入數據
INSERT INTO 數據表名(字段1,字段2) VALUES(值1,值2);
演示:創建一個 test 庫,含有一個 students 數據表,往表中插入 id, name, gender, birth等信息,結果如下。

如果在插入中文時出錯,可以在創建數據表時將編碼方式設置為 utf8。
CREATE TABLE student(
id int(10),
name char(20),
gender enum('男','女'),
birth date,
age int(5),
city varchar(20)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
查詢
SELECT 語句的基本格式為:
SELECT 列名 FROM 表名 WHERE 限制條件
限制條件
- 比較條件:=, <, >, <=, >=
- 邏輯條件:AND, OR
- 范圍:IN, NOT IN
- 通配符:LIKE 用於實現模糊查詢,常見於搜索功能。
_代表一個未指定字符,%代表不定個未指定字符。 - 排序:ORDER BY 字段 (ASC/DESC) 升序或降序,默認為升序
內置計算函數
5 個內置函數:
| 函數名 | COUNT | SUM | AVG | MAX | MIN |
|---|---|---|---|---|---|
| 作用 | 計數 | 求和 | 求平均 | 最大值 | 最小值 |
其中 COUNT 函數可用於任何數據類型,而 SUM, AVG 函數都只能對數字類型數據做計算,MAX 和 MIN 可用於數值,字符串或是日期時間數據類型
select MAX(salary) AS max_salary,MIN(salary) FROM employee;

修改和刪除
MySQL 沒有提供修改數據庫名稱的方法,因為這曾導致一系列安全問題。比較安全的做法是重新建一個新庫,然后將舊庫中的數據轉移到新庫中,並且暫時不要刪除舊的數據庫,以防數據遺失。
刪除數據庫
DROP DATABASE 數據庫名;
重命名表名
RENAME TABLE 原名 TO 新名字;
ALTER TABLE 原名 RENAME 新名;
ALTER TABLE 原名 RENAME TO 新名;
刪除表
DROP TABLE 表名字;
表結構修改
增加一列——ALTER ... ADD
ALTER TABLE 表名字 ADD COLUMN 列名字 數據類型 約束;
ALTER TABLE 表名字 ADD 列名字 數據類型 約束;

ALTER TABLE emplouyee add height int(10) default 170;
結果如下

新增加的列,被默認放置在表的最右邊,如果要指定插入的位置,可以使用 AFTER 關鍵字;如果想放在第一列的位置,則使用 FIRST 關鍵字,如語句
ALTER TABLE employee ADD weight INT(4) DEFAULT 120 AFTER age;
ALTER TABLE employee ADD test INT(4) DEFAULT 11 FIRST;
刪除一列——ALTER ... DROP
ALTER TABLE 表名字 DROP COLUMN 列名字;
ALTER TABLE 表名字 DROP 列名字;
重命名一列——ALTER ... CHANGE
ALTER TABLE 表名 CHANGE 原列名 新列名 數據類型 約束;
原列名和新列名相同時可以用於修改數據類型,修改數據類型可能會導致數據丟失,所以要慎重使用。
ALTER TABLE employee CHANGE height shengao INT(4) DEFAULT 170;
修改數據類型——ALTER ... MODIFY
ALTER TABLE 表名字 MODIFY 列名字 新數據類型;
修改表中某個值——UPDATE ... SET ... WHERE
UPDATE 表名字 SET 列1=值1,列2=值2 WHERE 條件;
例:
UPDATE employee SET age=21,salary=3000 WHERE name='Tom';
注意:一定要有 WHERE 條件,否則會出現你不想看到的結果
刪除一行記錄——DELETE ... WHERE
DELETE FROM 表名 WHERE 條件;
例:
DELETE FROM emplyee WHERE name='Tom';
其他
索引
在表中建立索引,在在、索引中找到符合查詢條件的索引值,通過索引值可以快速找到表中的數據,可以大大加快查詢速度。
建立索引格式
ALTER TABLE 表名字 ADD INDEX 索引名 (列名)
CREATE INDEX 索引名 ON 表名 (列名)
例:
ALTER TABLE employee ADD INDEX idx_id (id);
CREATE INDEX idx_name ON employee (name);
使用 SHOW INDEX FROM 表名 查看新建的索引。
視圖
視圖是從一個或多個表中導出來的表,是一種虛擬存在的表。
- 數據庫中只存放了視圖的定義,沒有存放視圖中的數據,這些數據存放在原來的表中
- 使用視圖查詢數據時,數據庫系統會從原來的表中去除對應是數據
- 視圖中的數據依賴於原來表中的數據,一旦表中的數據發生改變,顯示在視圖中的數據也會發生改變
- 在使用視圖時,可以把它當做一張表
格式:
CREATE VIEW 視圖名(列1,列2) AS SELECT 列1,列2 FROM 表名;
例子
CREATE VIEW v_emp (v_name,v_age,v_phone) AS SELECT name,age,phone FROM employee;
SELECT * FROM v_emp;

導入
導入 .sql 文件,在 MySQL 交互界面執行如下命令
source 文件路徑/test.sql;
導入純數據文件,把文件中得到數據保存到表中
LOAD DATA INFILE '文件路徑和文件名' INTO TABLE 表名;
導入導出屬於敏感操作,根據 MySQL 的安全策略,導入導出文件都必須在指定的路徑下進行,在 MySQL 中查看路徑變量
show variables like '%secure%'

指定安全路徑為 /var/lib/mysql-files,將要導入的數據文件移動到安全路徑下。
查看 in.txt 文件內容
sudo vim /var/lib/mysql_files/SQL6/in.txt

在 MySQL 中查看沒導入數據之前 employee 表的內容

執行導入語句,結果如下
LOAD DATA INFILE '/var/lib/mysql-files/SQL6/in.txt' INTO TABLE employee;

導出
導出與導入是相反的過程,是把數據庫某個表中的數據保存到一個文件之中。
格式
SELECT 列1,列2 INTO OUTFILE '文件路徑和文件名' FROM 表名;
注意文件路徑之下不能有同名文件。
SELECT * INTO OUTFILE '/var/lib/mysql-files/out.txt' FROM employee;

備份
備份與導出的區別:導出的文件只是保存數據庫中的數據;備份則是把數據庫的結構,包括數據,約束,索引,視圖等全部另存為一個文件。
mysqldump 是用於備份數據庫的使用程序,主要產生一個 sql 腳本。
# 在終端中執行,不是 mysql 環境下
mysqldump -u root 數據庫名>備份文件名; # 備份整個數據庫
mysqldump -u root 數據庫名 表名>備份文件名; # 備份整個表
備份整個數據庫 mysql_shiyan,將備份文件命名為 bak.sql
mysqldump -u root mysql_shiyan > bak.sql

成功創建備份文件。
恢復
新建一個新的空數據庫 test
mysql> CREATE DATABASE test;
退出交互界面
mysql -u root test < bak.sql
總結
之前對數據庫的分類不了解,不清楚關系型數據庫與非關系型數據庫的區別,這次練習,因為是主動學習的過程,主動去了解關系型數據庫的特點,非關系型數據庫的分類,所以還是有很大的收獲。
對數據庫的操作練習,也加強了自己對數據庫的理解,但感覺自己還是不夠熟練,還需繼續加油!
