本筆記為天池SQL訓練營筆記:https://tianchi.aliyun.com/forum/postDetail?spm=5176.20222307.J_9059755190.2.92034cb3sVZvJi&postId=163421
一、初識數(shù)據(jù)庫
數(shù)據(jù)庫(Database,DB):本質上是數(shù)據(jù)集合
RDBMS(Database Management System,DBMS):數(shù)據(jù)庫管理系統(tǒng),是軟件工具
1.1 DBMS的種類
DBMS 主要通過數(shù)據(jù)的保存格式(數(shù)據(jù)庫的種類)來進行分類,現(xiàn)階段主要有以下 5 種類型:

1.2 RDBMS的常見系統(tǒng)結構

二、初識SQL
2.1 概念介紹

記錄:數(shù)據(jù)庫中的行
字段:數(shù)據(jù)庫中的列
根據(jù)對 RDBMS 賦予的指令種類的不同,SQL 語句可以分為以下三類:

2.2 SQL的基本書寫規(guī)則
SQL語句要以分號( ; )結尾
SQL 不區(qū)分關鍵字的大小寫,但是插入到表中的數(shù)據(jù)是區(qū)分大小寫的
win 系統(tǒng)默認不區(qū)分表名及字段名的大小寫;linux / mac 默認嚴格區(qū)分表名及字段名的大小寫
常數(shù)的書寫方式是固定的:'abc', 1234, '26 Jan 2010', '10/01/26', '2010-01-26'…
單詞需要用半角空格或者換行來分隔
2.3 數(shù)據(jù)庫的創(chuàng)建( CREATE DATABASE 語句)
語法:
CREATE DATABASE <數(shù)據(jù)庫名稱>;
示例:
CREATE DATABASE shop;
2.4 表的創(chuàng)建( CREATE TABLE 語句)
語法:
CREATE TABLE < 表名 >
( < 列名 1> < 數(shù)據(jù)類型 > < 該列所需約束 > ,
< 列名 2> < 數(shù)據(jù)類型 > < 該列所需約束 > ,
< 列名 3> < 數(shù)據(jù)類型 > < 該列所需約束 > ,
< 列名 4> < 數(shù)據(jù)類型 > < 該列所需約束 > ,
.
.
.
< 該表的約束 1> , < 該表的約束 2> ,……);
示例:
CREATE TABLE product(
product_id CHAR(4) NOT NULL,
product_name VARCHAR(100) NOT NULL,
product_type VARCHAR(32) NOT NULL,
sale_price INTEGER,
purchase_price INTEGER,
regist_date DATE,
PRIMARY KEY(product_id)
) ;
2.5 命名規(guī)則
- 只能使用半角英文字母、數(shù)字、下劃線(_)作為數(shù)據(jù)庫、表和列的名稱
- 名稱必須以半角英文字母開頭
2.6 數(shù)據(jù)類型的指定
數(shù)據(jù)庫創(chuàng)建的表,所有的列都必須指定數(shù)據(jù)類型,每一列都不能存儲與該列數(shù)據(jù)類型不符的數(shù)據(jù)。
4種最基本的數(shù)據(jù)類型:
- INTEGER 型:存儲整數(shù)的列的數(shù)據(jù)類型(數(shù)字型),不能存儲小數(shù)。
- CHAR 型:存儲定長字符串,當列中存儲的字符串長度達不到最大長度的時候,使用半角空格進行補足,由于會浪費存儲空間,所以一般不使用。
- VARCHAR 型:存儲可變長度字符串,定長字符串在字符數(shù)未達到最大長度時會用半角空格補足,但可變長字符串不同,即使字符數(shù)未達到最大長度,也不會用半角空格補足。
- DATE 型:指定存儲日期(年月日)的列的數(shù)據(jù)類型(日期型)。
2.7 約束的設置
約束是除了數(shù)據(jù)類型之外,對列中存儲的數(shù)據(jù)進行限制或者追加條件的功能。
-
NOT NULL:非空約束,即該列必須輸入數(shù)據(jù)。 -
PRIMARY KEY:主鍵約束,代表該列是唯一值,可以通過該列取出特定的行的數(shù)據(jù)。
2.8 表的刪除和更新
刪除表的語法:
DROP TABLE < 表名 > ;
-- 刪除 product 表:
DROP TABLE product;
添加列的語法:
ALTER TABLE < 表名 > ADD COLUMN < 列的定義 >;
-- 添加一列可以存儲100位的可變長字符串的 product_name_pinyin 列:
ALTER TABLE product ADD COLUMN product_name_pinin VARCHAR(100);
刪除列的語法:
ALTER TABLE < 表名 > DROP COLUMN < 列名 >;
-- 刪除 product_name_pinyin 列:
ALTER TABLE product DROP COLUMN product_name_pinyin;
ALTER TABLE 語句和 DROP TABLE 語句一樣,執(zhí)行之后無法恢復。
清空表的語法:
TRUNCATE TABLE < 表名 >;
優(yōu)點:相比drop/delete,truncate用來清除數(shù)據(jù)時,速度更快。
數(shù)據(jù)更新的語法:
UPDATE <表名>
SET <列名> = <表達式> [, <列名2>=<表達式2>...];
WHERE <條件>; -- 可選,非常重要。
ORDER BY 子句; --可選
LIMIT 子句; --可選
使用 update 時要注意添加 where 條件,否則將會將所有的行按照語句修改:
-- 修改所有的注冊時間
UPDATE product
SET regist_date = '2009-10-10';
-- 僅修改部分商品的單價
UPDATE product
SET sale_price = sale_price * 10
WHERE product_type = '廚房用具';
使用 UPDATE 也可以將列更新為 NULL(該更新俗稱為NULL清空)。此時只需要將賦值表達式右邊的值直接寫為 null 即可:
-- 將商品編號為0008的數(shù)據(jù)(圓珠筆)的登記日期更新為NULL
UPDATE product
SET regist_date = NULL
WHERE product_id = '0008';
和 INSERT 語句一樣, UPDATE 語句也可以將 NULL 作為一個值來使用。
但是,只有未設置 NOT NULL 約束和主鍵約束的列才可以清空為NULL。如果將設置了上述約束的列更新為 NULL,就會出錯,這點與INSERT 語句相同。
多列更新的語法:
UPDATE product
SET sale_price = sale_price * 10,
purchase_price = purchase_price / 2
WHERE product_type = '廚房用具';
2.9 向 product 表中插入數(shù)據(jù)
我們首先創(chuàng)建一個名為productins的表:
CREATE TABLE productins
(product_id CHAR(4) NOT NULL,
product_name VARCHAR(100) NOT NULL,
product_type VARCHAR(32) NOT NULL,
sale_price INTEGER DEFAULT 0,
purchase_price INTEGER ,
regist_date DATE ,
PRIMARY KEY (product_id));
插入數(shù)據(jù)的語法:
INSERT INTO <表名> (列1, 列2, 列3, ……) VALUES (值1, 值2, 值3, ……);
對表進行全列 INSERT 時,可以省略表名后的列清單。這時 VALUES子句的值會默認按照從左到右的順序賦給每一列。
-- 包含列清單
INSERT INTO productins (product_id, product_name, product_type,
sale_price, purchase_price, regist_date) VALUES ('0005', '高壓鍋', '廚房用具', 6800, 5000, '2009-01-15');
-- 省略列清單
INSERT INTO productins
VALUES ('0005', '高壓鍋', '廚房用具', 6800, 5000, '2009-01-15');
原則上,執(zhí)行一次 INSERT 語句會插入一行數(shù)據(jù)。插入多行時,通常需要循環(huán)執(zhí)行相應次數(shù)的 INSERT 語句。其實很多 RDBMS 都支持一次插入多行數(shù)據(jù):
-- 通常的INSERT
INSERT INTO productins VALUES ('0002', '打孔器',
'辦公用品', 500, 320, '2009-09-11');
INSERT INTO productins VALUES ('0003', '運動T恤',
'衣服', 4000, 2800, NULL);
INSERT INTO productins VALUES ('0004', '菜刀',
'廚房用具', 3000, 2800, '2009-09-20');
-- 多行INSERT ( DB2、SQL、SQL Server、 PostgreSQL 和 MySQL多行插入)
INSERT INTO productins VALUES ('0002', '打孔器',
'辦公用品', 500, 320, '2009-09-11'),
('0003', '運動T恤', '衣服', 4000, 2800, NULL),
('0004', '菜刀', '廚房用具', 3000, 2800, '2009-09-20');
-- Oracle中的多行INSERT
INSERT ALL INTO productins VALUES ('0002', '打孔器', '辦公用品', 500, 320, '2009-09-11')
INTO productins VALUES ('0003', '運動T恤', '衣服', 4000, 2800, NULL)
INTO productins VALUES ('0004', '菜刀', '廚房用具', 3000, 2800, '2009-09-20')
SELECT * FROM DUAL;
-- DUAL是Oracle特有(安裝時的必選項)的一種臨時表A。因此“SELECT *FROM DUAL” 部分也只是臨時性的,并沒有實際意義。
INSERT 語句中想給某一列賦予 NULL 值時,可以直接在 VALUES子句的值清單中寫入 NULL。想要插入 NULL 的列一定不能設置 NOT NULL 約束。
INSERT INTO productins (product_id, product_name, product_type,
sale_price, purchase_price, regist_date) VALUES ('0006', '叉子',
'廚房用具', 500, NULL, '2009-09-20');
插入默認值:
CREATE TABLE productins
(product_id CHAR(4) NOT NULL,
(略)
sale_price INTEGER
(略) DEFAULT 0, -- 銷售單價的默認值設定為0;
PRIMARY KEY (product_id));
使用INSERT … SELECT 語句從其他表復制數(shù)據(jù):
-- 將商品表中的數(shù)據(jù)復制到商品復制表中
INSERT INTO productocpy (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
SELECT product_id, product_name, product_type, sale_price,
purchase_price, regist_date
FROM Product;
- DML :插入數(shù)據(jù)
START TRANSACTION;
INSERT INTO product VALUES('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20');
INSERT INTO product VALUES('0002', '打孔器', '辦公用品', 500, 320, '2009-09-11');
INSERT INTO product VALUES('0003', '運動T恤', '衣服', 4000, 2800, NULL);
INSERT INTO product VALUES('0004', '菜刀', '廚房用具', 3000, 2800, '2009-09-20');
INSERT INTO product VALUES('0005', '高壓鍋', '廚房用具', 6800, 5000, '2009-01-15');
INSERT INTO product VALUES('0006', '叉子', '廚房用具', 500, NULL, '2009-09-20');
INSERT INTO product VALUES('0007', '擦菜板', '廚房用具', 880, 790, '2008-04-28');
INSERT INTO product VALUES('0008', '圓珠筆', '辦公用品', 100, NULL, '2009-11-11');
COMMIT;
三、練習題
3.1 編寫一條 CREATE TABLE 語句,用來創(chuàng)建一個包含表 1-A 中所列各項的表 Addressbook (地址簿),并為 regist_no (注冊編號)列設置主鍵約束。

DROP TABLE IF EXISTS Addressbook;
CREATE TABLE Addressbook(
registno INTEGER NOT NULL,
`name` VARCHAR(128) NOT NULL,
address VARCHAR(256) NOT NULL,
tel_no CHAR(10),
mail_address CHAR(20),
PRIMARY KEY(registno)
);
3.2 假設在創(chuàng)建練習1.1中的 Addressbook 表時忘記添加如下一列 postal_code (郵政編碼)了,請把此列添加到 Addressbook 表中。
-- 列名 : postal_code
-- 數(shù)據(jù)類型 :定長字符串類型(長度為 8)
-- 約束 :不能為 NULL
ALTER TABLE Addressbook ADD COLUMN postal_code CHAR(8) NOT NULL;
3.3 編寫 SQL 語句來刪除 Addressbook 表。
DROP TABLE Addressbook;
3.4 編寫 SQL 語句來恢復刪除掉的 Addressbook 表。
刪除后的表?法使?命令進?恢復