怒肝三個月啃完這110道面試題,三年老Java經驗面經
09、操作資料庫的神器,SQL語言
1、SQL簡介
對資料庫進行查詢和修改操作的語言叫做 SQL(Structured Query Language,結構化查詢語言)。SQL 語言是目前廣泛使用的關係資料庫標準語言,是各種資料庫互動方式的基礎。著名的大型商用資料庫 Oracle、DB2、Sybase、SQL Server,開源的資料庫 PostgreSQL、MySQL,甚至一些小型的資料庫 Access 等都支援 SQL。近些年蓬勃發展的 NoSQL 系統最初是宣稱不再需要 SQL 的,後來也不得不修正為 Not Only SQL,來擁抱 SQL。
1、SQL是什麼
SQL 是一種資料庫查詢和程式設計語言,用於存取資料以及查詢、更新和管理關係資料庫系統。與其他程式設計語言(如 C語言、Java 等)不同的是,SQL 由很少的關鍵字組成,每個 SQL 語句通過一個或多個關鍵字構成。
- SQL 具有如下優點:
-
- 一體化:SQL 集資料定義、資料操作和資料控制於一體,可以完成資料庫中的全部工作。
- 使用方式靈活:SQL 具有兩種使用方式,可以直接以命令方式互動使用;也可以嵌入使用,嵌入C、C++、Fortran、COBOL、Java 等語言中使用。
-
- 非過程化:只提操作要求,不必描述操作步驟,也不需要導航。使用時只需要告訴計算機“做什麼”,而不需要告訴它“怎麼做”,儲存路徑的選擇和操作的執行由資料庫管理系統自動完成。
- 語言簡潔、語法簡單:該語言的語句都是由描述性很強的英語單片語成,而且這些單詞的數目不多。
1)資料定義語言(Data Definition Language,DDL)
用來建立或刪除資料庫以及表等物件,主要包含以下幾種命令:
-
DROP:刪除資料庫和表等物件
-
CREATE:建立資料庫和表等物件
-
ALTER:修改資料庫和表等物件的結構
2)資料操作語言(Data Manipulation Language,DML)
用來變更表中的記錄,主要包含以下幾種命令:
-
SELECT:查詢表中的資料
-
INSERT:向表中插入新資料
-
UPDATE:更新表中的資料
-
DELETE:刪除表中的資料
3)資料查詢語言(Data Query Language,DQL)
用來查詢表中的記錄,主要包含 SELECT 命令,來查詢表中的資料。
4)資料控制語言(Data Control Language,DCL)
用來確認或者取消對資料庫中的資料進行的變更。除此之外,還可以對資料庫中的使用者設定許可權。主要包含以下幾種命令:
-
GRANT:賦予使用者操作許可權
-
REVOKE:取消使用者的操作許可權
-
COMMIT:確認對資料庫中的資料進行的變更
-
ROLLBACK:取消對資料庫中的資料進行的變更
標準 SQL 是指符合國際標準的 SQL,而非某個資料庫廠商的 SQL 語法(如:Microsoft SQL Server 的 T-SQL,Oracle 的 PL/SQL,MySQL)。
標準 SQL 可以在任何資料庫中使用,而資料庫廠商的 SQL 只適合它們對應的資料庫,如 T-SQL 只適合 Microsoft SQL Server。
2、SQL的基本規則
對於 SQL 初學者,在寫 SQL 語句時,只要遵守下面幾個書寫規則,就可以避免很多錯誤。這些規則都非常簡單,下面我們來逐一介紹。
1)SQL 語句要以分號;結尾
在 RDBMS (關係型資料庫)當中,SQL 語句是逐條執行的,一條 SQL 語句代表著資料庫的一個操作。我們通常在句子的句尾加註標點表示這句話結束,中文句子以句號。結尾,英文以點號.結尾,而 SQL 語句則使用英文分號;結尾。
2)SQL 語句不區分大小寫
SQL 不區分關鍵字的大小寫。例如,不管寫成 SELECT 還是 select,解釋都是一樣的。表名和列名也是如此。
提示:關鍵字是資料庫事先定義的,有特別意義的單詞。
雖然可以根據個人喜好選擇大寫還是小寫(或大小寫混雜),但為了理解起來更加容易。
- 關鍵字大寫
- 資料庫名、表名和列名等小寫
需要注意的是,插入到表中的資料是區分大小寫的。例如,向資料庫中插入單詞 Computer、COMPUTER 或 computer,這三個是不一樣的資料。
2、MySQL資料庫
在SQL語言中,資料庫相當於資料夾。
1、檢視資料庫
- 檢視所有資料庫
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
7 rows in set (0.00 sec)
mysql>
- 檢視資料庫定義
mysql> show create database test01;
+----------+-------------------------------------------------------------------+
| Database | Create Database |
+----------+-------------------------------------------------------------------+
| test01 | CREATE DATABASE `test01` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-------------------------------------------------------------------+
1 row in set (0.00 sec)
- 檢視正在使用的資料庫
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select database();
+------------+
| database() |
+------------+
| mysql |
+------------+
1 row in set (0.00 sec)
2、建立資料庫
-
釋義
-
- <資料庫名>:建立資料庫的名稱。MySQL 的資料儲存區將以目錄方式表示 MySQL 資料庫,因此資料庫名稱必須符合作業系統的資料夾命名規則,不能以數字開頭,儘量要有實際意義。注意在 MySQL 中不區分大小寫。
- IF NOT EXISTS:在建立資料庫之前進行判斷,只有該資料庫目前尚不存在時才能執行操作。此選項可以用來避免資料庫已經存在而重複建立的錯誤。
- <資料庫名>:建立資料庫的名稱。MySQL 的資料儲存區將以目錄方式表示 MySQL 資料庫,因此資料庫名稱必須符合作業系統的資料夾命名規則,不能以數字開頭,儘量要有實際意義。注意在 MySQL 中不區分大小寫。
-
- [DEFAULT] CHARACTER SET:指定資料庫的字符集。指定字符集的目的是為了避免在資料庫中儲存的資料出現亂碼的情況。如果在建立資料庫時不指定字符集,那麼就使用系統的預設字符集。
- [DEFAULT] COLLATE:指定字符集的預設校對規則。
- [DEFAULT] CHARACTER SET:指定資料庫的字符集。指定字符集的目的是為了避免在資料庫中儲存的資料出現亂碼的情況。如果在建立資料庫時不指定字符集,那麼就使用系統的預設字符集。
-
格式
CREATE DATABASE [IF NOT EXISTS] <資料庫名>
[[DEFAULT] CHARACTER SET <字符集名>]
[[DEFAULT] COLLATE <校對規則名>];
- 案例
mysql> CREATE DATABASE IF NOT EXISTS test01 CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| sys |
| test |
| test01 |
+--------------------+
7 rows in set (0.00 sec)
3、修改資料庫
在 MySQL 資料庫中只能對資料庫使用的字符集和校對規則進行修改,資料庫的這些特性都儲存在 db.opt 檔案中。下面我們來介紹一下修改資料庫的基本操作。
在 MySQL 中,可以使用 ALTER DATABASE 來修改已經被建立或者存在的資料庫的相關引數。修改資料庫的語法格式為:
ALTER DATABASE [資料庫名] {
[ DEFAULT ] CHARACTER SET <字符集名> |
[ DEFAULT ] COLLATE <校對規則名>}
-
語法說明如下:
-
- ALTER DATABASE 用於更改資料庫的全域性特性。
- 使用 ALTER DATABASE 需要獲得資料庫 ALTER 許可權。
- ALTER DATABASE 用於更改資料庫的全域性特性。
-
- 資料庫名稱可以忽略,此時語句對應於預設資料庫。
- CHARACTER SET 子句用於更改預設的資料庫字符集。
- 資料庫名稱可以忽略,此時語句對應於預設資料庫。
-
案例
mysql> show create database test01;
+----------+-------------------------------------------------------------------+
| Database | Create Database |
+----------+-------------------------------------------------------------------+
| test01 | CREATE DATABASE `test01` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> ALTER DATABASE test01
-> DEFAULT CHARACTER SET utf8
-> DEFAULT COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)
mysql> show create database test01;
+----------+-----------------------------------------------------------------+
| Database | Create Database |
+----------+-----------------------------------------------------------------+
| test01 | CREATE DATABASE `test01` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+-----------------------------------------------------------------+
1 row in set (0.00 sec)
4、指定資料庫
在 MySQL 中就有很多系統自帶的資料庫,那麼在操作資料庫之前就必須要確定是哪一個資料庫。在 MySQL 中,USE 語句用來完成一個數據庫到另一個數據庫的跳轉。
當用 CREATE DATABASE 語句建立資料庫之後,該資料庫不會自動成為當前資料庫,需要用 USE 來指定當前資料庫。其語法格式為:
USE [資料庫名稱];
注:該語句可以通知 MySQL 把<資料庫名>所指示的資料庫作為當前資料庫。該資料庫保持為預設資料庫,直到語段的結尾,或者直到遇見一個不同的 USE 語句。 只有使用 USE 語句來指定某個資料庫作為當前資料庫之後,才能對該資料庫及其儲存的資料物件執行操作。
- 案例
mysql> use test01;
Database changed
mysql>
5、刪除資料庫
當資料庫不再使用時應該將其刪除,以確保資料庫儲存空間中存放的是有效資料。刪除資料庫是將已經存在的資料庫從磁碟空間上清除,清除之後,資料庫中的所有資料也將一同被刪除。
在 MySQL 中,當需要刪除已建立的資料庫時,可以使用 DROP DATABASE 語句。其語法格式為:
DROP DATABASE [ IF EXISTS ] <資料庫名>
-
語法說明如下:
-
- <資料庫名>:指定要刪除的資料庫名。
- IF EXISTS:用於防止當資料庫不存在時發生錯誤。
- <資料庫名>:指定要刪除的資料庫名。
-
- DROP DATABASE:刪除資料庫中的所有表格並同時刪除資料庫。使用此語句時要非常小心,以免錯誤刪除。如果要使用 DROP DATABASE,需要獲得資料庫 DROP 許可權。
-
案例
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| sys |
| test |
| test01 |
+--------------------+
7 rows in set (0.00 sec)
mysql> drop database test01;
Query OK, 0 rows affected (0.03 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
6 rows in set (0.00 sec)
注意:MySQL 安裝後,系統會自動建立名為 information_schema 和 mysql 的兩個系統資料庫,系統資料庫存放一些和資料庫相關的資訊,如果刪除了這兩個資料庫,MySQL 將不能正常工作。
6、資料庫註釋
- 單行註釋可以使用#註釋符,#註釋符後直接加註釋內容。格式如下:
#註釋內容
單行註釋使用註釋符#的示例如下:
#從結果中刪除重複行
SELECT DISTINCT product_id, purchase_price FROM Product;
- 單行註釋可以使用--註釋符,--註釋符後需要加一個空格,註釋才能生效。格式如下:
-- 註釋內容
單行註釋使用註釋符--的示例如下:
-- 從結果中刪除重複行
SELECT DISTINCT product_id, purchase_price FROM Product;
#和--的區別就是:#後面直接加註釋內容,而--的第 2 個破折號後需要跟一個空格符在加註釋內容。
- MySQL 多行註釋
多行註釋使用/* /註釋符。/用於註釋內容的開頭,*/用於註釋內容的結尾。多行註釋格式如下:
/*
第一行註釋內容
第二行註釋內容
*/
註釋內容寫在/和/之間,可以跨多行。
3、Mysql資料中的資料型別
資料型別(data_type)是指系統中所允許的資料的型別。MySQL 資料型別定義了列中可以儲存什麼資料以及該資料怎樣儲存的規則。
資料庫中的每個列都應該有適當的資料型別,用於限制或允許該列中儲存的資料。例如,列中儲存的為數字,則相應的資料型別應該為數值型別。
如果使用錯誤的資料型別可能會嚴重影響應用程式的功能和效能,所以在設計表時,應該特別重視資料列所用的資料型別。更改包含資料的列不是一件小事,這樣做可能會導致資料丟失。因此,在建立表時必須為每個列設定正確的資料型別和長度。
MySQL 的資料型別有大概可以分為 5 種,分別是整數型別、浮點數型別和定點數型別、日期和時間型別、字串型別、二進位制型別等。
1、MySQL整數型別
整數型別又稱數值型資料,數值型資料型別主要用來儲存數字。
MySQL 提供了多種數值型資料型別,不同的資料型別提供不同的取值範圍,可以儲存的值範圍越大,所需的儲存空間也會越大。
MySQL 主要提供的整數型別有 TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,其屬性欄位可以新增 AUTO_INCREMENT 自增約束條件。下表中列出了 MySQL 中的數值型別。
型別名稱 | 說明 | 儲存需求 |
---|---|---|
TINYINT | 很小的整數 | 1個位元組 |
SMALLINT | 小的整數 | 2個宇節 |
MEDIUMINT | 中等大小的整數 | 3個位元組 |
INT (INTEGHR) | 普通大小的整數 | 4個位元組 |
BIGINT | 大整數 | 8個位元組 |
從上表中可以看到,不同型別的整數儲存所需的位元組數不相同,佔用位元組數最小的是 TINYINT 型別,佔用位元組最大的是 BIGINT 型別,佔用的位元組越多的型別所能表示的數值範圍越大。
根據佔用位元組數可以求出每一種資料型別的取值範圍。例如,TINYINT 需要 1 個位元組(8bit)來儲存,那麼 TINYINT 無符號數的最大值為 28-1,即 255;TINYINT 有符號數的最大值為 27-1,即 127。其他型別的整數的取值範圍計算方法相同,如下表所示。
型別名稱 | 說明 | 儲存需求 |
---|---|---|
TINYINT | -128〜127 | 0 〜255 |
SMALLINT | -32768〜32767 | 0〜65535 |
MEDIUMINT | -8388608〜8388607 | 0〜16777215 |
INT (INTEGER) | -2147483648〜2147483647 | 0〜4294967295 |
BIGINT | -9223372036854775808〜9223372036854775807 | 0〜18446744073709551615 |
- 案例
用utf8mb4建立xiaowu庫
mysql> create database xiaowu charset utf8mb4;
使用xiaowu庫;
mysql> use xiaowu;
在xiaowu庫下建立t1表,id列用int型,name列用varchar型,age用tinyint型
mysql> create table t1(id int ,name varchar(64) ,age tinyint);
說明:手機號是無法儲存到int的。一般是使用char型別來儲存手機
2、MySQL小數型別
MySQL 中使用浮點數和定點數來表示小數。
浮點型別有兩種,分別是單精度浮點數(FLOAT)和雙精度浮點數(DOUBLE);定點型別只有一種,就是 DECIMAL。
浮點型別和定點型別都可以用(M, D)來表示,其中M稱為精度,表示總共的位數;D稱為標度,表示小數的位數。
浮點數型別的取值範圍為 M(1~255)和 D(1~30,且不能大於 M-2),分別表示顯示寬度和小數位數。M 和 D 在 FLOAT 和DOUBLE 中是可選的,FLOAT 和 DOUBLE 型別將被儲存為硬體所支援的最大精度。DECIMAL 的預設 D 值為 0、M 值為 10。
下表中列出了 MySQL 中的小數型別和儲存需求。
型別名稱 | 說明 | 儲存需求 |
---|---|---|
FLOAT | 單精度浮點數 | 4 個位元組 |
DOUBLE | 雙精度浮點數 | 8 個位元組 |
DECIMAL (M, D) | 壓縮的“嚴格”定點數 | M+2 個位元組 |
DECIMAL 型別不同於 FLOAT 和 DOUBLE。DOUBLE 實際上是以字串的形式存放的,DECIMAL 可能的最大取值範圍與 DOUBLE 相同,但是有效的取值範圍由 M 和 D 決定。如果改變 M 而固定 D,則取值範圍將隨 M 的變大而變大。
從上表中可以看到,DECIMAL 的儲存空間並不是固定的,而由精度值 M 決定,佔用 M+2 個位元組。
FLOAT 型別的取值範圍如下:
- 有符號的取值範圍:-3.402823466E+38~-1.175494351E-38。
- 無符號的取值範圍:0 和 -1.175494351E-38~-3.402823466E+38。
DOUBLE 型別的取值範圍如下:
- 有符號的取值範圍:-1.7976931348623157E+308~-2.2250738585072014E-308。
- 無符號的取值範圍:0 和 -2.2250738585072014E-308~-1.7976931348623157E+308。
3、MySQL字串型別
字串型別用來儲存字串資料,還可以儲存圖片和聲音的二進位制資料。字串可以區分或者不區分大小寫的串比較,還可以進行正則表示式的匹配查詢。
MySQL 中的字串型別有 CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT、ENUM、SET 等。
下表中列出了 MySQL 中的字串資料型別,括號中的M表示可以為其指定長度。
型別名稱 | 說明 | 儲存需求 |
---|---|---|
CHAR(M) | 固定長度非二進位制字串 | M 位元組,1<=M<=255 |
VARCHAR(M) | 變長非二進位制字串 | L+1位元組,在此,L< = M和 1<=M<=255 |
TINYTEXT | 非常小的非二進位制字串 | L+1位元組,在此,L<2^8 |
TEXT | 小的非二進位制字串 | L+2位元組,在此,L<2^16 |
MEDIUMTEXT | 中等大小的非二進位制字串 | L+3位元組,在此,L<2^24 |
LONGTEXT | 大的非二進位制字串 | L+4位元組,在此,L<2^32 |
ENUM | 列舉型別,只能有一個列舉字串值 | 1或2個位元組,取決於列舉值的數目 (最大值為65535) |
SET | 一個設定,字串物件可以有零個或 多個SET成員 | 1、2、3、4或8個位元組,取決於集合 成員的數量(最多64個成員) |
VARCHAR 和 TEXT 型別是變長型別,其儲存需求取決於列值的實際長度(在前面的表格中用 L 表示),而不是取決於型別的最大可能尺寸。
例如,一個 VARCHAR(10) 列能儲存一個最大長度為 10 個字元的字串,實際的儲存需要字串的長度 L 加上一個位元組以記錄字串的長度。對於字元 “abcd”,L 是 4,而儲存要求 5 個位元組。
4、MySQL日期和時間型別
MySQL 中有多處表示日期的資料型別:YEAR、TIME、DATE、DTAETIME、TIMESTAMP。當只記錄年資訊的時候,可以只使用 YEAR 型別。
每一個型別都有合法的取值範圍,當指定確定不合法的值時,系統將“零”值插入資料庫中。
下表中列出了 MySQL 中的日期與時間型別。
型別名稱 | 日期格式 | 日期範圍 | 儲存需求 |
---|---|---|---|
YEAR | YYYY | 1901 ~ 2155 | 1 個位元組 |
TIME | HH:MM:SS | -838:59:59 ~ 838:59:59 | 3 個位元組 |
DATE | YYYY-MM-DD | 1000-01-01 ~ 9999-12-3 | 3 個位元組 |
DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 8 個位元組 |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1980-01-01 00:00:01 UTC ~ 2040-01-19 03:14:07 UTC | 4 個位元組 |
- 案例
mysql> create database db1 charset utf8;
Query OK, 1 row affected (0.03 sec)
mysql> use db1;
Database changed
mysql> create table t1(id int,name char, date1 date, date2 time, date3 datetime, date4 timestamp, date5 year);
Query OK, 0 rows affected (0.05 sec)
mysql> insert into t1 values (1, '1', '2021-09-09','12:12:12','2021-09-09','2021-09-09','2021');
Query OK, 1 row affected (0.04 sec)
mysql> select * from t1;
+----+------+------------+----------+---------------------+---------------------+-------+
| id | name | date1 | date2 | date3 | date4 | date5 |
+----+------+------------+----------+---------------------+---------------------+-------+
| 1 | 1 | 2021-09-09 | 12:12:12 | 2021-09-09 00:00:00 | 2021-09-09 00:00:00 | 2021 |
+----+------+------------+----------+---------------------+---------------------+-------+
1 row in set (0.07 sec)
datetime 和 timestamp 之間的區別?
1、兩者的儲存方式不一樣
對於TIMESTAMP,它把客戶端插入的時間從當前時區轉化為UTC(世界標準時間)進行儲存。查詢時,將其又轉化為客戶端當前時區進行返回。
對於DATETIME,不做任何改變,基本上是原樣輸入和輸出。
2、兩者所能儲存的時間範圍不一樣
timestamp所能儲存的時間範圍為:‘1970-01-01 00:00:01.000000’ 到 ‘2038-01-19 03:14:07.999999’。
datetime所能儲存的時間範圍為:‘1000-01-01 00:00:00.000000’ 到 ‘9999-12-31 23:59:59.999999’。
mysql> insert into t1 values (1, '1', '2021-09-09','12:12:12','2221-09-09 12','2221-09-09','2021');
1292 - Incorrect datetime value: '2221-09-09' for column 'date4' at row 1
5、MySQL二進位制型別
MySQL 中的二進位制字串有 BIT、BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。
下表中列出了 MySQL 中的二進位制資料型別,括號中的M表示可以為其指定長度。
型別名稱 | 說明 | 儲存需求 |
---|---|---|
BIT(M) | 位欄位型別 | 大約 (M+7)/8 位元組 |
BINARY(M) | 固定長度二進位制字串 | M 位元組 |
VARBINARY (M) | 可變長度二進位制字串 | M+1 位元組 |
TINYBLOB (M) | 非常小的BLOB | L+1 位元組,在此,L<2^8 |
BLOB (M) | 小 BLOB | L+2 位元組,在此,L<2^16 |
MEDIUMBLOB (M) | 中等大小的BLOB | L+3 位元組,在此,L<2^24 |
LONGBLOB (M) | 非常大的BLOB | L+4 位元組,在此,L<2^32 |
- 案例
import pymysql
class BlobDataTestor:
def __init__(self):
self.conn = pymysql.connect(host='127.0.0.1', user='root', passwd='123456', db='db1', port=3306)
def __del__(self):
try:
self.conn.close()
except:
pass
def closedb(self):
self.conn.close()
def setup(self):
cursor = self.conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS `Dem_Picture` (
`ID` int(11) NOT NULL auto_increment,
`PicData` mediumblob,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
""")
def testRWBlobData(self):
# 讀取源圖片資料
f = open("D:\\1.jpg", "rb")
b = f.read()
f.close()
# 將圖片資料寫入表
cursor = self.conn.cursor()
cursor.execute("INSERT INTO Dem_Picture (PicData) VALUES (%s)", (pymysql.Binary(b)))
# self.conn.commit()
# 讀取表內圖片資料,並寫入硬碟檔案
cursor.execute("SELECT PicData FROM Dem_Picture ORDER BY ID DESC limit 1")
d = cursor.fetchone()[0]
cursor.close()
f = open("D:\\1.jpg", "wb")
f.write(d)
f.close()
# 下面一句的作用是:執行本程式檔案時執行什麼操作
if __name__ == "__main__":
test = BlobDataTestor()
try:
test.setup()
test.testRWBlobData()
# test.teardown()
finally:
test.closedb()
6、MySQL系統變數
在 MySQL 資料庫,變數分為系統變數和使用者自定義變數。系統變數以 @@ 開頭,使用者自定義變數以 @ 開頭。
伺服器維護著兩種系統變數,即全域性變數(GLOBAL VARIABLES)和會話變數(SESSION VARIABLES)。全域性變數影響 MySQL 服務的整體執行方式,會話變數影響具體客戶端連線的操作。
每一個客戶端成功連線伺服器後,都會產生與之對應的會話。會話期間,MySQL 服務例項會在伺服器記憶體中生成與該會話對應的會話變數,這些會話變數的初始值是全域性變數值的拷貝。
1、檢視系統變數
可以使用以下命令檢視 MySQL 中所有的全域性變數資訊。
SHOW GLOBAL VARIABLES;
可以使用以下命令檢視與當前會話相關的所有會話變數以及全域性變數。
SHOW SESSION VARIABLES;
其中,SESSION 關鍵字可以省略。
4、MySQL資料表
資料表是資料庫的重要組成部分,每一個數據庫都是由若干個資料表組成的。換句話說,沒有資料表就無法在資料庫中存放資料。
1、建立資料表
在建立資料庫之後,接下來就要在資料庫中建立資料表。所謂建立資料表,指的是在已經建立的資料庫中建立新表。
建立資料表的過程是規定資料列的屬性的過程,同時也是實施資料完整性(包括實體完整性、引用完整性和域完整性)約束的過程。接下來我們介紹一下建立資料表的語法形式。
1、基本語法
在 MySQL 中,可以使用 CREATE TABLE 語句建立表。其語法格式為:
CREATE TABLE <表名> ([表定義選項])[表選項][分割槽選項];
其中,[表定義選項]的格式為:
<列名1> <型別1> [,…] <列名n> <型別n>
CREATE TABLE 命令語法比較多,其主要是由表建立定義(create-definition)、表選項(table-options)和分割槽選項(partition-options)所組成的。
這裡首先描述一個簡單的新建表的例子,然後重點介紹 CREATE TABLE 命令中的一些主要的語法知識點。
CREATE TABLE 語句的主要語法及使用說明如下:
-
CREATE TABLE:用於建立給定名稱的表,必須擁有表CREATE的許可權。
-
<表名>:指定要建立表的名稱,在 CREATE TABLE 之後給出,必須符合識別符號命名規則。表名稱被指定為 db_name.tbl_name,以便在特定的資料庫中建立表。無論是否有當前資料庫,都可以通過這種方式建立。在當前資料庫中建立表時,可以省略 db-name。如果使用加引號的識別名,則應對資料庫和表名稱分別加引號。例如,'mydb'.'mytbl' 是合法的,但 'mydb.mytbl' 不合法。
-
<表定義選項>:表建立定義,由列名(col_name)、列的定義(column_definition)以及可能的空值說明、完整性約束或表索引組成。
-
預設的情況是,表被建立到當前的資料庫中。若表已存在、沒有當前資料庫或者資料庫不存在,則會出現錯誤。
2、建立資料表
資料表屬於資料庫,在建立資料表之前,應使用語句“USE<資料庫>”指定操作在哪個資料庫中進行,如果沒有選擇資料庫,就會丟擲 No database selected 的錯誤。
mysql> CREATE TABLE test01(
-> id int(11),
-> name VARCHAR(25)
-> );
Query OK, 0 rows affected (0.02 sec)
語句執行後,便建立了一個名稱為 test01 的資料表,使用 SHOW TABLES;語句檢視資料表是否建立成功,如下所示。
mysql> SHOW TABLES;
+---------------+
| Tables_in_db1 |
+---------------+
| test01 |
+---------------+
2 rows in set (0.00 sec)
2、修改資料表
修改資料表的前提是資料庫中已經存在該表。修改表指的是修改資料庫中已經存在的資料表的結構。修改資料表的操作也是資料庫管理中必不可少的,就像畫素描一樣,畫多了可以用橡皮擦掉,畫少了可以用筆加上。
不瞭解如何修改資料表,就相當於是我們只要畫錯了就要扔掉重畫,這樣就增加了不必要的成本。
1、修改表名
MySQL 通過 ALTER TABLE 語句來實現表名的修改。
ALTER TABLE <舊錶名> RENAME [TO] <新表名>;
- 案例
mysql> ALTER TABLE test01 RENAME TO test_01;
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW TABLES;
+---------------+
| Tables_in_db1 |
+---------------+
| Dem_Picture |
| test_01 |
+---------------+
2 rows in set (0.00 sec)
2、修改表字符集
MySQL 通過 ALTER TABLE 語句來實現表字符集的修改。
ALTER TABLE 表名 [DEFAULT] CHARACTER SET <字符集名> [DEFAULT] COLLATE <校對規則名>;
其中,DEFAULT 為可選引數,使用與否均不影響結果。
mysql> SHOW CREATE TABLE test_01\G
*************************** 1. row ***************************
Table: test_01
Create Table: CREATE TABLE `test_01` (
`id` int(11) DEFAULT NULL,
`name` varchar(25) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gb2312
1 row in set (0.00 sec)
3、修改表字段
在 MySQL 中可以使用 ALTER TABLE 語句來改變原有表的結構,例如增加或刪減列、更改原有列型別、重新命名列或表等。
其語法格式如下:
ALTER TABLE <表名> CHANGE <舊欄位名> <新欄位名> <新資料型別>;
- 案例
mysql> ALTER TABLE test_01 CHANGE name name CHAR(11);
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC test_01;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
4、修改欄位資料型別
修改欄位的資料型別就是把欄位的資料型別轉換成另一種資料型別。
ALTER TABLE <表名> MODIFY <欄位名> <資料型別>
其中:
-
表名:指要修改資料型別的欄位所在表的名稱;
-
欄位名:指需要修改的欄位;
-
資料型別:指修改後欄位的新資料型別。
案例
mysql> DESC test_01;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | char(11) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE test_01 MODIFY name VARCHAR(15);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC test_01;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(15) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
3、刪除資料表
在 MySQL 資料庫中,對於不再需要的資料表,我們可以將其從資料庫中刪除。
在刪除表的同時,表的結構和表中所有的資料都會被刪除,因此在刪除資料表之前最好先備份,以免造成無法挽回的損失。
下面我們來了解一下 MySQL 資料庫中資料表的刪除方法。
1、基礎語法
使用 DROP TABLE 語句可以刪除一個或多個數據表,語法格式如下:
DROP TABLE [IF EXISTS] 表名1 [ ,表名2, 表名3 ...]
對語法格式的說明如下:
- 表名1, 表名2, 表名3 ...表示要被刪除的資料表的名稱。DROP TABLE 可以同時刪除多個表,只要將表名依次寫在後面,相互之間用逗號隔開即可。
- IF EXISTS 用於在刪除資料表之前判斷該表是否存在。如果不加 IF EXISTS,當資料表不存在時 MySQL 將提示錯誤,中斷 SQL 語句的執行;加上 IF EXISTS 後,當資料表不存在時 SQL 語句可以順利執行,但是會發出警告(warning)。
兩點注意:
- 使用者必須擁有執行 DROP TABLE 命令的許可權,否則資料表不會被刪除。
- 表被刪除時,使用者在該表上的許可權不會自動刪除。
2、刪除資料表
刪除資料表test_01。
mysql> DROP TABLE test_01;
Query OK, 0 rows affected (0.00 sec)
3、刪除欄位
刪除欄位是將資料表中的某個欄位從表中移除。
ALTER TABLE <表名> DROP <欄位名>;
- 案例
mysql> DESC db01;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE db01 DROP name;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC db01;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
+-------+---------+------+-----+---------+----------------+
1 row in set (0.00 sec)
4、增加欄位
MySQL 資料表是由行和列構成的,通常把表的“列”稱為欄位(Field),把表的“行”稱為記錄(Record)。隨著業務的變化,可能需要在已有的表中新增新的欄位。
1、在開頭位置新增欄位
MySQL 預設在表的最後位置新增新欄位,如果希望在開頭位置(第一列的前面)新增新欄位,那麼可以使用 FIRST 關鍵字。
ALTER TABLE <表名> ADD <新欄位名> <資料型別> [約束條件] FIRST;
- 案例
mysql> DESC db01;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| addr | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> ALTER TABLE db01 ADD name VARCHAR(20) FIRST;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC db01;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| name | varchar(20) | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| addr | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
2、在中間位置新增欄位
MySQL 除了允許在表的開頭位置和末尾位置新增欄位外,還允許在中間位置(指定的欄位之後)新增欄位,此時需要使用 AFTER 關鍵字。
ALTER TABLE <表名> ADD <新欄位名> <資料型別> [約束條件] AFTER <已經存在的欄位名>;
AFTER 的作用是將新欄位新增到某個已有欄位後面。
mysql> DESC db01;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| name | varchar(20) | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| addr | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> ALTER TABLE db01 ADD sex VARCHAR(20) AFTER id;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC db01;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| name | varchar(20) | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| sex | varchar(20) | YES | | NULL | |
| addr | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
3、在末尾位置新增欄位
一個完整的欄位包括欄位名、資料型別和約束條件。
ALTER TABLE <表名> ADD <新欄位名><資料型別>[約束條件];
對語法格式的說明如下:
-
<表名> 為資料表的名字
-
<新欄位名> 為所要新增的欄位的名字
-
<資料型別> 為所要新增的欄位能儲存資料的資料型別
-
[約束條件] 是可選的,用來對新增的欄位進行約束
使用 ALTER TABLE 語句新增一個 INT 型別的欄位 age,SQL 語句和執行結果如下:
mysql> DESC db01;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
+-------+---------+------+-----+---------+----------------+
1 row in set (0.00 sec)
mysql> ALTER TABLE db01 ADD addr VARCHAR(20);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> DESC db01;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| addr | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)