目錄
- MySQL簡介
- 基本輸入查詢
- 創建并使用數據庫
- SELECT語句
- 選擇特殊行
- 條件
- 通配符
- 選擇特殊列
- 排序
- 內置函數
- 日期計算
- 子查詢
- 連接查詢
- 修改和刪除
- 刪除
- ALTER 改寫歷史
- 對表的內容修改
- 索引
- 視圖
- 導入與導出數據
- 備份數據
- 恢復
- SQL 約束
- 主鍵
- 默認約束
- 唯一約束值
- 外鍵約束
- 非空約束
MySQL簡介
- 數據庫:保存表和其他相關SQL結果的容器
- 列是存儲在表中的一塊數據。行是一組能夠描述某個事物的流的集合。行和列構成了表
- 數據庫中所有的表應該能以某種方式相互關聯
基本輸入查詢
- 啟動與連接服務器
sudo service mysql start
mysql -u root
- 要求服務器告訴MySQL的版本號和當前日期。
SELECT VERSION(), CURRENT_DATE;
- 不想執行正在輸入過程中的一個命令,輸入\c取消它
SELECT USER() \c
- 找出服務器上當前存在什么數據庫
SHOW DATABASES;
創建并使用數據庫
- 創建數據庫 gregs_list
CREATE DATABASE gregs_list;
- 使用剛才的數據庫
USE gregs_list;
- 創建一個表
CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
- CRATE TABLE 創建表
- 括號里輸入表列和列名稱
- VARCHAR:保存以文本格式存儲的信息
- (20):表示這段文字的長度最多只有6個字符
- 各種數據類型
- CHAR / CHARACTER
- INT / INTEGER
- DEC, DECIMAL
- BLOB
- DATE
- TIMESTAMP / DATETIME
- VARCHAR
- 驗證表是按你期望的方式創建
DESC pet;
- 展示數據庫中的所有表
SHOW TABLES;
- 刪除創建的表
DROP TABLE pet;
- 添加數據:INSERT
INSERT INTO pet
VALUES ('zhangyu','Diane','hamster','f','1994-03-',NULL);
INSERT 語句的三種形式
- 改變列順序:可改變列名和數據值的順序
- 省略列名:數據值必須有,且與列順序完全相同
- 省略部分列
- SELECT語句查看表中檢索所有記錄
SELECT*FROM my_contacts;
- 用一個UPDATE語句就可以修正錯誤記錄
UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';
- NULL:代表未定義的值
可以把列改為不接受NULL,但一定要提供NOT NULL列的值,否則會出現錯誤信息
CREATE TABLE my_contacts
(last_name VARCHAR (30) NOT null);
- 使用DEFAULT 填補空白
如果某些列通常有某個特定值,可把特定值指派為DEFAULT默認值
跟在DEFAULT關鍵字后的值會在每次新增記錄時自動插入表中。
默認值的類型必須和列類型相同
CREATE TABLE doughnut_list
( doughnut_name VARCHAR(10) NOT NULL,
doughnut_cost DEC(3,2) NOT NULL DEFAULT 1.00);
SELECT語句
SELECT 語句的基本格式為:
SELECT 要查詢的列名 FROM 表名字 WHERE 限制條件;
選擇特殊行
- WHERE :提供搜索的特定條件
SELECT * FROM my_contacts
WHERE first_name = 'zhang';
*
: 返回表中的所有列
單引號與不需要單引號
數據類型中,VARCHAR, CHAR,BLOB,DATA,TIME需要單引號。數字類的類型,DEC和INT不需要引號當單引號為特殊字符,需加反斜線或在單引號前再加單引號
INSERT INTO my_contacts
(location)
VALUES
('Grover\'s Mill');
INSERT INTO my_contacts
(location)
VALUES
('Grover''s Mill');
- 只顯示特定數據
用列名代替*
SELECT drink_name, main, second FROM easy_drinks WHERE main ='soda';
- AND 同時處理兩項查詢
SELECT drink_name FROM easy_drinks
WHERE
main = 'soda'
AND
amount1 = 1.5
- OR:返回符合條件之一的數據
SELECT field1_index, field2_index FROM test_table
WHERE field1_index = '1' OR field2_index = '1'
- 使用UNION將兩個表里面的關鍵字一起使用進行搜索
SELECT field1_index, field2_index
FROM test_table WHERE field1_index = '1'
UNION
SELECT field1_index, field2_index
FROM test_table WHERE field2_index = '1';
- 比較運算符
- =
- <> / !=
- (>=)
- <=
- 可用于數據數據或文本數據的比較
SELECT drink_name
FROM drink_info
WHERE
drink_name >= 'L'
AND
drink_name < 'M';
- 用 IS NULL 找到 NULL
唯一直接選擇NULL 的方法是利用關鍵字IS NULL
SELECT drink_name
FROM drink_info
WHERE
calories IS NULL;
- 選取一個范圍
AND
SELECT drink_name FROM drink_info
WHERE
calories >= 30
AND
calories <= 60;
BETWEEN
SELECT drink_name FROM drink_info
WHERE
calories BETWEEN 30 AND 60;
- 查找是否在多個篩選條件
IN
SELECT date_name FROM
black_book
WHERE
rating IN('innovative', 'fabulous',
'delightful', 'pretty good');
- 或者不符合特征的結果
NOT IN
SELECT date_name from black_book
WHERE NOT date_name LIKE 'A%'
AND NOT date_name LIKE 'B%';
- LIKE 查找部分文本字符串并返回所有符合匹配條件的行
- 通配符%——任意數量未知字符的替身
找出以“b”開頭的名字的動物信息
找出以“fy”結尾的名字
找出包含“w”的名字
mysql> SELECT * FROM pet WHERE name LIKE 'b%';
mysql> SELECT * FROM pet WHERE name LIKE '%fy';
mysql> SELECT * FROM pet WHERE name LIKE '%w%';
SELECT * FROM pet WHERE name LIKE '_____';
- 通配符下劃線(_)——一個未知字符的替身
SELECT first_name FROM my_contacts WHERE first_name LIKE '_im';
查詢結果例如:Kim
- 如果你不想看到表中的所有行,就需要指明你感興趣的列名稱,并用逗號將列名分開。例如,如果你想要知道你的動物什么時候出生的,選擇name和birth列
SELECT name, birth FROM pet;
- 取出重復數據,增加關鍵字DISTINCT檢索出每條唯一的輸出記錄
SELECT DISTINCT owner FROM pet;
- 使用一個WHERE子句同時進行行選擇與列選擇。例如,要想查詢狗和貓的出生日期,使用以下查詢:
SELECT name, species, birth FROM pet
WHERE species = 'dog' OR species = 'cat';
排序
- 對表pet的生日按日期排序ORDER BY
SELECT name, birth FROM pet ORDER BY birth;
-
BINARY
強制執行區分大小寫
SELECT col_name, birth FROM pet ORDER BY BINARY col_name
- 默認排序是升序,也就是最小的值排在第一。要想以降序排序,在你正在排序的列名旁邊增加
DESC
(降序 )關鍵字
SELECT name, birth FROM pet ORDER BY birth DESC;
- 可以對多個列進行排序,并且可以按不同的方向對不同的列進行排序。
例如,按升序對動物的種類進行排序,然后按降序根據生日對各動物種類進行排序(最年輕的動物在最前面),使用下列查詢
SELECT name, species, birth FROM pet
-> ORDER BY species, birth DESC;
內置函數
|函數名|COUNT|SUM|AVG|MAX|MIN|
|作用|計數|求和|求平均值|最大值|最小值|
- 計算表中有多少行
COUNT(*)
SELECT COUNT(*) FROM pet;
- 你檢索了擁有寵物的人的名字。如果你想要知道每個主人有多少寵物,你也可以使用
COUNT(*)
函數,使用GROUP BY
對每個owner
的所有記錄分組
SELECT owner, COUNT(*) FROM pet GROUP BY owner;
- 分類數量
查看每種動物的數量
查看每種性別的動物數量
按種類和性別組合分類的動物數量
SELECT species, COUNT(*) FROM pet GROUP BY species;
SELECT sex, COUNT(*) FROM pet GROUP BY sex;
SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
- 計算出salary的最大、最小值
SELECT MAX(salary) AS max_salary,MIN(salary) FROM employee;
- 找出最高或最低的商品
SELECT min_price:=MIN(price),max_price:=MAX(price) FROM shop;
SELECT * FROM shop WHERE price= min_price OR price= max_price;
日期計算
- 使用函數
TIMESTAMPDIFF()
計算當前日期的年和出生日期之間的差也可以按照直接使用語句(YEAR(CURDATE())-YEAR(birth))
計算,其中函數CURDATE()
是計算當前的日期。如果當前日期的日歷年比出生日期早,則減去一年。
SELECT name, birth, CURDATE(),
TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
FROM pet;
SELECT name, birth, CURDATE(),
(YEAR(CURDATE())-YEAR(birth))
- (RIGHT(CURDATE(),5)<RIGHT(birth,5)) AS age
FROM pet;
YEAR()
提取日期的年部分
RIGHT()
提取日期最右面5個字符的MM-DD
(月份和日期)部分
MM-DD
值的表達式部分的值一般為1或0,如果CURDATE()
的年比birth
的年早,則年份應減去1
整個表達式看起來有些難懂,使用age
來使輸出的列標記更有意義
- 如果以某個順序排列行,那么會使得瀏覽結果變得更加輕松。添加
ORDER BY name
子句則能夠實現按照名字進行排序輸出
SELECT name, birth, CURDATE(),(YEAR(CURDATE())-YEAR(birth)) - (RIGHT(CURDATE(),5)<RIGHT(birth,5))
AS age
FROM pet ORDER BY name;
子查詢
- 處理多個表才能獲得想要的信息
想要知道名為 "Tom" 的員工所在部門做了幾個工程。員工信息儲存在 employee 表中,但工程信息儲存在project 表中
SELECT of_dpt,COUNT(proj_name) AS count_project FROM project
WHERE of_dpt IN
(SELECT in_dpt FROM employee WHERE name='Tom');
- event表中有生產日期,但是為了計算年齡,你需要出生日期,存儲在pet表中。查詢需要兩個表
- FROM子句連接兩個表,因為查詢需要從兩個表中提取信息
- 當從多個表組合(聯結)信息時,你需要指定其中一個表中的列明以期匹配其它表的列名。這很簡單,因為它們都有一個name列,查詢可以通過使用WHERE子句基于name值來匹配兩個表中的記錄
- 因為name列都存在兩個表中,因此當引用該列時,一定要指定是哪個表,把表名附在列名前即可以實現
SELECT pet.name,
(YEAR(date)-YEAR(birth)) - (RIGHT(date,5)<RIGHT(birth,5)) AS age,
remark
FROM pet, event
WHERE pet.name = event.name AND event.type = 'litter';
連接查詢
在處理多個表時,子查詢只有在結果來自一個表時才有用。但如果需要顯示兩個表或多個表中的數據,這時就必須使用連接 (join) 操作。
- 連接的基本思想是把兩個或多個表當作一個新的表來操作,如下
SELECT id,name,people_num
FROM employee,department
WHERE employee.in_dpt = department.dpt_name
ORDER BY id;
- 另一個連接語句格式是使用 JOIN ON 語法,剛才的語句等同于:
SELECT id,name,people_num
FROM employee JOIN department
ON employee.in_dpt = department.dpt_name
ORDER BY id;
- 如果你想要將一個表的記錄與該表的其它記錄進行比較,可以將該表聯結到自身。
例如,為了在你的寵物之中選擇繁殖中的配偶,你可以用pet表聯結自身來進行相同種類的雄雌配對:
為表名指定別名p1和p2以便能引用它們的列并且使得每一個列的引用更直觀
SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
FROM pet AS p1, pet AS p2
WHERE p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';
修改和刪除
刪除
- 刪除數據庫 DROP
DROP DATABASE test_01;
- 創建新記錄并刪除舊記錄
SELECT——INSERT——DELETE,先用SELECT 挑選你必須移除的記錄,確認記錄無誤,并沒有誤刪其他記錄,用INSERT添加新的信息,再刪除舊的信息
SELECT * FROM clown_info
WHERE
activities = 'dancing';
INSERT INTO clown_info
VALUES
('CLARABELLE', 'Belmont senior', 'F,pink hair', 'dancing');
DELETE FROM clown_info
WHERE
activities = 'yelling, dancing' AND name = 'Clarabelle';
- 刪除一張表
DDROP TABLE 表名字;
- 刪除一列:
ALTER TABLE 表名字 DROP COLUMN 列名字;
或: ALTER TABLE 表名字 DROP 列名字;
ALTER 改寫歷史
- 添加一列
ALTER TABLE 表名字 ADD COLUMN 列名字 數據類型 約束;
或:
ALTER TABLE 表名字 ADD 列名字 數據類型 約束;
- 如果要把增加的列插入在指定位置,則需要在語句的最后使用AFTER關鍵詞
ALTER TABLE employee ADD weight INT(4) DEFAULE 120 AFTER age;
ADD COLUMN
添加列
AFTER 列
表示新增的列被放置在列1
的后面,
DEFAULT 120
:新增的一列weight
的默認數值都為值為120
如果想放在第一列的位置,則使用FIRST
關鍵詞
- 修改表的常用命令
- CHANGE :可同時改變現有列的名稱和數據類型
- MODIFY:修改現有列的數據類型和位置
- ADD:在當前表中添加一列
- DROP:從表中刪除某列
- DESCRIBE 查看表的構成
- 更換列名
修改數據類型可能會導致數據丟失,所以要慎重使用
ALTER TABLE 表名字 CHANGE 原列名 新列名 數據類型 約束;
- 改變列名,并標注為主鍵
ALTER TABLE project_list
CHANGE COLUMN number proj_id INT NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (proj_id);
AUTO_INCREMENT
自動填入遞增的整數
ADD......
——使用新命令的列作為主鍵
- 重命名一張表,三種形式:
RENAME TABLE 原名 TO 新名字;
ALTER TABLE 原名 RENAME 新名;
ALTER TABLE 原名 RENAME TO 新名;
ALTER TABLE projekts
RENAME TO project_list;
- 只改變數據類型, 關鍵字:MODIFY
ALTER TABLE project_list
MODIFY COLUMN proj_desc VARCHAR(120);
project_list 要修改的列名
VARCHAR(120)新數據類型, 保證新類型不會造成舊數據被截斷。
- 刪除一列:
ALTER TABLE 表名字 DROP COLUMN 列名字;
或: ALTER TABLE 表名字 DROP 列名字;
ALTER TABLE project_list
DROP COLUMN start_date;
- 使用FIRST, LAST, BEFORE column_name, AFTER column_name, SECOND,THIRD, FOURTH等關鍵字,可調整列的順序
- 改變數據類型
ALTER TABLE 表名字 MODIFY 列名字 新數據類型;
- 將現有列的內容填入新列
UPDATE my_contacts
SET state = RIGHT(location, 2);
(state, 儲存州數據的新列
RIGHT........提取location列的最后兩個字符)
對表的內容修改
- 修改表中某個值
UPDATE 表名字 SET 列1=值1,列2=值2 WHERE 條件;
UPDATE doughnut_ratings
SET
type = 'glazed'
WHERE type = 'plain glazed';
不加where子句,SET子句提到的表中的每行的每列都會被修改
- 一次更改多個數值
UPDATE drink_info
SET cost = cost + 1
WHERE
drink_name = 'Blue Moon'
OR
drink_name = 'Oh My Gosh'
OR
drink_name = 'Lime Fizz';
- 刪除一行記錄
刪除表中的一行數據,也必須加上WHERE條件,否則整列的數據都會被刪除
DELETE FROM 表名字 WHERE 條件;
索引
- 什么是索引
索引是一種與表有關的結構,它的作用相當于書的目錄,可以根據目錄中的頁碼快速找到所需的內容- 當表中有大量記錄時,若要對表進行查詢,沒有索引的情況是全表搜索:將所有記錄一一取出,和查詢條件進行一一對比,然后返回滿足條件的記錄。這樣做會消耗大量數據庫系統時間,并造成大量磁盤 I/O 操作。
- 而如果在表中已建立索引,在索引中找到符合查詢條件的索引值,通過索引值就可以快速找到表中的數據,可以大大加快查詢速度
- 對一張表中的某個列建立索引,有以下兩種語句格式
ALTER TABLE 表名字 ADD INDEX 索引名 (列名);
CREATE INDEX 索引名 ON 表名字 (列名);
ALTER TABLE employee ADD INDEX idx_id (id); #在employee表的id列上建立名為idx_id的索引
CREATE INDEX idx_name ON employee (name); #在employee表的name列上建立名為idx_name的索引
索引的效果是加快查詢速度,當表中數據不夠多的時候是感受不出它的效果的。使用命令 SHOW INDEX FROM 表名字; 查看剛才新建的索引
視圖
- 什么是視圖
視圖是從一個或多個表中導出來的表,是一種虛擬存在的表。它就像一個窗口,通過這個窗口可以看到系統專門提供的數據,這樣,用戶可以不用看到整個數據庫中的數據,而只關心對自己有用的數據
注意理解視圖是虛擬的表:
- 數據庫中只存放了視圖的定義,而沒有存放視圖中的數據,這些數據存放在原來的表中;
- 使用視圖查詢數據時,數據庫系統會從原來的表中取出對應的數據;
- 視圖中的數據依賴于原來表中的數據,一旦表中數據發生改變,顯示在視圖中的數據也會發生改變;
- 在使用視圖的時候,可以把它當作一張表。
- 創建視圖的語句格式為
CREATE VIEW 視圖名(列a,列b,列c) AS SELECT 列1,列2,列3 FROM 表名字;
現在我們創建一個簡單的視圖,名為 v_emp,包含v_name,v_age,v_phone三個列
CREATE VIEW v_emp(v_name, v_age,v_phone) AS SELECT name, age, phone FROM employee;
導入與導出數據
- 導入操作
可以把一個文件里的數據保存進一張表。
- linux系統
LOAD DATA INFILE '文件路徑' INTO TABLE 表名字;
- windows 系統
LOAD DATA INFILE '文件路徑' INTO TABLE pet LINES
TERMINATED BY '\r\n';
- 導出數據
導出與導入是相反的過程,是把數據庫某個表中的數據保存到一個文件之中
SELECT 列1,列2 INTO OUTFILE '文件路徑和文件名' FROM 表名字;
把整個employee表的數據導出到 /tmp 目錄下,導出文件命名為 out.txt 具體語句為
SELECT * INTO OUTFILE '/tmp/out.txt' FROM employee;
備份數據
- 數據庫中的數據或許十分重要,出于安全性考慮,在數據庫的使用中,應該注意使用備份功能。
備份與導出的區別:導出的文件只是保存數據庫中的數據;而備份,則是把數據庫的結構,包括數據、約束、索引、視圖等全部另存為一個文件。
mysqldump 是 MySQL 用于備份數據庫的實用程序。它主要產生一個 SQL 腳本文件,其中包含從頭重新創建數據庫所必需的命令CREATE TABLE INSERT 等。
使用 mysqldump 備份的語句,退出msql, 在終端輸入
mysqldump -u root 數據庫名>備份文件名; #備份整個數據庫
mysqldump -u root 數據庫名 表名字>備份文件名; #備份整個表
備份整個數據庫 mysql_shiyan,將備份文件命名為 bak.sql,先 Ctrl+Z 退出 MySQL 控制臺,再打開終端
mysqldump -u root mysql_shiyan > bak.sql;
恢復
- 方法1
把 MySQL-06.sql 文件中保存的mysql_shiyan 數據庫恢復。
source /tmp/SQL6/MySQL-06.sql
- 方法2
先使用命令新建一個空的數據庫 test:
mysql -u root #因為在上一步已經退出了MySQL,現在需要重新登錄
CREATE DATABASE test; #新建一個名為test的數據庫
再次 Ctrl+Z 退出MySQL,然后輸入語句進行恢復,把剛才備份的 bak.sql 恢復到 test 數據庫
mysql -u root test < bak.sql
輸入命令查看 test 數據庫的表,便可驗證是否恢復成功
mysql -u root #因為在上一步已經退出了MySQL,現在需要重新登錄
use test #連接數據庫test
SHOW TABLES; #查看test數據庫的表
SQL 約束
約束
- 什么是約束
約束是一種限制,它通過對表的行或列的數據做出限制,來確保表的數據的完整性、唯一性。 - 約束類型
約束類型: | 主鍵 | 默認值 | 唯一值 | 外鍵 | 非空 |
---|---|---|---|---|---|
關鍵字 | PRIMARY KEY | DEFAULT | UNIQUE | FOREIGN KEY | NOT NULL |
主鍵
什么是主鍵
主鍵 是用于約束表中的一行,作為這一行的唯一標識符,讓每一條記錄成為唯一的,在一張表中通過主鍵就能準確定位到一行,用于獨一無二地識別出每條記錄。主鍵的規則
- 主鍵不可以為NULL
- 插入新記錄時必須制定主鍵值
- 主鍵必須簡潔
- 主鍵值不可以被修改
- 為現有的表添加主鍵
ALTER TABLE 并添加PRIMARY KEY
ALTER TABLE my_contacts
ADD COLUMN contact_id INT NOT
AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (contact_id);
默認約束
什么是默認約束
默認值約束 (DEFAULT) 規定,當有 DEFAULT 約束的列,插入數據為空時,將使用默認值。規則
DEFAULT 約束只會在使用 INSERT 語句時體現出來,INSERT語句中,如果被 DEFAULT 約束的位置沒有值,那么這個位置將會被 DEFAULT 的值填充
# 正常插入數據
INSERT INTO department(dpt_name,people_num) VALUES('dpt1',11);
#插入新的數據,people_num 為空,使用默認值
INSERT INTO department(dpt_name) VALUES('dpt2');
唯一約束值
唯一約束 (UNIQUE) 比較簡單,它規定一張表中指定的一列的值必須不能有重復值,即這一列每個值都是唯一的
- 規則
當 INSERT 語句新插入的數據和已有數據重復的時候,如果有 UNIQUE約束,則 INSERT 失敗
INSERT INTO employee VALUES(01,'Tom',25,3000,110110,'dpt1');
INSERT INTO employee VALUES(02,'Jack',30,3500,110110,'dpt2');
第二行插入會顯示錯誤
外鍵約束
-
什么是外鍵約束
外鍵 (FOREIGN KEY) 既能確保數據完整性,也能表現表之間的關系。一個表可以有多個外鍵,每個外鍵必須 REFERENCES (參考) 另一個表的主鍵,被外鍵約束的列,取值必須在它參考的列中有對應值
規則
在 INSERT 時,如果被外鍵約束的值沒有在參考列中有對應,比如以下命令,參考列 (department 表的 dpt_name) 中沒有dpt3,則INSERT 失敗
#將 dpt3 改為 dpt2(department 表中有 dpt2),則插入成功
INSERT INTO employee VALUES(02,'Jack',30,3500,114114,'dpt3');
非空約束
被非空約束的列,在插入值時必須非空
參考資料:
實驗樓-MySQL 基礎課程
《MySQL必知必會》