參考資料
慕課網——與MySQL的零距離接觸
前言
本人菜鳥,入IT只為當鼓勵師。本編文章主要對 MySQL的一些基礎知識進行總結。
一、常用服務指令
1. 啟動和停止MySQL服務
-
啟動:
net start [mysql服務名]
-
停止:
net stop [mysql服務名]
net start / net stop
Windows服務
2. MySQL的登錄與退出
-
登錄:
mysql -uroot -p -P3306 -h127.0.0.1
(端口:3306,IP:127.0.0.1)
登錄與退出
3. 創建新用戶
腳本:CREATE USER 'username'@'host' [IDENTIFIED BY 'PASSWORD'];
其中密碼是可選項。
例子:CREATE USER 'john'@'192.168.189.71' IDENTIFIED BY "123456";
這樣就創建了一個用戶(用戶名:john,密碼:123456,該用戶只能在IP地址為192.168.189.71的內網機子上訪問操作數據庫。若host為localhost,則該用戶只能在本地登錄,不能在另外一臺機器上遠程登錄。如果想遠程登錄的話,將localhost改為%,表示在任何一臺電腦上都可以登錄。也可以指定某臺機器可以遠程登錄)。
4. 修改MySQL提示符
-
示例:(賬號:root ,密碼:root )
C:\Users\JIN>mysql -uroot -proot --prompt \h
localhostprompt \h>
PROMPT set to ‘\h>’
localhost>prompt \u#\h \d \D >
PROMPT set to ‘\u#\h \d \D > ‘
root#localhost (none) Thu Dec 08 21:15:08 2016 >
5. 用SELECT顯示當前信息
語句規范:
**1. **關鍵字與函數名稱全部大寫。
**2. **數據庫名稱、表名稱、字段名稱全部小寫。
**3. **SQL語句必須以分號結尾。-
SELECT指令:
SELECT VERSION();
:顯示當前服務器版本。
SELECT NOW();
:顯示當前日期時間。
SELECT USER();
:顯示當前用戶。
SELECT指令示例
二、數據庫
1. 數據庫的操作
1-1. 創建數據庫
CREATE {DATABASE| SCHEMA} [IF NOT EXISTS] db_name [DEFAULT] CHARACTER SET [=] charset_name(編碼方式)
-
基本指令
CREATE DATABASE db_name;
:
顯示Query OK后,可用SHOW DATABASES;
指令顯示已成功創建出名為test的數據庫:
CREATE DATABASE test; -
可選參數
IF NOT EXISTS
:
若再次嘗試創建已存在的數據庫,系統會報錯(error)。若加了可選參數IF NOT EXISTS
,系統不會報錯,取而代之的是把原本的錯誤放到警告(warning)中,可用SHOW WARNINGS;
查看所有的警告:
IF NOT EXISTS -
可選指令
CHARACTER SET [=] charset_name(編碼方式)
:
顯示Query OK后,可用SHOW CREATE DATABASE db_name;
查看某個庫使用的編碼方式:
CHARACTER SET gbk;
1-2. 打開數據庫
USE db_name(數據庫名稱);
- 顯示Database changed即成功打開對應數據庫,可用
SELECT DATABASE();
查看當前打開的數據庫:
USE test;
1-3. 修改數據庫
ALTER {DATABASE | SCHEMA} db_name [DEFAULT] CHARACTER SET [=] charset_name;
-
可用該指令修改數據庫的編碼方式:
ALTER DATABASE test2 CHARACTER SET utf8;
1-4. 刪除數據庫
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name;
-
Query OK即為刪除成功,可用
SHOW DATABASES;
再次查看數據庫,發現里面沒有test2(IF EXISTS
作用與創建數據庫指令中的IF NOT EXISTS
相同):
DROP DATABASE IF EXISTS test2;
2. 查看數據庫的相關信息
2-1. 查看數據庫列表
SHOW {DATABASES | SCHEMAS};
-
注:下面顯示已存在的6個數據庫是軟件自帶的:
SHOW DATABASES; / SHOW SCHEMAS;
2-2. 查看某個庫使用的編碼方式
SHOW CREATE DATABASE db_name;
2-3. 查看當前打開的數據庫
SELECT DATABASE();
-
默認情況下,打開的數據庫為空(NULL):
SELECT DATABASE(); (默認為NULL)
2-4. 查看數據庫引擎
SHOW ENGINES;
3. 查看警告信息
SHOW WARNINGS;
三、數據表
- 數據表(或稱表)是數據庫最重要的組成部分之一。數據庫只是一個框架,數據表才是其實質內容。
- 一個(數據)表由
行(記錄)
和列(字段、域)
構成,組成一個二維關系表,其中列名
也稱為字段名
。而一個真正的數據庫由幾個(或更多)表、視圖及相關的文件等組成一個統一的、相關聯的系統。 - 列的屬性:
1. 列名:表的列名在同一個表中具有惟一性。
2. 數據類型:指列、存儲過程參數、表達式和局部變量的數據特征,它決定了數據的存儲格式,代表了不同的信息類型。同一列的數據屬于同一種數據類型。
3. NULL、NOT NULL、AUTO_INCREMENT、約束:NULL
屬性:允許在插入數據時省略該列的值;NOT NULL
屬性:不允許在沒有指定列缺省值的情況下插入省略該列值的數據行;AUTO_INCREMENT
:每插入一個新行時,被設值該屬性的對應列的值(相對于上一行)遞增加1。只有設置了主鍵約束的列才能使用該屬性,一般用于id等序號。詳細見第四點;約束
:約束一共有五種,分別擁有不同的目的和功能,詳細見第四點。
1. 數據類型
CREATE TABLE [IF NOT EXISTS] table_name(
column_name type_name,
...
);
-
type_name
即為數據類型。 -
數據類型:指列、存儲過程參數、表達式和局部變量的數據特征,它決定了數據的存儲格式,代表了不同的信息類型。
整型
浮點型
日期時間型
字符型
2. 數據表的操作
2-1. 創建數據表
CREATE TABLE [IF NOT EXISTS] table_name(
column_name type_name,
...
);
-
該命令用來創建數據表的列:
CREATE TABLE tb( column_name type_name,... ); -
若當前打開的數據庫為空(NULL),創建數據表會報錯:
ERROR:no database selected
2-2. 修改數據表
2-2-1.添加列(字段)
2-3. 插入行(記錄)
INSERT [INTO] tbl_name[(col_name, ...)] VALUES(val, ...);
-
全部列:
INSERT tb VALUES(); -
可選列:
INSERT tb() VALUES();
3. 查看數據表的相關信息
3-1. 查看數據表列表
SHOW TABLES [FROM db_name] [LIKE 'pattern' | WHERE expr];
- 若不加
FROM db_name
,要確保已經有數據庫被打開,否則報錯:
ERROR:no database selected - 正確使用指令:
打開test數據庫(USE test;
)后再查看。
SHOW TABLES;
或直接加FROM db_name
,此時與當前打開的數據庫無關。
SHOW TABLES FROM test;
3-2. 查看數據表的索引
SHOW INDEXES FROM tbl_name [\G]
-
以表格的形式顯示:
SHOW INDEXES FROM provinces; -
以列表的形式顯示
SHOW INDEXES FROM provinces \G;
SHOW INDEXES FROM users \G;
3-3. 查看列(字段)的結構和屬性
SHOW COLUMNS FROM db_name;
-
使用該命令之前要確保已經有數據庫被打開,否則報錯:
ERROR:no database selected -
正確使用該命令:
SHOW COLUMNS FROM tb
3-4. 查看列(字段)的代碼與引擎
SHOW CREATE TABLE tbl_name;
3-5. 查找行(記錄)
SELECT expr,... FROM tbl_name;
4. 列的其他屬性
表的列名在同一個表中具有惟一性,同一列的數據屬于同一種數據類型。除了用列名和數據類型來指定列的屬性外,還可以定義其它屬性:
4-1. 自動編號
CREATE TABLE [IF NOT EXISTS] table_name(
column_name type_name AUTO_INCREMENT PRIMARY KEY,
...
);
-
AUTO_INCREMENT
,把字段設置為自動編號。 - 必須與主鍵(
PRIMARY KEY
)組合使用:
非主鍵用AUTO_INCREMENT會報錯 -
默認情況下,起始值為1,每次增量為1:
起始值為1,增量為1 - 不管INSERT指令是否成功,被設置成AUTO_INCREMENT的列(
id
)都會自增:
id=2時,INSERT失敗而被跳過
4-2. 具體的五種約束
- 約束保證數據的完整性和一致性。
- 約束分為表級約束和列級約束。
- 約束類型包括:
NOT NULL
(非空約束)
PRIMARY KEY
(主鍵約束)
UNIQUE KEY
(唯一約束)
DEFAULT (value)
(默認約束)
FOREIGN KEY
(外鍵約束)
4-2-1. 空值和非空約束
CREATE TABLE [IF NOT EXISTS] table_name(
column_name type_name NULL(默認),
column_name type_name NOT NULL,
...
);
-
NULL
,字段值可以為空(默認)。
NOT NULL
,字段值禁止為空。 - 若該字段時屬性設置為
NOT NULL
,則插入行(記錄)時該字段不能省略,否則報錯:
NULL / NOT NULL
4-2-2. 主鍵約束
CREATE TABLE [IF NOT EXISTS] table_name(
column_name type_name PRIMARY KEY,
...
);
-
PRIMARY KEY
,給字段設置主鍵約束。 -
每張數據表只能存在一個主鍵:
Error:Multiple primary key defined -
主鍵保證記錄的唯一性:
ERROR:Duplicate entry 'xxx' for key 'xxx' - 主鍵自動被設置為
NOT NULL
:
ERROR:Field 'xxx' doesn't have a default value -
主鍵是默認自帶索引的:
CREATE TABLE provinces
SHOW INDEXES FROM provinces
4-2-3. 唯一約束
CREATE TABLE [IF NOT EXISTS] table_name(
column_name type_name UNIQUE KEY,
...
);
-
UNIQUE KEY
,給字段設置唯一約束:
UNIQUE KEY -
唯一約束保證記錄的唯一性:
ERROR:Duplicate entry 'xxx' for key 'xxx' -
每張數據表可以存在多個唯一約束:
Multiple UNIQUE KEY - 唯一約束默認被設置為
NULL
:
唯一約束默認為NULL
4-2-4. 默認約束
CREATE TABLE [IF NOT EXISTS] table_name(
column_name type_name DEFAULT value,
...
);
-
DEFAULT (value)
,默認值。 -
當插入記錄時,如果沒有明確為字段賦值,則自動賦予默認值:
DEFAULT 'unknown'
4-2-5. 外鍵約束
CREATE TABLE [IF NOT EXISTS] table_name(
...,
FOREIGN KEY (column_name) REFERENCES tbl_name(column_name) on [DELETE / UPDATE] [CASCADE / SET NULL / ON ACTION],
...
);
FOREIGN KEY
目的:
- 保持數據一致性和完整性。
- 實現一對一或一對多的關系。
要求:
- 父表和子表必須使用相同的存儲引擎,且禁止使用臨時表。
- 數據表的存儲引擎只能為InnoDB:
可以查看或編輯數據表的默認存儲引擎(編輯后要重啟MySQL服務)——打開MySQL安裝目錄下的MySQL Server 5.7
文件夾并用編輯器打開my.ini
文件,找到下面這段代碼:
default-storage-engine=INNODB - 外鍵列和參照列必須具有相似的數據類型。其中數字長度或是否有符號位必須相同;而字符的長度則可以不同:
ERROR:Cannot add foreign key constraint - **1. **外鍵列是不可以以一個沒有索引的列作為參照列的,故參照列必須創建索引(該示例為主鍵(
PRIMARY KEY
)的索引):
SHOW INDEXES FROM provinces \G;
**2. **外鍵列不存在索引的話,MySQL將自動創建索引:
SHOW INDEXES FROM users \G;
SHOW CREATE TABLE users
參照操作:
- CASCADE:從表中刪除或更新且自動刪除或更新子表中匹配的行。
- SET NULL:從父表中刪除或更新行,并設置子表中的外鍵列為NULL。如果使用該選項,必須保證子表列沒有指定NOT NULL。
- RESTRICT:拒絕對父表的刪除或更新操作。
- NO ACTION:標準SQL的關鍵字,在MySQL中與RESTRICT相同。
-- 父表
create table t_group (
id int not null, --參照列
name varchar(30),
primary key (id)
);
insert into t_group values (1, 'Group1');
insert into t_group values (2, 'Group2');
****************************** 級聯(cascade)方式 ******************************
--子表
create table t_user (
id int not null,
name varchar(30),
groupid int, --外鍵列
primary key (id),
foreign key (groupid) references t_group(id) on delete cascade on update cascade
);
--參照完整性測試
insert into t_user values (1, 'qianxin', 1); --可以插入
insert into t_user values (2, 'yiyu', 2); --可以插入
insert into t_user values (3, 'dai', 3); --錯誤,用戶組3不存在,與參照完整性約束不符
--約束方式測試
insert into t_user values (1, 'qianxin', 1);
insert into t_user values (2, 'yiyu', 2);
insert into t_user values (3, 'dai', 2);
delete from t_group where id=2; --導致t_user中的2、3記錄級聯刪除
update t_group set id=2 where id=1; --導致t_user中的1記錄的groupid級聯修改為2
****************************** 置空(set null)方式 ******************************
create table t_user (
id int not null,
name varchar(30),
groupid int,
primary key (id),
foreign key (groupid) references t_group(id) on delete set null on update set null
);
--參照完整性測試
insert into t_user values (1, 'qianxin', 1); --可以插入
insert into t_user values (2, 'yiyu', 2); --可以插入
insert into t_user values (3, 'dai', 3); --錯誤,用戶組3不存在,與參照完整性約束不符
--約束方式測試
insert into t_user values (1, 'qianxin', 1);
insert into t_user values (2, 'yiyu', 2);
insert into t_user values (3, 'dai', 2);
delete from t_group where id=2; --導致t_user中的2、3記錄的groupid被設置為NULL
update t_group set id=2 where id=1; --導致t_user中的1記錄的groupid被設置為NULL
*********************** 禁止(no action / restrict)方式 ***********************
create table t_user (
id int not null,
name varchar(30),
groupid int,
primary key (id),
foreign key (groupid) references t_group(id) on delete no action on update no action
);
--參照完整性測試
insert into t_user values (1, 'qianxin', 1); --可以插入
insert into t_user values (2, 'yiyu', 2); --可以插入
insert into t_user values (3, 'dai', 3); --錯誤,用戶組3不存在,與參照完整性約束不符
--約束方式測試
insert into t_user values (1, 'qianxin', 1);
insert into t_user values (2, 'yiyu', 2);
insert into t_user values (3, 'dai', 2);
delete from t_group where id=2; --錯誤,從表中有相關引用,因此主表中無法刪除
update t_group set id=2 where id=1; --錯誤,從表中有相關引用,因此主表中無法修改
實戰經驗:
- 在實際開發中其實很少用到物理的外鍵約束(即如上設置外鍵列),很多使用的是邏輯的外鍵約束,物理的外鍵約束只有InnoDB這種引擎才能支持,所以一般不定義物理外鍵。
- 邏輯外鍵:定義兩張表結構的時候,按照存在著某種結構的方式去定義,但是不使用FOREIGN KEY 這個關鍵詞。
4-2. 表級約束與列級約束
-
列級約束:對一個數據列建立的約束。
表級約束:對多個數據列建立的約束。 - 列級約束 即可在列定義時聲明,也可在列定義后聲明。
表級約束 只能在列定義后聲明。 - 在實際開發中,列級約束用得比較多,表級約束很少用。
- 在所有的約束中,并不是說每種約束都存在著表級或列級約束。其中:
NOT NULL
非空約束,DEFAULT
約束:只有列級約束而不存在表級約束。
PRIMARY KEY
主鍵約束,UNIQUE KEY
唯一約束,FOREIGN KEY
外鍵約束:都可以存在表級和列級約束。