
本·福達
SQL是使用最爲廣泛的數據庫語言,幾乎所有重要的DBMS都支持SQL。本書是麻省理工學院、伊利諾伊大學等衆多大學的參考教材,由淺入深地講解了SQL的基本概念和語法,涉及數據的排序、過濾和分組,以及表、視圖、聯結、子查詢、遊標、存儲過程和觸發器等內容,實例豐富,便於查閱。與其他同類圖書不同,本書沒有過多闡述數據庫基礎理論,而是專門針對一線軟件開發人員,直接從SQLSELECT開始,講述實際工作環境中最常用和最必需的SQL知識,實用性極強。新版對書中的案例進行了全面的更新,並增加了章後挑戰題,便於讀者鞏固所學知識。
可恨的是爲什麼不同DBMS的語法不一樣。本書對新手很友好,講的很詳細,上一秒糾結的點,下一秒作者就告訴你了。本書對於18課19課20課21課的講解不深,只能瞭解到視圖、存儲過程,管理事務處理和遊標具體是什麼,淺嘗輒止,但作爲入門書個人感覺夠了,整理筆記如下(可直接寫入.sql文件),希望幫到你們。 -- 《SQL必知必會》第二章 檢索數據 /* SELECT prod_name, prod_prIce FROM products;# 這是一條註釋 -- 這也是一條註釋 /* 這是一段註釋 */ /* SELECT DISTINCT prod_id FROM orderitems; -- 只檢索出不同的 SELECT prod_name FROM products LIMIT 5; -- 只看前五條 SELECT prod_name FROM products LIMIT 5 OFFSET 4;-- 丟掉前四行,看後面的五行 SELECT prod_name FROM products LIMIT 4,5;-- 丟掉前四行,看後面的五行 SELECT * FROM products; -- 檢索表中所有的列 */ -- 《SQL必知必會》第三章 排序檢索數據 /* SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price,prod_name; -- 排序數據,先按price排,一致再按name排,升序 SELECT prod_id, prod_price, prod_name FROM products ORDER BY 2, 3; -- 排序數據,從0列開始,先按照第二列排,再按照第三列排,升序 SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price DESC; # 按照 price 降序排序數據 SELECT prod_id, prod_price, prod_name FROM products ORDER BY prod_price DESC,prod_name DESC; # 多個列降序必須在每個列背後加上DESC */ # 1檢索2過濾3排序4限制 -- 《SQL必知必會》第四章 過濾數據 /* SELECT prod_id, prod_price, prod_name FROM products WHERE prod_price > 6 ORDER BY prod_price,prod_name; -- WHERE子句操作符 # WHERE 子句操作符: =,!=,<>,>.>=,!<,<=.!>,IS NULL, BETWEEN a AND b(包含a和b) */ -- 《SQL必知必會》第五章 高級數據過濾 /* SELECT prod_id, prod_price, prod_name FROM products WHERE vend_id = 'BRS01' AND prod_price > 7; SELECT prod_id, prod_price, prod_name FROM products WHERE prod_price < 4 OR prod_price > 7; # WHERE 子句可以包含任意數量的 OR 和 AND , 順序是括號>與>或; # 列出價格爲10美元以上,由DLL01或BRS01 製造的所有產品 SELECT prod_name, prod_price FROM products WHERE prod_price > 10 and (vend_id = 'DLL01' OR vend_id = 'BRS01'); SELECT prod_name, prod_price FROM products WHERE vend_id IN ('DLL01','BRS01') ORDER BY prod_name; -- IN 指定條件範圍 SELECT prod_name FROM products WHERE NOT vend_id = 'DLL01' ORDER BY prod_name; -- NOT 否定跟在其後的條件 */ -- 《SQL必知必會》第六章 用通配符進行過濾; /* SELECT prod_id, prod_name FROM products WHERE prod_name LIKE 'Fish%';-- 通配符'%'表示任何字符出現任意次數 SELECT prod_id, prod_name FROM products WHERE prod_name LIKE '__ inch teddy bear';-- 通配符'_'只匹配單個字符 -- 通配符'[]'指定一個字符集,必須匹配所在位置的一個字符, MYSQL 不支持 # 不要過度使用通配符,用通配符儘量不放在開頭 */ -- 《SQL必知必會》第七章 創建計算字段; /* SELECT concat(RTRIM(vend_name),'(',RTRIM(vend_country),')') FROM vendors ORDER BY vend_name; -- MYSQL用 concat()函數拼接,RTRIM去除右空格 SELECT prod_name AS pname FROM products; -- 別名 AS SELECT prod_id, quantity, item_price, quantity * item_price AS totalprice FROM orderitems where order_num = 20008; -- totalprice 是一個計算字段除了* 還有+,-,/ */ -- 《SQL必知必會》第八章 使用函數處理數據; /* -- 函數upper()將文本轉換爲大寫,lower()轉小寫 -- MYSQL中提取字符串用substring()函數,用法爲substring(str,pos,len)從str的pos位置開始提取長爲len的字符串,pos可選 SELECT cust_name, cust_contact FROM customers WHERE soundex(cust_contact) = soundex('Michael Green');-- soundex()函數用於發音檢索 SELECT order_num FROM orders WHERE year(order_date) = 2020; -- MYSQL 用year()函數提取年份,month()函數提取月份 -- 數值處理函數 abs(), cos(), exp(), pi()返回Π的值, sin(), sqrt(), tan(). */ -- 《SQL必知必會》第九章 匯總數據; # SQL的五個聚集函數 avg()返回某列平均值,count()行數,,max()最大值,min()最小值,sum()某列值之和; -- 《SQL必知必會》第十章 分組數據; /* SELECT vend_id, COUNT(*) AS num_prods FROM products GROUP BY vend_id; -- 按照 vend_id分組並計算每組行數,GROUP BY中列出的必須是檢索列,不能是聚集函數 SELECT cust_id, count(*) AS orders FROM orders GROUP BY cust_id HAVING COUNT(*) >= 2 -- WHERE對行過濾, HAVING對組過濾 */ -- 《SQL必知必會》第十一章 使用子查詢; /* SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'RGAN01'); -- 子查詢,可以子查詢裏面再有子查詢 # 子查詢的SELECT語句只能返回單個列 SELECT cust_name, cust_state,(SELECT count(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name; */ -- 《SQL必知必會》第十二章 聯結(join)表; /* SELECT vend_name, prod_name, prod_price FROM vendors, products WHERE vendors.vend_id = products.vend_id; -- 創建聯結 # 完全限定列名:表名.列名 SELECT vend_name, prod_name, prod_price FROM products INNER JOIN vendors ON products.vend_id = vendors.vend_id -- 使用內聯結創建聯結 */ -- 《SQL必知必會》第十三章 創建高級聯結; /* SELECT cust_name, cust_contact FROM customers AS C, orders AS O, orderitems AS OI WHERE C.cust_id = O.cust_id AND O.order_num = OI.order_num AND prod_id = 'RGAN01'; -- 對錶使用別名 # 自聯結 SELECT c1.cust_id, c1.cust_name, c1.cust_contact FROM customers AS c1, customers AS c2# 對同一個表使用不同別名 WHERE c1.cust_name = c2.cust_name AND c2.cust_contact = 'Jim Jones'; # 自然聯結 SELECT c.*, o.order_num, o.order_date, oi.prod_id, oi.quantity, oi.item_price FROM customers AS c, orders AS o, orderitems AS oi WHERE c.cust_id = o.cust_id AND oi.order_num = o.order_num AND prod_id = 'RGAN01'; # 外聯結 SELECT customers.cust_id, orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id; -- OUT JOIN 指定了聯結類型時外聯結,LEFT指包含左表-orders的所有行 */ -- 《SQL必知必會》第十四章 組合查詢; /* SELECT cust_name, cust_contact, cust_email FROM customers WHERE cust_state IN ('IL','IN','MI') UNION -- UNION指示DBMS執行這兩條SELECT語句,並把輸出組合成一個查詢結果集 SELECT cust_name, cust_contact, cust_email FROM customers WHERE cust_name = 'Fun4All'; # UNION 默認取消重複的行,可用 UNION ALL不取消重複行 # ORDER BY 只能放在最後一個SELECT語句的最後 */ -- 《SQL必知必會》第十五章 插入數據; /* INSERT INTO customers VALUES(1000000006, 'Toy Land', '123 Any Street', 'New York', 'NY', '11111', 'USA', NULL, NULL); -- 在表customers中插入完整的的行 INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)-- 指定列名插入更安全 VALUES (1000000006, 'Toy Land', '123 Any Street', 'New York', 'NY', '11111', 'USA', NULL, NULL); # 在表的定義允許的情況下,只給出一行部分列名插入數據,就能插入部分行了(省略某幾列) INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) SELECT cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email FROM CustNew;-- INSERT SELECT語句合併表,將custnew表合併到customers中 # 複製表 CREATE TABLE customers_new AS SELECT * FROM customers; -- 複製一個customers表,名爲customers_new */ -- 《SQL必知必會》第十六章 更新和刪除數據; /* # 更新/刪除數據 UPDATE/DELETE 語句,有更新/刪除特定行和更新/刪除所有行兩種更新方式 UPDATE Customers -- 要更新的表 SET cust_email = '[email protected]' -- 列名和新值 WHERE cust_id = 1000000005; -- 過濾條件 # 更新多個列 UPDATE Customers SET cust_contact = 'Sam Roberts', cust_email = '[email protected]' WHERE cust_id = 1000000006; # 刪除一行 DELETE FROM Customers WHERE cust_id = 1000000006; */ -- 《SQL必知必會》第十七章 創建操縱表; # 創建表 /* CREATE TABLE Products ( prod_id CHAR(10) NOT NULL, vend_id CHAR(10) NOT NULL, prod_name CHAR(254) NOT NULL, prod_price DECIMAL(8,2) NOT NULL, prod_desc VARCHAR(1000) NULL -- NULL爲默認設置,可省略,如果不指定NOT NULL,就是NULL );*/ /* CREATE TABLE OrderItems ( order_num INTEGER NOT NULL, order_item INTEGER NOT NULL, prod_id CHAR(10) NOT NULL, quantity INTEGER NOT NULL DEFAULT 1, -- 如果沒給具體值就默認爲1 item_price DECIMAL(8,2) NOT NULL -- 對於日期,設定默認爲當前日期語句爲 DEFAULT CURRENT_DATE() );*/ # 更新表 /* ALTER TABLE Vendors ADD vend_phone CHAR(20); -- 給vendors表增加一個名爲vendor_phone的列 ALTER TABLE Vendors DROP COLUMN vend_phone; -- 給vendors 表刪除vend_phone列 DROP TABLE custcopy; -- 刪除custcopy表*/ -- 《SQL必知必會》第十八章 使用視圖; # 視圖是虛擬的表,本身不包含數據,只包含在需要使用時執行動態檢索的查詢語句 # 創建視圖 /*CREATE VIEW ProductCustomers AS SELECcust_name, cust_contact, prod_id FROM Customers, Orders, OrderItems WHERE Customers.cust_id = Orders.cust_id AND OrderItems.order_num = Orders.order_num;*/ # 調用視圖 SELECT cust_name, cust_contact FROM ProductCustomers WHERE prod_id = 'RGAN01'; -- 《SQL必知必會》第十九章 使用存儲過程; # 簡單來說,存儲過程就是爲以後使用而保存的一條或多條SQL語句。類似於python的函數 # 使用存儲過程有三個主要的好處,即簡單、安全、高性能。 -- 《SQL必知必會》第二十章 管理事物處理; # 使用事務處理(transaction processing),通過確保成批的SQL操作要麼完全執行,要麼完全不執行,來維護數據庫的完整性。 # COMMIT用於在執行一系列操作不出錯時提交語句 # ROLLBACK 相當於遊戲中的存檔點 -- 《SQL必知必會》第二十一章 使用遊標; # 遊標(cursor)是一個存儲在DBMS服務器上的數據庫查詢,它不是一條SELECT語句,而是被該語句檢索出來的結果集。 -- 《SQL必知必會》第二十二章 高級SQL特性; # 約束 -- 主鍵,是一種特殊的約束,定義主鍵的方法可以是在創建表時定義它也可以是更新表操作中用CONSTRAINT語法 -- 外鍵,是表中的一列,其值必須列在另一表的主鍵中。外鍵是保證引用完整性的極其重要部分。 # 定義外鍵的方法 /* CREATE TABLE Orders ( order_num INTEGER NOT NULL PRIMARY KEY, order_date DATETIME NOT NULL, cust_id CHAR(10) NOT NULL REFERENCES Customers(cust_id) );*/ -- 唯一約束,保證一列(或一組列)中的數據是唯一的。 -- 檢查約束用來保證一列(或一組列)中的數據滿足一組指定的條件。 /* CREATE TABLE OrderItems ( order_num INTEGER NOT NULL, order_item INTEGER NOT NULL, prod_id CHAR(10) NOT NULL, quantity INTEGER NOT NULL CHECK (quantity > 0), item_price MONEY NOT NULL );*/ # 索引,用來排序數據以加快搜索和排序操作的速度 # 觸發器,是特殊的存儲過程,它在特定的數據庫活動發生時自動執行。 # (最後吐槽一下微信讀書,我先把附錄看完之後,微信讀書就一直閱讀進度100%,改爲在讀,他過一會還是自動跳轉爲已讀完,感覺是不是可以在每個章節隨機放一個觸發器避免這個問題)
SQL必知必會(第5版) ◆ 1.1 數據庫基礎 >> 主鍵通常定義在表的一列上,但並不是必須這麼做,也可以一起使用多個列作爲主鍵。在使用多列作爲主鍵時,上述條件必須應用到所有列,所有列值的組合必須是唯一的 ◆ 2.4 檢索所有列 >> 但檢索不需要的列通常會降低檢索速度和應用程序的性能。 >> 使用通配符有一個大優點。由於不明確指定列名(因爲星號檢索每一列),所以能檢索出名字未知的列 ◆ 2.5 檢索不同的值 >> 辦法就是使用DISTINCT關鍵字,顧名思義,它指示數據庫只返回不同的值。 >> DISTINCT關鍵字作用於所有的列,不僅僅是跟在其後的那一列。 ◆ 2.6 限制結果 >> 可以用TOP關鍵字來限制最多返回多少行 >> FETCH FIRST 5 ROWS ONLY就會按字面的意思去做的(只取前5行) >> 如果你使用Oracle,需要基於ROWNUM(行計數器)來計算行 >> 如果你使用MySQL、MariaDB、PostgreSQL或者SQLite,需要使用LIMIT子句,像這樣: >> LIMIT 5 OFFSET 5指示MySQL等DBMS返回從第5行起的5行數據。第一個數字是檢索的行數,第二個數字是指從哪兒開始。 >> MySQL、MariaDB和SQLite可以把LIMIT 4 OFFSET 3語句簡化爲LIMIT 3,4。使用這個語法,逗號之前的值對應OFFSET,逗號之後的值對應LIMIT(反着的,要小心)。 >> SQL雖然通常都有相當一致的實現,但你不能想當然地認爲它總是這樣。非常基本的語句往往是相通的,但較複雜的語句就不同了 ◆ 2.7 使用註釋 >> 註釋使用--(兩個連字符)嵌在行內。——之後的文本就是註釋 >> 註釋從/*開始,到*/結束,/*和*/之間的任何內容都是註釋。 ◆ 3.1 排序數據 >> 關係數據庫設計理論認爲,如果不明確規定排序順序,則不應該假定檢索出的數據的順序有任何意義。 >> 在指定一條ORDER BY子句時,應該保證它是SELECT語句中最後一條子句。如果它不是最後的子句,將會出錯。 >> 通常,ORDER BY子句中使用的列將是爲顯示而選擇的列。但是,實際上並不一定要這樣,用非檢索的列排序數據是完全合法的。 ◆ 6.1 LIKE操作符 >> 根據DBMS的不同及其配置,搜索可以是區分大小寫的。如果區分大小寫,則’fish%’與Fish bean bag toy就不匹配。 ◆ 6.2 使用通配符的技巧 >> 通配符搜索一般比前面討論的其他搜索要耗費更長的處理時間 >> 不要過度使用通配符 >> 在確實需要使用通配符時,也儘量不要把它們用在搜索模式的開始處。把通配符置於開始處,搜索起來是最慢的。 >> 仔細注意通配符的位置 ◆ 7.2 拼接字段 >> 將值聯結到一起(將一個值附加到另一個值)構成單個值。 >> 爲正確返回格式化的數據,必須去掉這些空格。這可以使用SQL的RTRIM()函數來完成 ◆ 9.1 聚集函數 >> AVG()只能用值列的平均值,而且列名必須作爲函數參數給出。爲了獲得多個列的平均值,必須使用多個AVG()函數 >> AVG()函數忽略列值爲NULL的行。 >> SUM()函數忽略列值爲NULL的行。 ◆ 9.2 聚集不同值 >> 在使用了DISTINCT後,此例子中的avg_price比較高,因爲有多個物品具有相同的較低價格。排除它們提升了平均價格。 >> 如果指定列名,則DISTINCT只能用於COUNT()。DISTINCT不能用於COUNT(*)。類似地,DISTINCT必須使用列名,不能用於計算或表達式。 ◆ 9.3 組合聚集函數 >> 在指定別名以包含某個聚集函數的結果時,不應該使用表中實際的列名 ◆ 10.2 創建分組 >> GROUP BY子句指示DBMS分組數據,然後對每個組而不是整個結果集進行聚集。 >> GROUP BY子句中列出的每一列都必須是檢索列或有效的表達式(但不能是聚集函數) >> 如果在SELECT中使用表達式,則必須在GROUP BY子句中指定相同的表達式。不能使用別名 >> 除聚集計算語句外,SELECT語句中的每一列都必須在GROUP BY子句中給出 >> GROUP BY子句必須出現在WHERE子句之後,ORDER BY子句之前。 ◆ 10.3 過濾分組 >> 唯一的差別是,WHERE過濾行,而HAVING過濾分組。 >> 學過的這些有關WHERE的所有技術和選項都適用於HAVING。它們的句法是相同的,只是關鍵字有差別。 >> WHERE在數據分組前進行過濾,HAVING在數據分組後進行過濾。這是一個重要的區別,WHERE排除的行不包括在分組中。這可能會改變計算值,從而影響HAVING子句中基於這些值過濾掉的分組。 ◆ 10.4 分組和排序 >> 一般在使用GROUP BY子句時,應該也給出ORDER BY子句。這是保證數據正確排序的唯一方法。千萬不要僅依賴GROUP BY排序數據。 ◆ 11.2 利用子查詢進行過濾 >> 在SELECT語句中,子查詢總是從內向外處理。 ◆ 11.3 作爲計算字段使用子查詢 >> 要對每個顧客執行COUNT(*),應該將它作爲一個子查詢 >> SELECT cust_name, cust_state, (SELECT COUNT(*) FROM Orders WHERE Orders.cust_id = Customers.cust_id) AS orders FROM Customers ORDER BY cust_name; >> 如果在SELECT語句中操作多個表,就應使用完全限定列名來避免歧義。 ◆ 12.1 聯結 這裏其實就是說數據庫要滿足基本的數據範式(一般數據庫的設計滿足第三範式即可) 範式的好處是:使編程相對簡單,數據量更小,更適合放入內存,更新更快,只需更新更少的數據。更少的冗餘數據意味着更少地需要GROUP、DISTINCT之類的操作。不利之處是查詢會變得更加複雜,查詢時需要更多連接(JOIN)操作,一些可以複合索引的列由於範式化的需要被分佈到了不同的表中,導致索引策略不佳。 我們日常輸出的數據呈現清單報表的時候,又需要一定程度地反範式,通過增加冗餘數據或通過分組數據來優化數據庫讀取性能的過程。 >關係表的設計就是要把信息分解成多個表,一類數據一個表。各表通過某些共同的值互相關聯(所以才叫關係數據庫)。 >> 關係表的設計就是要把信息分解成多個表,一類數據一個表。各表通過某些共同的值互相關聯(所以才叫關係數據庫)。 ◆ 12.2 創建聯結 >> 相應的笛卡兒積不是我們想要的。這裏返回的數據用每個供應商匹配了每個產品,包括了供應商不正確的產品(即使供應商根本就沒有產品)。 >> SQL不限制一條SELECT語句中可以聯結的表的數目。創建聯結的基本規則也相同。 >> 不要聯結不必要的表。聯結的表越多,性能下降越厲害。 ◆ 14.2 創建組合查詢 >> UNION指示DBMS執行這兩條SELECT語句,並把輸出組合成一個查詢結果集。 >> UNION中的每個查詢必須包含相同的列、表達式或聚集函數(不過,各個列不需要以相同的次序列出)。 >> 事實上,如果想返回所有的匹配行,可使用UNION ALL而不是UNION。 >> 如果確實需要每個條件的匹配行全部出現(包括重複行),就必須使用UNION ALL,而不是WHERE。 >> SELECT語句的輸出用ORDER BY子句排序。在用UNION組合查詢時,只能使用一條ORDER BY子句,它必須位於最後一條SELECT語句之後。對於結果集,不存在用一種方式排序一部分,而又用另一種方式排序另一部分的情況,因此不允許使用多條ORDER BY子句。 ◆ 14.4 挑戰題 SELECT語句的輸出用ORDER BY子句排序。在用UNION組合查詢時,只能使用一條ORDER BY子句,它必須位於最後一條SELECT語句之後。對於結果集,不存在用一種方式排序一部分,而又用另一種方式排序另一部分的情況,因此不允許使用多條ORDER BY子句。 ◆ 15.1 數據插入 >> 這個例子將一個新顧客插入到Customers表中。存儲到表中每一列的數據在VALUES子句中給出,必須給每一列提供一個值。如果某列沒有值,如上面的cust_contact和cust_email列,則應該使用NULL值(假定表允許對該列指定空值)。各列必須以它們在表定義中出現的次序填充。 >> 表名後的括號裏明確給出了列名。在插入行時,DBMS將用VALUES列表中的相應值填入列表中的對應項。VALUES中的第一個值對應於第一個指定列名,第二個值對應於第二個列名,如此等等。 >> 因爲提供了列名,VALUES必須以其指定的次序匹配指定的列名,不一定按各列出現在表中的實際次序。其優點是,即使表的結構改變,這條INSERT語句仍然能正確工作。 >> 不要使用沒有明確給出列的INSERT語句。給出列能使SQL代碼繼續發揮作用,即使表結構發生了變化。 >> 不管使用哪種INSERT語法,VALUES的數目都必須正確。如果不提供列名,則必須給每個表列提供一個值;如果提供列名,則必須給列出的每個列一個值。否則,就會產生一條錯誤消息,相應的行不能成功插入 >> 如果表的定義允許,則可以在INSERT操作中省略某些列。省略的列必須滿足以下某個條件。 ❑ 該列定義爲允許NULL值(無值或空值)。 ❑ 在表定義中給出默認值。這表示如果不給出值,將使用默認值。 >> INSERT還存在另一種形式,可以利用它將SELECT語句的結果插入表中,這就是所謂的INSERT SELECT ◆ 16.1 更新數據 >> 要刪除某個列的值,可設置它爲NULL ◆ 16.2 刪除數據 >> DELETE刪除整行而不是刪除列。要刪除指定的列,請使用UPDATE語句。 ◆ 16.3 更新和刪除的指導原則 >> 在UPDATE或DELETE語句使用WHERE子句前,應該先用SELECT進行測試,保證它過濾的是正確的記錄,以防編寫的WHERE子句不正確。 ◆ 17.1 創建表 >> 利用CREATE TABLE創建表,必須給出下列信息:❑ 新表的名字,在關鍵字CREATE TABLE之後給出;❑ 表列的名字和定義,用逗號分隔;❑ 有的DBMS還要求指定表的位置。 >> 列名(它在表中必須是唯一的) 爲了防止新表表名已經存在導致的報錯,可以在建表示加上if not exists,寫成: create table 【if not exists】 表名( 字段名 字段類型 【約束】, 字段名 字段類型 【約束】, 。。。 字段名 字段類型 【約束】 ) >在創建新的表時,指定的表名必須不存在,否則會出錯。 >> 在創建新的表時,指定的表名必須不存在,否則會出錯。 >> 主鍵是其值唯一標識表中每一行的列。只有不允許NULL值的列可作爲主鍵,允許NULL值的列不能作爲唯一標識 >> NULL值是沒有值,不是空字符串 >> 空字符串是一個有效的值,它不是無值 ◆ 17.2 更新表 理想情況下,不要在表中包含數據時對其進行更新。應該在表的設計過程中充分考慮未來可能的需求,避免今後對錶的結構做大改動。 1.添加列 alter table 表名 add column 列名 類型 【first|after 字段名】; 2.修改列的類型或約束 alter table 表名 modify column 列名 新類型 【新約束】; 3.修改列名 alter table 表名 change column 舊列名 新列名 類型; 4 .刪除列 alter table 表名 drop column 列名; 5.修改表名 alter table 表名 rename 【to】 新表名; >17.2 更新表 >> 複雜的表結構更改一般需要手動刪除過程,它涉及以下步驟: (1) 用新的列布局創建一個新表; (2) 使用INSERT SELECT語句(關於這條語句的詳細介紹,請參閱第15課)從舊錶複製數據到新表。有必要的話,可以使用轉換函數和計算字段; (3) 檢驗包含所需數據的新表; (4) 重命名舊錶(如果確定,可以刪除它); (5) 用舊錶原來的名字重命名新表; (6) 根據需要,重新創建觸發器、存儲過程、索引和外鍵。 >> 數據庫表的更改不能撤銷,如果增加了不需要的列,也許無法刪除它們。類似地,如果刪除了不應該刪除的列,可能會丟失該列中的所有數據。 ◆ 17.3 刪除表 >> 許多DBMS允許強制實施有關規則,防止刪除與其他表相關聯的表。在實施這些規則時,如果對某個表發佈一條DROP TABLE語句,且該表是某個關係的組成部分,則DBMS將阻止這條語句執行,直到該關係被刪除爲止。如果允許,應該啓用這些選項,它能防止意外刪除有用的表。 ◆ 18.1 視圖 視圖是mysql5.1版本出現的新特性,視圖本身是一個虛擬表,它的數據來自於表,通過執行時動態生成。 好處: 1、簡化sql語句 2、提高了sql的重用性 3、保護基表的數據,提高了安全性 二、創建 create view 視圖名 as 查詢語句; 三、修改 方式一: create or replace view 視圖名 as 查詢語句; 方式二: alter view 視圖名 as 查詢語句 四、刪除 drop view 視圖1,視圖2,...; 五、查看 desc 視圖名; show create view 視圖名; 六、使用 1.插入 insert 2.修改 update 3.刪除 delete 4.查看 select 注意:視圖一般用於查詢的,而不是更新的,所以具備以下特點的視圖都不允許更新 ①包含分組函數、group by、distinct、having、union、 ②join ③常量視圖 ④where後的子查詢用到了from中的表 ⑤用到了不可更新的視圖 >18.1 視圖 >> 視圖的一些常見應用。 ❑ 重用SQL語句。 ❑ 簡化複雜的SQL操作。在編寫查詢後,可以方便地重用它而不必知道其基本查詢細節。 ❑ 使用表的一部分而不是整個表。 ❑ 保護數據。可以授予用戶訪問表的特定部分的權限,而不是整個表的訪問權限。❑ 更改數據格式和表示。視圖可返回與底層表的表示和格式不同的數據。創建視圖之後,可以用與表基本相同的方式使用它們。可以對視圖執行SELECT操作,過濾和排序數據,將視圖聯結到其他視圖或表,甚至添加和更新數據 >> 關於視圖創建和使用的一些最常見的規則和限制。 ❑ 與表一樣,視圖必須唯一命名(不能給視圖取與別的視圖或表相同的名字)。 ❑ 對於可以創建的視圖數目沒有限制。 ❑ 創建視圖,必須具有足夠的訪問權限。這些權限通常由數據庫管理人員授予。 ❑ 視圖可以嵌套,即可以利用從其他視圖中檢索數據的查詢來構造視圖。所允許的嵌套層數在不同的DBMS中有所不同(嵌套視圖可能會嚴重降低查詢的性能,因此在產品環境中使用之前,應該對其進行全面測試)。 ❑ 許多DBMS禁止在視圖查詢中使用ORDER BY子句。 ❑ 有些DBMS要求對返回的所有列進行命名,如果列是計算字段,則需要使用別名(關於列別名的更多信息,請參閱第7課)。 ❑ 視圖不能索引,也不能有關聯的觸發器或默認值。 ❑ 有些DBMS把視圖作爲只讀的查詢,這表示可以從視圖檢索數據,但不能將數據寫回底層表。詳情請參閱具體的DBMS文檔。 ❑ 有些DBMS允許創建這樣的視圖,它不能進行導致行不再屬於視圖的插入或更新。例如有一個視圖,只檢索帶有電子郵件地址的顧客。如果更新某個顧客,刪除他的電子郵件地址,將使該顧客不再屬於視圖。 ◆ 18.2 創建視圖 >> SELECT約束全部適用 >> 用視圖過濾不想要的數據 >> 在簡化計算字段的使用上,視圖也特別有用 >> 視圖非常容易創建,而且很好使用。正確使用,視圖可極大地簡化複雜數據的處理。 ◆ 18.3 小結 >> 視圖爲虛擬的表。它們包含的不是數據而是根據需要檢索數據的查詢。視圖提供了一種封裝SELECT語句的層次,可用來簡化數據處理,重新格式化或保護基礎數據。
閱讀速度5000字/分鐘 1、本書主題:介紹SQL的基本概念和語法 2、速讀建議:業餘人士大致瀏覽即可。 有人會覺得這些內容上網查也能知道, 1、網上信息很雜亂,找到需要的內容費時費力; 2、不要高估自己的定力,可能上網中途就去幹別的了; 3、網上的信息真假難辨; 提供權威書籍系統學習基礎知識,效率比上網搜更高。 確實網上有個別解讀淺顯易懂,也很有趣。 但別揀了芝麻丟了西瓜。 本書含金量高,值得推薦。
本科的時候學過數據庫,這次也是先看了一些視頻課程進行回顧,才又來看書再鞏固一下。內容很基礎,讀起來很快,確實是很適合小白了,有助於提升學習信心。提供的網站上有習題答案,用起來還不錯。不過有挺多重要的內容一筆帶過,比如索引,還有的甚至根本沒提到,比如鎖。
真真的入門級別,已經入門的話,不建議看。 UNION操作符:當你需要從多個表中獲取相似的數據並將其合併爲一個結果集時,UNION 是非常有用的。 事務處理是一種機制,用來管理必須成批執行的SQL操作,保證數據庫不包含不完整的操作結果。 需要在檢索出來的行中前進或後退一行或多行,這就是遊標的用途所在。 觸發器是特殊的存儲過程,它在特定的數據庫活動發生時自動執行。 1確保數據正確。比喻:想象你在填寫一張表格,有人會在你填完後立即檢查你的信息是否正確。如果發現錯誤,他們會告訴你並阻止你提交。 實際應用:當你在某個表中插入或更新數據時,觸發器會自動檢查這些數據是否符合特定的規則。如果不符,它可以阻止這些數據被保存。 2記錄操作日誌。比喻:就像你在銀行存取款時,銀行會自動記錄你的每一筆交易。 實際應用:每當表中的數據發生變化(如插入、更新或刪除),觸發器可以自動把這些變化記錄到另一個表中,以便日後查看和審計。 3自動執行任務。比喻:就像你設定了一條規則,每當你完成一項任務,系統會自動給你發一封獎勵郵件。 實際應用:當某個事件發生時(如訂單狀態變爲“已發貨”),觸發器可以自動執行一些操作,比如發送郵件通知客戶。 4保持數據同步。比喻:就像你在兩個筆記本上做筆記,當你在一個筆記本上寫了一些東西,另一個筆記本會自動同步這些內容。 實際應用:當一個表中的數據發生變化時,觸發器可以自動更新另一個表中的相應數據,確保兩個表的數據保持一致。
書裏面具體知識點,我就不長篇累牘地在這做筆記了,各位自行閱讀即可。重點講吓,個人認爲這本書適合什麼人看,以及能否學會的觀點。先說個人水平,我是個文科生,且零基礎,我通過B站白嫖課自學了sql的萌新,屬於剛新鮮出爐學會sql的萌新。看這本書原因和各位一樣,無非就是sql工具書銷售榜一都是它,以及大佬們都牆裂推薦入行小白必讀,慕名而來讀的。讀完此書後,有幾個看法: 一、這本書對於我這個零基礎剛學會sql的萌新來說,都太過容易了,是真的完全沒難度,知識點比較淺,我看這本書就當作複習和鞏固知識點了。 二、這本書知識雖然淺,但內容很精華又核心,非常適合也非常建議,小白閱讀,就算沒學過sql的人,只要你掌握了高中基本數學的思維,和初中英語詞彙量,都可以讀得懂這本書,完全不用擔心。 三、這本書雖然讀完了,你入門也只是入了一半,因爲學會一門語言最好的方法是實踐,光看是很難把一個知識真的掌握的。建議讀完此書去牛客網把題都刷完。對了,牛客網還有專門的篇章就是這本書的配套課後習題,也建議初學者邊看邊刷題。實踐與理論結合,這個sql的基礎門算是入的了。 沒想到這個幾年前隨手寫的評論,還是挺多網友點讚的。那我補充多第四點哈 四、這本書核心知識基本上具備了,但由於這本書出版時間還是比較久遠的,因此該本唯一缺漏的重點知識是窗口函數。 窗口函數是日常業務的重點知識,學習這本書的網友們,需要自己找這塊知識補全哈。
對我而言,這本書最大的價值不是記住了多少語法,而是兩點認知: 1. SQL 的本質是“提問” 寫 SQL 的過程,其實是在把業務問題翻譯成數據庫能理解的問題。語法只是工具,邏輯思維纔是核心。 2. 剋制與清晰比炫技更重要 能用簡單查詢解決的問題,就不要寫成多層嵌套的“天書 SQL”。可讀性、可維護性,往往比“看起來很厲害”更重要。 《SQL必知必會》是一本“小而美”的 SQL 入門書,它不一定讓你成爲專家,但一定能讓你真正會用 SQL。
微信讀書讀完的第377本書,《SQL必知必會《第5版》》。經典SQL書籍,介紹不同版本軟件,怎樣創立數據庫、表格、插入數據、修改表格、修改數據、查詢數據(select from、where、group by、having、order by、join、union、子查詢、常見函數等)、存儲、索引、觸發器等。本書並沒有涉及到窗口函數。可以在牛客網,實操練習“必知必會”部分。
今天花了一天時間,從頭到尾仔細看了一遍,下午五點鐘看完。本書重點介紹了SELECT語句用法,後面章節的高級用法只是做了概念性的介紹,可以作爲入門級別的學習,提升學習不太適合,像一些高級用法遞歸與開窗函數等都沒有講。
看到十八課。這本書太淺了,只能說是摸着門邊,都不能說是入門。說是淺吧,但好像也不能說是非常系統,像是數據類型這種東西也不放在正文要放在附錄,很多底層的東西都沒搭建起來(也可能是sql本身的特性吧)。像是習慣寫R的,新建一個列用來輔助計算很正常,但是sql儘量避免對數據的直接操作,所以會導致思維習慣上差別有點大,類似這種的點也沒完全點出來。 個人認爲有點其他語言基礎的直接去看cheat sheet可能都好過在這本上費時間…… btw真是越寫題越火大……