1. 程式人生 > >1.偏頭痛楊的mysql教學系列之基礎概念篇

1.偏頭痛楊的mysql教學系列之基礎概念篇

前戲

mysql是目前最流行的關係型資料庫之一,在阿里前幾年的去IOE化後整風運動後,
mysql從中小型資料庫解決方案成長為了大型網際網路應用關係型資料庫解決方案的中流砥柱。
因為mysql免費且開源,還可以無限擴充套件成N個數據庫叢集,玩分庫分表。

MYSQL可以與很多技術結合使用,彰顯巨大威力。
例如:memcached、redis、mycat、druid、mongodb等等等等。

mysql是一個關係型資料庫管理系統,被SUN公司收購,後又被Oracle收購。



什麼是資料庫?

資料庫就是用來儲存和讀取資料的地方。我們可以對資料進行增刪改查等操作,
當然,資料也可以不儲存在資料庫中,那麼可以儲存在什麼地方?

例如可以儲存在記憶體中,DVD中,excel中,硬碟的某個檔案中等等。
那為什麼非得要儲存在資料庫中呢?因為專人專事,
用最專業的軟體幹最專業的事情。

我們的程式需要對資料庫中的資料進行增刪改查等業務操作,
很多業務邏輯都是建立在資料庫的基礎之上衍生而來,
是網際網路應用中必不可少的元件。
所謂關係型資料庫是建立在關係模型基礎上的資料庫,
例如一對一關係,一對多,多對多等等。

一些核心概念

概 念 別 名 描述
例項 instance 部署在某個節點上的mysql服務,一個例項上可以建多個庫。
database 最大的邏輯儲存單元,庫是一些表的集合。
table 表是資料的矩陣,表有點像一個電子表格,表是儲存資料的邏輯單元,以行和列的形式存在;列就是欄位,行就是記錄。
column 一列包含了相同的資料, 例如郵政編碼的資料。
row 一行是一組相關的資料,例如一條使用者訂閱的資料。
主鍵 primary key 主鍵是唯一的。一個數據表中只能包含一個主鍵。你可以使用主鍵來查詢資料。
外來鍵 foreign key 外來鍵用於關聯兩個表,很多廠禁止使用物理外來鍵。
索引 index 使用索引可快速訪問資料庫表中的特定資訊。索引是對資料庫表中一列或多列的值進行排序的一種結構,類似於書籍的目錄。
資料字典 schema 系統表,存放資料庫相關資訊的表,系統表裡的資料通常由資料庫系統維護,程式設計師不應該手動修改系統表以及內部資料,程式設計師可以檢視系統表的資料。
約束 constraint 執行資料校驗的規則,用於保證資料的完整性的規則。
檢視 view 一個或多個數據表裡資料的邏輯顯示,檢視並不儲存資料。
索引 index 用於提高查詢效能,相當於書的目錄。
函式 function 用於完成一次特定的計算,具有一個返回值。
儲存過程 procedure 用於完成一次完整的業務處理,沒有返回值,但可以通過傳出引數將多個值傳給呼叫環境。
觸發器 trigger 相當於一個事件監聽器,當資料庫發生特定事件後,觸發器被觸發,完成相應的處理。

注意:大中型網際網路專案中禁止使用觸發器、儲存過程、檢視等資料物件以提升資料庫效能。



表與表之間的關係

在mysql中,表與表之間是有關係的,就好像人與人之間也有關係一樣,
人與人的關係可以是同學,朋友,親人,戀人,陌生人等等。
表與表之間的關係分為:一對一,一對多,多對多,多對多,
所謂的關係型資料庫,關係~

一對一

A表的一條資料對應B表的一條資料。
一對一又分為:雙向主鍵一對一,特殊一對多等情況。

一對多

A表的一條資料對應B表的多條資料。
(記住一個關於entity bean的口訣,一方有多方的集合,多方有一方的ID。)
在B表中應該有一個欄位儲存A表記錄的id。

多對一

A表的多條資料對應B表的一條資料。
在A表中應該有一個欄位儲存B表記錄的id。

多對多

A表的一條資料對應B表的多條資料,B表的一條資料對應A表的多條資料。
多對多關係比較要建立一張中間表,中間表中要有兩張表的主鍵作為聯合主鍵。



列型別

建表時需要指定每列的資料型別,
一般情況下,我們不會往資料庫存大物件資料、列舉、集合,
值得一提的是,mysql的整型型別資料的length是不起作用的,整型長度跟表數範圍走。

列型別 說明
tinyint/smallint/mediumint/int/bigint 1/2/3/4/8位元組整數,又可分為有符號和無符號兩種,這些整數型別的區別僅僅是表數範圍不同。
float/double 單精度/雙精度浮點型別
decimal 精確小數型別,相對於float和double不會產生精度丟失的問題。
date 日期型別,不能儲存時間。
time 時間型別,不能儲存日期。
datetime 日期時間型別。
timestamp 時間戳型別。
year 年型別,僅僅儲存時間的年份。
char 定長字串型別。
varchar 可變長度字串型別。
binary 定長二進位制字串型別,他以二進位制形式儲存字串。
varbinary 可變長度二進位制字串型別,他以二進位制形式儲存字串。
tinyblob/blob/mediumblob/longblob 1/2/3/4位元組的二進位制大物件,可用於儲存圖片,音樂等二進位制資料,分別可儲存255B/64KB/16MB/4GB大小的資料,但通常不把檔案儲存在資料庫中,而是儲存在檔案伺服器,在資料庫中儲存檔案的地址即可。
tinytext/text/mediumtext/longtext 1/2/3/4位元組的文字物件,可用於儲存超長長度的字串,分別可儲存255B/64KB/16MB/4GB大小的文字。
enum(‘a’,‘b’) 列舉型別,該列的值只能是enum後括號內多個值的其中之一。該型別比較少用,詳情請搜尋mysql enum is evil.
set(‘a’,‘b’) 集合型別,該列的值可以是set後括號內多個值得其中幾個。


資料庫約束

約束是在表上強制執行的資料校驗規則,約束主要用於保證資料庫裡資料的完整性。
除此之外,當表中的資料存在相互依賴性時,可以保護相關的資料不被刪除。
約束也是資料庫物件,並被儲存在系統表中,擁有自己的名字,約束分單列約束和多列約束。

約束可以在建表時以及建表後通過ALTER命令建立。
mysql使用information_schema庫裡的TABLE_CONSTRAINTS來儲存約束資訊。

NOT NULL約束

非空約束,指定某列不能為空。
注意事項:

  1. null不是空字串,也不是0;
  2. 當插入一個數據,該資料的所屬列是非空列且設定了預設值時,
    如果insert語句沒有顯式的寫出這個列則會插入成功,如果insert語句顯式的寫了這個列,該資料又是null資料時,則會插入失敗;
  3. 建議表中所有的欄位都設定成非空的,這樣有利於效能;
CREATE TABLE t_user(
  user_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT '使用者ID主鍵',
  user_name VARCHAR(20) DEFAULT '' COMMENT '使用者名稱稱'
) COMMENT='使用者表';

ALTER TABLE t_user MODIFY user_name VARCHAR(20) NOT NULL;

#取消非空約束
ALTER TABLE t_user MODIFY user_name VARCHAR(20) NULL;

UNIQUE約束

唯一約束,指定某列或者幾列組合不能重複,但允許出現多個NULL值。
建立唯一約束後,mysql會自動為其建立唯一索引,預設約束名等於列名

CREATE TABLE t_user(
  user_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT '使用者ID主鍵',
  user_name VARCHAR(20) UNIQUE DEFAULT '' COMMENT '使用者名稱稱'
) COMMENT='使用者表';

#兩列的組合不能有重複
CREATE TABLE t_user_info(
  user_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT '使用者ID主鍵',
  user_name VARCHAR(20) DEFAULT '' COMMENT '使用者名稱稱',
  user_age INT(2) COMMENT '使用者年齡',
  CONSTRAINT test_unique UNIQUE(user_name,user_age)
) COMMENT='使用者表';

ALTER TABLE t_user_info ADD UNIQUE(user_name,user_age);
ALTER TABLE t_user_info MODIFY user_age INT(2) UNIQUE;

#刪除約束
ALTER TABLE t_user_info DROP INDEX user_age;

PRIMARY KEY約束

主鍵,指定該列的值可以唯一的標識該條記錄,相當於非空約束+唯一約束。
mysql會自動為其建立唯一索引,允許為多列建立組合主鍵約束。
一張表最多隻能有一個主鍵,主鍵是表中能夠唯一確定一行記錄的欄位或欄位組合。
一旦設定了AUTO_INCREMENT則表示整型欄位自增,由資料庫自動維護該欄位。

CREATE TABLE t_user(
  user_id INT AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT '使用者ID主鍵',
  user_name VARCHAR(20) UNIQUE DEFAULT '' COMMENT '使用者名稱稱'
) COMMENT='使用者表';

#多列組合索引
CREATE TABLE t_user(
  user_id INT NOT NULL COMMENT '使用者ID主鍵',
  user_name VARCHAR(20) UNIQUE DEFAULT '' COMMENT '使用者名稱稱',
  PRIMARY KEY(user_id,user_name)
) COMMENT='使用者表';

#刪除主鍵
ALTER TABLE t_user DROP PRIMARY KEY;

ALTER TABLE t_user ADD PRIMARY KEY(user_id,user_name);

FOREIGN KEY約束

外來鍵,指定該行記錄從屬於主表中的一條記錄,主要用於保證參照完整性。
從表外來鍵參照的只能是主表主鍵列或者唯一鍵列,同一個表內可以有多個外來鍵,
建立外來鍵約束時,mysql會為該列建立索引。外來鍵多用於一對一,一對多,多對多關係。

當主表記錄被從表記錄參照時,主表記錄不允許刪除,必須要先刪除對應的從表資料。
也可以設定級聯刪除:
on delete cascade (級聯刪除)
on delete set null (級聯設定為null)

由於各大網際網路公司全部禁用物理外來鍵,使用邏輯外來鍵,因此不再展開。

檢視

檢視看上去非常像一個數據表,但它不是資料表,因為它並不能儲存資料。
檢視只是一個或多個數據表中資料的邏輯顯示。檢視的本質就是一條被命名的sql查詢語句。
一旦檢視被建立後就跟查詢普通資料表沒什麼區別了。

檢視的優點如下:
1、可以限制對資料的訪問。
2、可以使複雜的查詢變得簡單。
3、提供了資料的獨立性。
4、提供了對相同資料的不同顯示。

==由於各大網際網路公司全部禁用檢視,因此不再展開。 ==

資料字典&系統表&元資料表

每個資料庫例項都會具有一個數據庫字典information_schema
(又稱系統表、元資料表metadata),
用於儲存資料物件資訊以及其他系統級的資訊。
當資料庫表建立成功後,mysql使用information_schema資料庫裡的
tables表來儲存該資料庫例項中的所有資料表,
使用者可以通過查詢TABLES表來獲取該資料庫的表資訊。

表:tables
資料庫資訊:schemata
檢視:views
列資訊:columns
觸發器資訊:triggers
儲存過程+函式:routines
約束:tables_constraints
所有約束的鍵資訊:key_column_usage
索引:statistics

總結

今天我們學習了一些mysql的基礎知識,讓大家有一個感性的認識,
其中庫、表、行、列這四個概念最為核心,是必須要掌握的知識點。
並且許多場景下,做業務系統時,都需要先對資料庫建模,
因此學好mysql成為了一項必須通關的遊戲。