在本系列教程中,目前我們使用平面文本文件來存儲數據。平面文本文件可能適合相對較少的數據,但它們對存儲大量數據或查詢該數據沒有多大幫助。多年來,為該目的開發了多種數據庫,包括分層和網絡數據庫,但現在最常見的是關系數據庫。關系數據庫基於 E. F. Codd 的想法,E. F. Codd 效力於 IBM®,他在 1970 年發表了原創性論文 “一種針對大型共享數據銀行的關系數據模型”。如今有多種關系數據庫系統,包括商用產品(比如 IBM DB2®、IBM Informix® 和 Oracle Database)和開源項目(比如 MySQL、PostgreSQL SQLite 和 MariaDB[MySQL 的一個分支])。關系數據庫使用 SQL 作為數據定義和查詢語言。
要從本系列教程中獲得最大收獲,您應該擁有 Linux 的基本知識和一個正常工作的 Linux 系統,您可以在這個系統上實踐本教程中涵蓋的命令。您應該熟悉 GNU 和 UNIX® 命令。有時,一個程序的不同版本會以不同方式格式化輸出,所以您的結果可能並不總是與這裡給出的清單完全一樣。
對於本教程,您需要一個數據庫(比如 MariaDB)和您的數據庫的文檔。
本教程中的 SQL 示例在很大程度上獨立於發行版和數據庫。大部分示例都使用了含 4.2.6 內核的 Fedora 23 上的開源 MariaDB 10.0.21 版。我還提供了一些使用 IBM DB2 Express-C 10.5 版的示例,該版本是 IBM DB2 數據服務器在含 2.6.32 內核的 CentOS 6.7 上的一個免費社區版本。通過比較這些示例,您可以了解您在使用多種數據庫系統時可能遇到的差別。如果您需要實現可移植的數據庫程序或腳本,則要求您對 ISO/ANSI SQL 標准的了解比我在這裡介紹的多一些。
一些數據庫操作命令是特定於數據庫的。SQL 語法中也存在一些小差異,尤其是對於非標准擴展。在必要時,請參閱您使用的數據庫的文檔。
數據庫、表、列和行關系數據庫由一組表 組成。可以將表中的每行 數據視為一條記錄,表的每列 對應於相應行的記錄中的字段。一列中的數據都具有相同的類型,比如字符、整數、日期或二進制數據(比如圖像)。通過以這種方式使用結構化數據,您可以構造有益的查詢,比如 “找到在某個日期後招聘的所有員工” 或 “找到所有大於 0.25 英畝的地塊”。
關系數據庫中的數據可能在每行有一個唯一值,比如員工記錄中的員工 ID,市政土地數據庫中的地塊 ID,或者計算機系統中的用戶 ID。如果是這樣,您可以為該列創建一個索引,可以將一個這樣的列指定為該表的主鍵。鍵和索引可幫助數據庫引擎加速數據的檢索。
當您安裝數據庫時,您通常會安裝一個數據庫服務器。您可能還會安裝一個客戶端,或者可能通過編寫的應用程序或命令行訪問該服務器。服務器通常作為後台進程運行,您的客戶端或應用程序通常通過 TCP/IP 連接來連接它。您必須采取相應的措施來保護安裝,預防您不想支持的訪問。
許多 Linux 發行版包含 MariaDB、SQLite、PostgreSQL 和 MySQL 的包。對於本教程,我主要使用了 MariaDB。請參閱 “包含 MariaDB 的發行版” 或使用適合您的發行版的包管理工具來檢查已為您的發行版打包了哪些數據庫。MariaDB 是 MySQL 的一個開源分支,所以 mysql 是許多命令名稱的一部分。
MariaDB 入門這裡提供一些簡單技巧,幫助您在打包了 MariaDB 的發行版上運行它。我在本教程中使用了 Fedora 23。首先安裝 mariadb 和 mariadb-server 包,它們會引入所需的其他一些包。
接下來,采用擁有 root 用戶權限的用戶身份運行 mysql_secure_installation 命令。通過運行此命令,您可以:
為一個 root 數據庫用戶設置一個密碼
刪除最初安裝用於測試的匿名用戶
確保該 root 用戶僅能從本地系統登錄
刪除測試數據庫(可選)
重新加載特權表,讓之前的更改立即生效
數據庫 root 用戶不是系統 root 用戶,不應擁有相同的密碼。如果您需要執行更改,可以重新運行 mysql_secure_installation。
對於本教程,我使用了來自 GitHub 的 test_db 包中包含的 employee 示例數據庫。清單 1 給出了我將該數據庫安裝在我的系統上所用的步驟。
[ian@attic-f23 ~]$ unzip -q test_db-master.zip [ian@attic-f23 ~]$ cd test_db-master[ian@attic-f23 test_db-master]$ mysql -u root -p (< )employees .sqlEnter password: INFOCREATING DATABASE STRUCTUREINFOstorage engine: InnoDBINFOLOADING departmentsINFOLOADING employeesINFOLOADING dept_empINFOLOADING dept_managerINFOLOADING titlesINFOLOADING salariesdata_load_time_diffNULL.
清單 1 中使用的默認 InnoDB 引擎適合本教程的目的。
您的第一個數據庫現在 MariaDB 已安裝在您的系統上,您可以啟動它來看看您擁有哪些數據庫。清單 2 使用 mysqlshow 命令來顯示我已安裝的數據庫。-u 選項指定數據庫 root 用戶,-p 選項告訴 mysqlshow 提示您輸入您在運行 mysql_secure_installation 命令時定義的密碼。
清單 2. 我擁有哪些數據庫?[ian@attic-f23 ~]$ mysqlshow -u root -pEnter password: +--------------------+| Databases |+--------------------+| employees || information_schema || mysql || performance_schema || test |+--------------------+
可以看到我有 5 個數據庫:我剛剛創建的 employees 數據庫,我沒有創建的 test 數據庫,以及其他 3 個數據庫。數據庫程序通常包含多個數據庫來描述該數據庫本身,您可以在 清單 2 中看到它們。
mysqlshow 命令是一個快速列出數據庫、表和列信息的便捷工具。MariaDB(和 MySQL)包含一個類似於數據庫 shell 的交互式命令行接口 (CLI) 程序,名為 mysql。DB2 還有一個 CLI 程序,名為 db2。與 bash 等 shell 一樣,您可以將一個命令傳遞到任意一個數據庫 shell,也可以運行一個包含許多命令的交互式會話。清單 3 通過帶 -e 選項的 mysql 命令執行單個數據庫命令來顯示數據庫信息。
清單 3. 列出 MariaDB 數據庫[ian@attic-f23 ~]$ mysql -u root -p -e "show databases"Enter password: +--------------------+| Database |+--------------------+| employees || information_schema || mysql || performance_schema || test |+--------------------+
如果您還安裝了 DB2 Express-C,那麼您已經創建了一個名為 db2inst1 的用戶(默認用戶)來管理該數據庫。清單 4 展示了如何使用 db2 命令獲取 DB2 數據庫的相應信息。
清單 4. 列出 DB2 數據庫[ian@attic4-cent ~]$ db2 list database directory System Database Directory Number of entries in the directory = 1Database 1 entry: Database alias = SAMPLE Database name = SAMPLE Local database directory = /home/db2inst1 Database release level = 10.00 Comment = Directory entry type = Indirect Catalog database partition number = 0 Alternate server hostname = Alternate server port number =了解表和列
在從數據庫提取信息之前,您需要知道數據庫中有什麼。在 清單 5 中,您可以了解如何:
清單 5. 顯示 MariaDB 表和列信息啟動 mysql 交互式數據庫 shell,並使用您創建的 root ID 連接到 employees 數據庫
使用 show tables 命令查看 employees 數據庫中包含哪些表
使用 describe 命令查看 employees 數據庫中的 employees 表中包含哪些列
[ian@attic-f23 ~]$ mysql -u root -p employeesEnter password: Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -AWelcome to the MariaDB monitor. Commands end with ; or \g.Your MariaDB connection id is 19Server version: 10.0.21-MariaDB MariaDB ServerCopyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [employees]> show tables;+----------------------+| Tables_in_employees |+----------------------+| current_dept_emp || departments || dept_emp || dept_emp_latest_date || dept_manager || employees || salaries || titles |+----------------------+8 rows in set (0.00 sec)MariaDB [employees]> describe employees;+------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+------------+---------------+------+-----+---------+-------+| emp_no | int(11) | NO | PRI | NULL | || birth_date | date | NO | | NULL | || first_name | varchar(14) | NO | | NULL | || last_name | varchar(16) | NO | | NULL | || gender | enum('M','F') | NO | | NULL | || hire_date | date | NO | | NULL | |+------------+---------------+------+-----+---------+-------+6 rows in set (0.00 sec)
employees 表中的每個字段(或列)有多個屬性:
Field:列的名稱。
Type:列的數據類型。許多數據類型都具有最大長度限制。例如,int(11) 指定一個可包含 11 位數的整數,varchar(16) 指定包含最多 16 字節數據的可變長度字符串。請參閱 “SQL 數據類型” 部分,了解有關數據類型的更多信息。
Null:指定是否允許該列擁有 null(空)值。
Key:如果該列是一個鍵,則表示鍵類型。主 (PRI) 鍵必須包含非 null 的唯一值。
Default:指定如果添加一條記錄且沒有為該列提供數據,則在該列中放入什麼樣的默認值。
Extra:指定額外屬性(例如 auto_increment,它用於創建唯一遞增編號,比如序列號)。
如果您在 shell 中需要獲得幫助,可以使用 help(或 ?)命令。清單 6 給出了 describe 命令的幫助輸出。
清單 6. MariaDB describe 命令的幫助MariaDB [employees]> ? describeName: 'DESCRIBE'Description:Syntax:{DESCRIBE | DESC} tbl_name [col_name | wild]DESCRIBE provides information about the columns in a table. It is ashortcut for SHOW COLUMNS FROM. These statements also displayinformation for views. (See [HELP SHOW COLUMNS].)col_name can be a column name, or a string containing the SQL "%" and"_" wildcard characters to obtain output only for the columns withnames matching the string. There is no need to enclose the stringwithin quotation marks unless it contains spaces or other specialcharacters.MariaDB> DESCRIBE City;+------------+----------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra |+------------+----------+------+-----+---------+----------------+| Id | int(11) | NO | PRI | NULL | auto_increment || Name | char(35) | NO | | | || Country | char(3) | NO | UNI | | || District | char(20) | YES | MUL | | || Population | int(11) | NO | | 0 | |+------------+----------+------+-----+---------+----------------+5 rows in set (0.00 sec)The description for SHOW COLUMNS provides more information about theoutput columns (see [HELP SHOW COLUMNS]).URL: https://mariadb.com/kb/en/describe/
請注意,該幫助以全大寫字母形式顯示 DESCRIBE。通常,SQL 命令名稱是不區分大小寫的。其他對象(比如數據庫、表或列)的名稱是否區分大小寫取決於您的數據庫程序和運行它的平台。請參見 參考資料,了解有關 MariaDB 的更多信息。
SQL 數據類型您已在 清單 5 中看到了 SQL 數據類型的示例。典型的 SQL 數據類型大體分為 4 類:
String 數據類型存儲固定長度或可變長度的字符或二進制串,以及大對象。示例包括 CHAR(8)、VARCHAR(240)、BINARY(12)、VARBINARY(500) 和 BLOB(200000)。
Numeric 數據類型存儲定點數或浮點數。示例包括 SMALLINT(16 位)、INT 或 INTEGER(32 位)、BIGINT(64 位)、FLOAT(單精度浮點)、DOUBLE(雙精度浮點)和 DECIMAL(一個包含小數點的壓縮十進制數)。整數數據可以是有符號或無符號的。
Boolean 數據類型存儲 TRUE 或 FALSE 值。
Date 和 time 值存儲可用於比較的日期和時間。示例包括 DATE 和 TIME。
這些示例並不詳盡,而且不同的數據庫程序可能會擴展它們。例如,DB2 支持使用 CLOB 存儲字符大對象,使用 DBCLOB 存儲包含雙字節字符數據的大對象。MariaDB 支持使用 TINYINT 存儲 1 字節整數和使用 ENUM 存儲枚舉數據,您在 清單 5 中的 gender 字段中已看到。
備注:在 SQL 中使用枚舉數據類型存在一定的爭議。更傳統的方法是使用具有外鍵 的參考表。可以在網絡上搜索來進一步了解對數據庫中的枚舉數據類型的爭議。
您現在已經看到了數據庫、表和表中的數據類型的示例。下一步是獲取表中的數據。可以使用 SELECT 語句檢索數據。可以選擇表中的所有數據,或者選擇特定列的數據。清單 7 顯示了 departments 表中的數據,以及如何通過 SELECT * 選擇其中的所有數據,然後如何僅選擇部門名稱。
清單 7. SELECT 命令的基本用法MariaDB [employees]> describe departments;+-----------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------+-------------+------+-----+---------+-------+| dept_no | char(4) | NO | PRI | NULL | || dept_name | varchar(40) | NO | UNI | NULL | |+-----------+-------------+------+-----+---------+-------+2 rows in set (0.00 sec)MariaDB [employees]> select * from departments;+---------+--------------------+| dept_no | dept_name |+---------+--------------------+| d009 | Customer Service || d005 | Development || d002 | Finance || d003 | Human Resources || d001 | Marketing || d004 | Production || d006 | Quality Management || d008 | Research || d007 | Sales |+---------+--------------------+9 rows in set (0.00 sec)MariaDB [employees]> select dept_name from departments;+--------------------+| dept_name |+--------------------+| Customer Service || Development || Finance || Human Resources || Marketing || Production || Quality Management || Research || Sales |+--------------------+9 rows in set (0.00 sec)排序和選擇
選擇 departments 表中的所有數據時,像 清單 7 中一樣,輸出會按部門名稱排序。如果您希望根據一個或多個列中的值對輸出數據進行排序,可以使用 ORDER BY 子句。指定一個用逗號分隔的列組成的列表。也可以指定 ASC 來按升序進行排序(默認),或者指定 DESC 來按照降序進行排序。清單 8 展示了如何按 dept_no 進行降序排序。
清單 8. 對查詢輸出進行排序MariaDB [employees]> select dept_name,dept_no from departments order by dept_no desc;+--------------------+---------+| dept_name | dept_no |+--------------------+---------+| Customer Service | d009 || Research | d008 || Sales | d007 || Quality Management | d006 || Development | d005 || Production | d004 || Human Resources | d003 || Finance | d002 || Marketing | d001 |+--------------------+---------+9 rows in set (0.00 sec)
可以使用 WHERE 子句選擇要顯示哪些數據。可以比較各列,或者將列值與某個值比較。該值(稱為標量)可以是一個常數(必須包含在引號內)或一個標量函數的結果,比如今天的日期。可使用布爾 AND、OR 和 NOT 運算符來定義更復雜的條件。清單 9 給出了一些使用 departments 表的示例。
清單 9. 使用 WHERE 子句限制數據輸出MariaDB [employees]> select * from departments where dept_no > 'd007';+---------+------------------+| dept_no | dept_name |+---------+------------------+| d008 | Research || d009 | Customer Service |+---------+------------------+2 rows in set (0.00 sec)MariaDB [employees]> select * from departments -> WHERE dept_name = 'Customer Service' OR ( -> dept_no > 'd002' AND dept_no < = "d006" -> );+---------+--------------------+| dept_no | dept_name |+---------+--------------------+| d009 | Customer Service || d005 | Development || d003 | Human Resources || d004 | Production || d006 | Quality Management |+---------+--------------------+5 rows in set (0.00 sec)
請注意,在 清單 9 中,來自更復雜的 WHERE 子句的輸出沒有排序。使用 ORDER 子句來采用您想要的排序方式。另請注意,您可以將 SQL 命令輸入在多行上。MariaDB 在第二行和後續行上提供了一個 -> 提示符。我在後續示例中刪除了這些輔助提示符,以便您可以更輕松地將該命令直接復制並粘貼到自己的系統中。
您還可以使用 LIKE 來執行模式匹配和直接比較。大多數 SQL 數據庫都支持以下兩種通配符:
% 匹配任意多個字符,包括空字符串。
_ 匹配任何單一字符。
清單 10 展示了如何查找所有包含字符串 es 的部門名稱。
清單 10. 使用 WHERE 子句和 LIKE 進行模式匹配MariaDB [employees]> select * from departments WHERE dept_name LIKE '%es%';+---------+-----------------+| dept_no | dept_name |+---------+-----------------+| d003 | Human Resources || d008 | Research || d007 | Sales |+---------+-----------------+3 rows in set (0.00 sec)v
一些數據庫(包括 MariaDB)支持正則表達式模式匹配。請參閱您數據庫的文檔,了解關於這個主題的更多信息。
針對列的 SQL 函數您已經了解了一些簡單的比較運算符。SQL 還有一些函數可供使用,它們包括:
COUNT:統計返回的行數。
DISTINCT:僅選擇不同的值。
MAX 和 MIN:選擇一對值中的最大值或最小值。
NOW:返回當前的日期和時間。
DATEDIFF:將兩個日期相減,返回它們之間相隔的天數。
DAY:返回給定日期是星期幾。
LEAST:找到一組值中最小的一個值。
還有其他許多這樣的函數,所以請參閱您的文檔來了解它們。
清單 11 展示了如何統計兩個不同表中的行數。
MariaDB [employees]> # How many employees?MariaDB [employees]> select count(*) from employees;+----------+| count(*) |+----------+| 300024 |+----------+1 row in set (0.08 sec)MariaDB [employees]> # How many managers?MariaDB [employees]> select count(*) from dept_manager;+----------+| count(*) |+----------+| 24 |+----------+1 row in set (0.00 sec)
清單 12 展示了如何使用 DISTINCT 函數來查看一些經理是否與其他經理在同一日期招聘的。
清單 12. 找到不同的開始日期MariaDB [employees]> describe dept_manager;+-----------+---------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------+---------+------+-----+---------+-------+| emp_no | int(11) | NO | PRI | NULL | || dept_no | char(4) | NO | PRI | NULL | || from_date | date | NO | | NULL | || to_date | date | NO | | NULL | |+-----------+---------+------+-----+---------+-------+4 rows in set (0.00 sec)MariaDB [employees]> select DISTINCT(from_date) from dept_manager order by from_date;+------------+| from_date |+------------+| 1985-01-01 || 1988-09-09 || 1988-10-17 || 1989-05-06 || 1989-12-17 || 1991-03-07 || 1991-04-08 || 1991-09-12 || 1991-10-01 || 1992-03-21 || 1992-04-25 || 1992-08-02 || 1992-09-08 || 1994-06-28 || 1996-01-03 || 1996-08-30 |+------------+16 rows in set (0.00 sec)
僅返回了 16 行。您可以組合 COUNT 和 DISTINCT 來獲得此數字,但您在 清單 12 中也有實際的開始日期。您對多個經理開始上任的日期還一無所知。
假設您想找到某位經理上任了多長時間。可以計算 from_date 與 to_date 的差,但是如何將此運算應用於目前正在任職的經理?表通常使用某種標記來表示當前日期,該日期也許是一個 NULL 值,也許是未來的一個日期。dept_manager 表使用一個未來的日期實現此目的。to_date 晚於今日表示該經理仍在任職。可使用 NOW 函數獲得當前的時間戳,或者使用 CURDATE 函數僅獲取當前日期。清單 13 展示了一種查找每位經理任職多少天的方式。
清單 13. 查找經理任職了多少天MariaDB [employees]> # Show marker for managers still managingMariaDB [employees]> select max(to_date) from dept_manager;+--------------+| max(to_date) |+--------------+| 9999-01-01 |+--------------+1 row in set (0.00 sec)MariaDB [employees]> # Calculate duration of management in daysMariaDB [employees]> select emp_no, datediff(least(to_date, curdate()),from_date) from dept_manager;+--------+-----------------------------------------------+| emp_no | datediff(least(to_date, curdate()),from_date) |+--------+-----------------------------------------------+| 110022 | 2464 || 110039 | 8869 || 110085 | 1811 || 110114 | 9522 || 110183 | 2636 || 110228 | 8697 || 110303 | 1347 || 110344 | 1423 || 110386 | 1489 || 110420 | 7074 || 110511 | 2671 || 110567 | 8662 || 110725 | 1586 || 110765 | 859 || 110800 | 1020 || 110854 | 7868 || 111035 | 2256 || 111133 | 9077 || 111400 | 2288 || 111534 | 9045 || 111692 | 1385 || 111784 | 1422 || 111877 | 1212 || 111939 | 7314 |+--------+-----------------------------------------------+24 rows in set (0.00 sec)使用別名
當您擁有長表達式時,比如 datediff(least(to_date,curdate()),from_date),您可能希望縮短列標題或為該表達式提供一個別名,因為您計劃在查詢中的其他地方使用它,例如在 WHERE 子句中。清單 14 展示了如何使用別名來提供更短的標題,查找所有現任經理任職了多少年。
清單 14. 使用別名表示更短的標題MariaDB [employees]> select emp_no AS Employee, (datediff(least(to_date, curdate()),from_date)/365.25) as Years from dept_manager where to_date > curdate();+----------+---------+| Employee | Years |+----------+---------+| 110039 | 24.2820 || 110114 | 26.0698 || 110228 | 23.8111 || 110420 | 19.3676 || 110567 | 23.7153 || 110854 | 21.5414 || 111133 | 24.8515 || 111534 | 24.7639 || 111939 | 20.0246 |+----------+---------+9 rows in set (0.00 sec)使用 GROUP BY 對數據進行分組
有時您想匯總來自某個表的信息。例如,您想知道在每個 10000 美元薪資區間內有多少員工。為此,可以使用 GROUP BY 子句對您的數據進行分組。清單 15 展示了如何做。
清單 15. 使用 GROUP BY 聚合數據MariaDB [employees]> describe salaries;+-----------+---------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------+---------+------+-----+---------+-------+| emp_no | int(11) | NO | PRI | NULL | || salary | int(11) | NO | | NULL | || from_date | date | NO | PRI | NULL | || to_date | date | NO | | NULL | |+-----------+---------+------+-----+---------+-------+4 rows in set (0.00 sec)MariaDB [employees]> select salary DIV 10000 as 10K, count(*) as Number from salaries where to_date > curdate() group by 10K;+------+--------+| 10K | Number |+------+--------+| 3 | 85 || 4 | 20220 || 5 | 44666 || 6 | 56236 || 7 | 49128 || 8 | 32351 || 9 | 19939 || 10 | 10611 || 11 | 4729 || 12 | 1645 || 13 | 421 || 14 | 78 || 15 | 15 |+------+--------+13 rows in set (1.42 sec)使用 HAVING 執行進一步選擇
在 清單 15 中,Number 列中的值是從聚合數據計算出來的。假設您僅對該范圍中擁有 5,000 或更少員工的薪資范圍感興趣。您的第一個想法可能是使用 WHERE 子句,但您不能使用它獲得計算為聚合數據的中間結果數據。您需要使用 HAVING 子句,將中間結果限制到一個具有特定條件或條件組合的子集。清單 16 展示了如何查找該范圍中擁有 5,000 或更少員工的薪資范圍。
清單 16. 使用 HAVING 子句MariaDB [employees]> select salary DIV 10000 as 10K, count(*) as Number from salaries where to_date > curdate() group by 10K HAVING Number < = 5000;+------+--------+| 10K | Number |+------+--------+| 3 | 85 || 11 | 4729 || 12 | 1645 || 13 | 421 || 14 | 78 || 15 | 15 |+------+--------+6 rows in set (1.45 sec)使用 JOIN 從多個表獲取數據
目前為止,本教程中的示例都使用了單個表。salaries 表和 dept_manager 表包含員工編號,但不含姓名或其他員工信息。員工信息保存在 employees 表中。通過將數據保存在單獨的表中,SQL 設計可以消除(或者至少減少)數據存儲冗余,以及在一個位置更新數據而不在另一個位置更新的相關風險。
在您想提取信息時,比如所有現任經理的姓名和性別,您需要從 dept_manager 表和 employees 表獲取此信息。出於這個目的,您使用 JOIN 子句和一個指定聯接 (join) 條件的條件表達式。最常見的是,您將兩個表聯接在單個字段上,該字段值在兩個表中相同,例如,dept_manager 表和 employees 表中都包含的 emp_no 字段。
清單 17 展示了如何使用 JOIN 查找所有現任經理的姓名和性別。(請注意,我們使用了別名 e 和 m 來表示 dept_manager 表和 employees 表。)
清單 17. 使用 JOIN 子句獲取現任經理信息MariaDB [employees]> SELECT e.first_name, e.last_name, e.gender FROM employees as e JOIN dept_manager as m ON e.emp_no = m.emp_no WHERE m.to_date > now() ORDER BY e.last_name;+------------+------------+--------+| first_name | last_name | gender |+------------+------------+--------+| Leon | DasSarma | F || Oscar | Ghazalie | M || Hilary | Kambil | F || Isamu | Legleitner | F || Vishwani | Minakawa | M || Dung | Pesch | M || Karsten | Sigstam | F || Yuchang | Weedman | M || Hauke | Zhang | M |+------------+------------+--------+9 rows in set (0.00 sec)
如果您想要使用薪資而不是性別作為輸出列,必須將 salaries 表與其他兩個表聯接,如 清單 18 所示。(我添加了一些括號,我發現括號對構造復雜查詢通常很有用。)
清單 18. 使用 JOIN 子句獲取現任經理薪資MariaDB [employees]> SELECT e.first_name, e.last_name, s.salary FROM (employees as e JOIN dept_manager as m ON e.emp_no = m.emp_no) JOIN salaries as s on e.emp_no = s.emp_no WHERE m.to_date > now() AND s.to_date > now() ORDER BY e.last_name;+------------+------------+--------+| first_name | last_name | salary |+------------+------------+--------+| Leon | DasSarma | 74510 || Oscar | Ghazalie | 56654 || Hilary | Kambil | 79393 || Isamu | Legleitner | 83457 || Vishwani | Minakawa | 106491 || Dung | Pesch | 72876 || Karsten | Sigstam | 65400 || Yuchang | Weedman | 58745 || Hauke | Zhang | 101987 |+------------+------------+--------+9 rows in set (0.00 sec)
清單 17 和 清單 18 中的 JOIN 示例稱為內部 聯接:它們從兩個表中查找與聯接條件匹配的行。另外 3 種常見的聯接是:
LEFT JOIN 查找左側表中的所有行和右側表中與該聯接條件匹配的行。
RIGHT JOIN 查找右側表中的所有行和左側表中與該聯接條件匹配的行。
OUTER JOIN 組合 LEFT JOIN 和 RIGHT JOIN 的結果。許多數據庫(包括 IBM DB2)將此稱為 FULL OUTER JOIN。
INNER JOIN 最常用,而且是沒有指定聯接類型時的默認選擇。清單 19 演示了如何使用 LEFT JOIN 來顯示選定的員工,如果他們恰好是經理,則顯示他們的 from_date 和 to_date。在這個示例中,我還使用了 LIMIT 值將輸出限制為最多 15 行。
清單 19. 使用 LEFT JOIN 子句MariaDB [employees]> SELECT e.emp_no, e.first_name, e.last_name, s.salary, m.from_date, m.to_date FROM (employees as e LEFT JOIN dept_manager as m ON e.emp_no = m.emp_no) JOIN salaries as s on e.emp_no = s.emp_no AND s.to_date > now() WHERE e.last_name LIKE 'Kambi%' AND e.first_name > 'G' ORDER BY e.last_name, e.first_name limit 15;+--------+------------+-----------+--------+------------+------------+| emp_no | first_name | last_name | salary | from_date | to_date |+--------+------------+-----------+--------+------------+------------+| 431582 | Gaurav | Kambil | 118128 | NULL | NULL || 252478 | Gaurav | Kambil | 69516 | NULL | NULL || 487991 | Gift | Kambil | 115960 | NULL | NULL || 204311 | Gil | Kambil | 96756 | NULL | NULL || 416604 | Gonzalo | Kambil | 80009 | NULL | NULL || 236164 | Hausi | Kambil | 66130 | NULL | NULL || 412003 | Hausi | Kambil | 83213 | NULL | NULL || 111534 | Hilary | Kambil | 79393 | 1991-04-08 | 9999-01-01 || 295702 | Huei | Kambil | 49498 | NULL | NULL || 77408 | Idoia | Kambil | 67122 | NULL | NULL || 271049 | Jianhao | Kambil | 58393 | NULL | NULL || 216820 | JiYoung | Kambil | 87541 | NULL | NULL || 206261 | Jongsuk | Kambil | 78396 | NULL | NULL || 250164 | Josyula | Kambil | 98835 | NULL | NULL || 289558 | Jouko | Kambil | 51393 | NULL | NULL |+--------+------------+-----------+--------+------------+------------+15 rows in set (0.14 sec)使用子選擇
有時您僅對查詢中的部分數據感興趣,希望僅操作這部分數據。出於此目的,您可以使用子選擇(也稱為子查詢),它實質上是 SELECT 中的另一個 SELECT。您還可以在 FROM、WHERE 或 HAVING 子句中使用子選擇。有時通過子選擇完成的工作也可以通過 JOIN 完成。考慮到如此多的選擇性,我將展示兩個示例來讓您了解這些。
employees 數據庫中的 titles 表顯示了一位員工已擔任的職位。一些員工擔任了多個職位。清單 20 展示了如何找到 3 位員工擔任的職位。請注意,我們使用了 IN 運算符來從一個集合中選擇結果,使用了 BETWEEN 運算符來選擇兩個值之間的員工數。
清單 20. 擔任了不同職位的員工MariaDB [employees]> describe titles;+-----------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-----------+-------------+------+-----+---------+-------+| emp_no | int(11) | NO | PRI | NULL | || title | varchar(50) | NO | PRI | NULL | || from_date | date | NO | PRI | NULL | || to_date | date | YES | | NULL | |+-----------+-------------+------+-----+---------+-------+4 rows in set (0.00 sec)MariaDB [employees]> select * from titles where emp_no IN (10001, 10004, 499666);+--------+--------------------+------------+------------+| emp_no | title | from_date | to_date |+--------+--------------------+------------+------------+| 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 || 10004 | Engineer | 1986-12-01 | 1995-12-01 || 10004 | Senior Engineer | 1995-12-01 | 9999-01-01 || 499666 | Assistant Engineer | 1987-10-18 | 1994-10-18 || 499666 | Engineer | 1994-10-18 | 2001-10-18 || 499666 | Senior Engineer | 2001-10-18 | 9999-01-01 |+--------+--------------------+------------+------------+6 rows in set (0.00 sec)MariaDB [employees]> select * from titles where emp_no BETWEEN 10001 AND 10004; +--------+-----------------+------------+------------+| emp_no | title | from_date | to_date |+--------+-----------------+------------+------------+| 10001 | Senior Engineer | 1986-06-26 | 9999-01-01 || 10002 | Staff | 1996-08-03 | 9999-01-01 || 10003 | Senior Engineer | 1995-12-03 | 9999-01-01 || 10004 | Engineer | 1986-12-01 | 1995-12-01 || 10004 | Senior Engineer | 1995-12-01 | 9999-01-01 |+--------+-----------------+------------+------------+5 rows in set (0.01 sec)
您已經知道如何使用 GROUP BY 和 COUNT 來查找每位員工擔任過多少個職位。如果只想知道多少員工擔任過一個職位,多少員工擔任過兩個職位等,該如何做? 清單 21 展示了如何構造一個查詢來查找每位員工擔任的職位數,然後如何使用此查詢作為一個查詢的子選擇,回答多少員工擔任過一個職位,多少員工擔任過兩個職位等問題。我將這個子查詢命名為 subq。該子查詢只返回一列:jobs。主要查詢使用限定名稱 subq.jobs 來引用此列。
清單 21. 使用子選擇來查找多少員工擔任過多個職位MariaDB [employees]> SELECT count(*) as jobs from titles group by emp_no limit 5;+------+| jobs |+------+| 1 || 1 || 1 || 2 || 2 |+------+5 rows in set (0.00 sec)MariaDB [employees]> SELECT jobs as '# jobs', count(subq.jobs) as '# employees' FROM ( SELECT count(*) as jobs from titles group by emp_no ) subq group by jobs;+--------+-------------+| # jobs | # employees |+--------+-------------+| 1 | 159754 || 2 | 137256 || 3 | 3014 |+--------+-------------+3 rows in set (0.31 sec)
現在假設您想知道公司中薪資最高的 10 位員工。清單 22 展示了另一個返回此信息的子選擇。
清單 22. 使用子選擇查找薪資最高的員工MariaDB [employees]> SELECT e.emp_no, e.last_name, e.first_name, ( SELECT MAX(salary) FROM salaries s WHERE e.emp_no = s.emp_no ) max_sal FROM employees e ORDER BY max_sal desc limit 10;+--------+-----------+------------+---------+| emp_no | last_name | first_name | max_sal |+--------+-----------+------------+---------+| 43624 | Pesch | Tokuyasu | 158220 || 254466 | Mukaidono | Honesty | 156286 || 47978 | Whitcomb | Xiahua | 155709 || 253939 | Luders | Sanjai | 155513 || 109334 | Alameldin | Tsutomu | 155377 || 80823 | Baca | Willard | 154459 || 493158 | Meriste | Lidong | 154376 || 205000 | Griswold | Charmane | 153715 || 266526 | Chenoweth | Weijing | 152710 || 237542 | Hatcliff | Weicheng | 152687 |+--------+-----------+------------+---------+10 rows in set (2.66 sec)
我提到過您有時可以使用 JOIN 完成子選擇的工作。清單 23 展示了如何使用 JOIN 查找薪資最高的 10 位員工。您可以注意到,此查詢的執行速度比 清單 22 的子選擇更快。一般而言,如果注重性能,首先應該選擇使用聯接而不是子選擇。性能差異取決於您的數據庫引擎。
清單 23. 使用 JOIN 查找薪資最高的員工MariaDB [employees]> SELECT e.emp_no, e.last_name, e.first_name, max(s.salary) as max_sal FROM employees e JOIN salaries s ON e.emp_no = s.emp_no GROUP BY e.emp_no ORDER BY max_sal desc limit 10;+--------+-----------+------------+---------+| emp_no | last_name | first_name | max_sal |+--------+-----------+------------+---------+| 43624 | Pesch | Tokuyasu | 158220 || 254466 | Mukaidono | Honesty | 156286 || 47978 | Whitcomb | Xiahua | 155709 || 253939 | Luders | Sanjai | 155513 || 109334 | Alameldin | Tsutomu | 155377 || 80823 | Baca | Willard | 154459 || 493158 | Meriste | Lidong | 154376 || 205000 | Griswold | Charmane | 153715 || 266526 | Chenoweth | Weijing | 152710 || 237542 | Hatcliff | Weicheng | 152687 |+--------+-----------+------------+---------+10 rows in set (2.16 sec)包含 ENUM 值的有趣結果
在 “了解表和列” 部分,我提到過 SQL 中的枚舉類型存在一些爭議。employees 表中的 gender 列是一個包含值 M 和 F 的 ENUM。這些值看起來像字符,但實際上它們在內部被存儲為整數。它們依據其內部數值表示而存儲在一個 ORDER BY 子句中,這可能帶來令人驚訝的結果。清單 24 展示了按性別排序的前 5 位員工。
清單 24. 通過 ENUM 字段排序輸出MariaDB [employees]> SELECT * FROM ( SELECT * FROM employees LIMIT 5 ) x ORDER BY x.gender;+--------+------------+------------+-----------+--------+------------+| emp_no | birth_date | first_name | last_name | gender | hire_date |+--------+------------+------------+-----------+--------+------------+| 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 || 10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 || 10004 | 1954-05-01 | Chirstian | Koblick | M | 1986-12-01 || 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 || 10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 |+--------+------------+------------+-----------+--------+------------+5 rows in set (0.00 sec)
您可能會奇怪地看到 M 值在 F 值之前列出。如果想按字母順序進行排列,可在 ORDERBY 子句中使用 CAST 或 CONVERT。例如:
ORDER BY CAST(x.gender AS CHAR)創建、更改和刪除數據和表
您已經學習了表和如何了解它們的結構。您還學習了如何創建 SQL 查詢,以便從一個或多個表中的數據中尋找答案。在本教程的剩余部分中,我將展示如何創建和操作表,如何插入、更新和刪除表中的數據。
創建表假設您決定為員工性別創建一個參考表,而不是使用枚舉。您決定提取性別的首字母,也就是英文字母 M 或 F。您還想要包含完整單詞 MALE 或 FEMALE 的另一列。第一步是使用 CREATE TABLE 創建該表。CREATE TABLE 的基本形式提供了一個表名稱,後跟一個列、索引和約束列表。清單 25 展示了如何創建包含兩個列的 gender 表,一個列是表示主鍵的字符,另一個列是一個最多 20 個字符的可變字符字段。
清單 25. 創建新表MariaDB [employees]> CREATE TABLE gender ( code CHAR(1) NOT NULL, gender VARCHAR(20) NOT NULL, PRIMARY KEY (code) );Query OK, 0 rows affected (0.23 sec)MariaDB [employees]> describe gender;+--------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+--------+-------------+------+-----+---------+-------+| code | char(1) | NO | PRI | NULL | || gender | varchar(20) | NO | | NULL | |+--------+-------------+------+-----+---------+-------+2 rows in set (0.00 sec)插入、更新和刪除數據
現在您有一個空表,您需要在其中填入數據。使用 INSERT 命令加載一行或多行數據。您指定想要在其中插入數據的列的列表,然後指定一個或多個匹配值列表。清單 26 展示了如何添加您計劃的兩行。
清單 26. 在 gender 表中插入數據MariaDB [employees]> INSERT INTO gender (code, gender) VALUES ('F', 'FEMALE'), ('M', 'MALE');Query OK, 2 rows affected (0.03 sec)Records: 2 Duplicates: 0 Warnings: 0MariaDB [employees]> select * from gender;+------+--------+| code | gender |+------+--------+| F | FEMALE || M | MALE |+------+--------+2 rows in set (0.00 sec)
接下來假設您認為一些員工可能需要在您知道其性別之前添加到數據庫中,所以您決定為 UNASSIGNED 性別添加第三種可能性。清單 27 展示了另一種插入數據的方式:通過使用 SET 子句。
清單 27. 在 gender 表中插入一個新行MariaDB [employees]> INSERT INTO gender SET code='U', gender='UNSIGNED';Query OK, 1 row affected (0.04 sec)MariaDB [employees]> select * from gender;+------+----------+| code | gender |+------+----------+| F | FEMALE || M | MALE || U | UNSIGNED |+------+----------+3 rows in set (0.00 sec)
我使用的示例數據庫只有兩個 gender 值。假設您的公司采用了一種性別多樣性策略,您需要為具有多樣性性別的員工提供額外的值。使用 VALUES 選項或 SET 選項和 INSERT INTO 向您的表中插入更多行。
由於錄入錯誤,我本來打算插入 UNASSIGNED,但插入了 UNSIGNED。使用 UPDATE 命令修復此錯誤,如 清單 28 所示。
MariaDB [employees]> UPDATE gender SET gender='UNASSIGNED' WHERE code='U';Query OK, 1 row affected (0.03 sec)Rows matched: 1 Changed: 1 Warnings: 0MariaDB [employees]> select * from gender;+------+------------+| code | gender |+------+------------+| F | FEMALE || M | MALE || U | UNASSIGNED |+------+------------+3 rows in set (0.00 sec)
現在人力資源經理告訴您,該公司始終在將新員工添加到數據庫之前就知道該員工的性別,所以您需要刪除表示未分配性別的條目。使用 DELETE 命令,如 清單 29 所示。
清單 29. 刪除一個表行MariaDB [employees]> DELETE FROM gender WHERE code='U';Query OK, 1 row affected (0.04 sec)MariaDB [employees]> select * from gender;+------+--------+| code | gender |+------+--------+| F | FEMALE || M | MALE |+------+--------+2 rows in set (0.00 sec)修改表
有時您希望更改一個表。您可以執行的部分操作包括:
重命名一列。
添加一個新列。
刪除一列。
更改一列的數據類型。
更改一列上的約束。
清單 30 展示了如何修改 gender 表來添加一個新列 gender_fr,表示 gender 列的法語版本,加載新的法語數據,然後將現有的 gender 列重命名為 gender_en。
清單 30. 修改 gender 表MariaDB [employees]> ALTER TABLE gender ADD COLUMN gender_fr VARCHAR(20) AFTER gender;Query OK, 0 rows affected (0.38 sec)Records: 0 Duplicates: 0 Warnings: 0MariaDB [employees]> UPDATE gender SET gender_fr='MASCULIN' WHERE code='M';Query OK, 1 row affected (0.03 sec)Rows matched: 1 Changed: 1 Warnings: 0MariaDB [employees]> UPDATE gender SET gender_fr='FÉMININ' WHERE code='F';Query OK, 1 row affected (0.04 sec)Rows matched: 1 Changed: 1 Warnings: 0MariaDB [employees]> ALTER TABLE gender CHANGE COLUMN gender gender_en VARCHAR(20);Query OK, 0 rows affected (0.38 sec)Records: 0 Duplicates: 0 Warnings: 0MariaDB [employees]> select * from gender;+------+-----------+-----------+| code | gender_en | gender_fr |+------+-----------+-----------+| F | FEMALE | FÉMININ || M | MALE | MASCULIN |+------+-----------+-----------+2 rows in set (0.00 sec)創建表和視圖的其他方式
您還可以創建一個表並填入來自一個 SELECT 的數據。清單 31 展示了一個創建女性員工表的簡單示例。
清單 31. 創建一個女性員工表MariaDB [employees]> create table female_employees select * from employees where gender='F';Query OK, 120051 rows affected (3.22 sec)Records: 120051 Duplicates: 0 Warnings: 0
當您以這種方式創建表時,新表可能未繼承來源表的所有屬性。比較 清單 32 中的表描述。您可以注意到,female_employees 表沒有鍵。
清單 32. 比較 employees 和 female_employees 表MariaDB [employees]> describe employees;+------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+------------+---------------+------+-----+---------+-------+| emp_no | int(11) | NO | PRI | NULL | || birth_date | date | NO | | NULL | || first_name | varchar(14) | NO | | NULL | || last_name | varchar(16) | NO | | NULL | || gender | enum('M','F') | NO | | NULL | || hire_date | date | NO | | NULL | |+------------+---------------+------+-----+---------+-------+6 rows in set (0.00 sec)MariaDB [employees]> describe female_employees;+------------+---------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+------------+---------------+------+-----+---------+-------+| emp_no | int(11) | NO | | NULL | || birth_date | date | NO | | NULL | || first_name | varchar(14) | NO | | NULL | || last_name | varchar(16) | NO | | NULL | || gender | enum('M','F') | NO | | NULL | || hire_date | date | NO | | NULL | |+------------+---------------+------+-----+---------+-------+6 rows in set (0.00 sec)
如果您使用現有數據來創建表,還需要考慮如何計劃未來將該數據保存在兩個同步的表中。在這個示例中,您可能想要一個 VIEW,它使您能夠像表一樣使用 SELECT 的結果。數據保留在一個或多個基礎表中,而且僅需要更新一個副本。清單 33 展示了如何創建男性員工的視圖。請注意視圖名稱與 SELECT 之間的單詞 AS。
清單 33. 創建男性員工的視圖MariaDB [employees]> CREATE VIEW male_employees AS select * from employees where gender='M';Query OK, 0 rows affected (0.05 sec)MariaDB [employees]> select * from male_employees limit 5;+--------+------------+------------+-----------+--------+------------+| emp_no | birth_date | first_name | last_name | gender | hire_date |+--------+------------+------------+-----------+--------+------------+| 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 || 10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 || 10004 | 1954-05-01 | Chirstian | Koblick | M | 1986-12-01 || 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 || 10008 | 1958-02-19 | Saniya | Kalloufi | M | 1994-09-15 |+--------+------------+------------+-----------+--------+------------+5 rows in set (0.00 sec)
如果您想知道數據庫中的哪些表是真正的視圖,一個命令可以幫助您。不同的數據庫使用不同的命令。在 MariaDB 中,使用:
show full tables
創建表時,您可以組合您的列規范和 SELECT 的結果。作為最後一個創建表的示例, 清單 34 展示了創建一種包含使用 CHAR(1) 字段而不是枚舉值來表 gender 的 employees 表的副本的方式,以及如何使用 IF 語句設置此值。
清單 34. 創建 employees 表的一個修訂的副本MariaDB [employees]> CREATE TABLE employees_new ( emp_no int(11) NOT NULL, birth_date date NOT NULL, first_name varchar(14) NOT NULL, last_name varchar(16) NOT NULL, gender CHAR(1), hire_date date NOT NULL, PRIMARY KEY (emp_no) ) select emp_no, birth_date, first_name, last_name, IF(gender = 'M', 'M', 'F') as gender, hire_date from employees;Query OK, 300024 rows affected (5.92 sec)Records: 300024 Duplicates: 0 Warnings: 0MariaDB [employees]> describe employees_new;+------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+------------+-------------+------+-----+---------+-------+| emp_no | int(11) | NO | PRI | NULL | || birth_date | date | NO | | NULL | || first_name | varchar(14) | NO | | NULL | || last_name | varchar(16) | NO | | NULL | || gender | char(1) | YES | | NULL | || hire_date | date | NO | | NULL | |+------------+-------------+------+-----+---------+-------+6 rows in set (0.00 sec)
外鍵的創建和維護不屬於這篇介紹性教程的討論范圍。但是,您仍然可以使用 JOIN 聯接 employees_new 和 gender 表來執行查詢,比如我在 清單 35 中演示的查詢。
清單 35. 聯接 employees_new 和 genderMariaDB [employees]> select e.emp_no, e.first_name, e.last_name, e.gender, g.gender_en, g.gender_fr from employees_new e join gender g on e.gender=g.code limit 5;+--------+------------+-----------+--------+-----------+-----------+| emp_no | first_name | last_name | gender | gender_en | gender_fr |+--------+------------+-----------+--------+-----------+-----------+| 10001 | Georgi | Facello | M | MALE | MASCULIN || 10002 | Bezalel | Simmel | F | FEMALE | FÉMININ || 10003 | Parto | Bamford | M | MALE | MASCULIN || 10004 | Chirstian | Koblick | M | MALE | MASCULIN || 10005 | Kyoichi | Maliniak | M | MALE | MASCULIN |+--------+------------+-----------+--------+-----------+-----------+5 rows in set (0.00 sec)刪除表和數據庫
我展示了如何使用 DELETE 從表中刪除行。如果您想要刪除一列而不是一行,則需要使用 ALTER TABLE。例如,如果您希望從 female_employees 表刪除 gender 列,可以使用 清單 36 中演示的命令。
清單 36. 從 female_employees 表刪除 gender 列MariaDB [employees]> ALTER TABLE female_employees DROP COLUMN gender;Query OK, 0 rows affected (4.32 sec) Records: 0 Duplicates: 0 Warnings: 0MariaDB [employees]> describe female_employees;+------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+------------+-------------+------+-----+---------+-------+| emp_no | int(11) | NO | | NULL | || birth_date | date | NO | | NULL | || first_name | varchar(14) | NO | | NULL | || last_name | varchar(16) | NO | | NULL | || hire_date | date | NO | | NULL | |+------------+-------------+------+-----+---------+-------+5 rows in set (0.00 sec)
要丟棄 female_employees 表和 male_employees 視圖,可以使用 DROP TABLE 和 DROP VIEW 命令,如 清單 37 所示。
清單 37. 刪除 female_employees 表和 male_employees 視圖MariaDB [employees]> drop table female_employees;Query OK, 0 rows affected (0.14 sec)MariaDB [employees]> drop view male_employees;Query OK, 0 rows affected (0.00 sec)
如果您想刪除整個 employees 數據庫和它的所有表,可以使用 DROP DATABASE 命令,如 清單 38 所示。
清單 38. 刪除整個 employees 數據庫MariaDB [employees]> drop database employees;Query OK, 10 rows affected (0.92 sec)
對 SQL 的簡要介紹到此就結束了。我只簡單介紹了一個大型項目的很少的一部分,您可以使用本教程作為起點來進一步探索。
原文來自:http://www.ibm.com/developerworks/cn/linux/l-lpic1-105-3/index.html
本文地址:http://www.linuxprobe.com/linux-sql-command.html
http://xxxxxx/Linuxjc/1139891.html TechArticle