數(shù)據(jù)庫基礎(chǔ)
數(shù)據(jù)庫≠數(shù)據(jù)庫軟件
確切的說,數(shù)據(jù)庫軟件應(yīng)稱為數(shù)據(jù)庫管理系統(tǒng)(DBMS),數(shù)據(jù)庫是通過DBMS創(chuàng)建和操作的容器
數(shù)據(jù)庫相當于文件柜(容器),表相當于文件
同一個數(shù)據(jù)庫不能存在相同的表名煮仇,不同的數(shù)據(jù)庫可以存在相同的表名
主鍵應(yīng)滿足的條件:
- 唯一性
- 非空性(NOT NULL)
- 主鍵列中的值不允許修改或更新
- 主鍵值不能重用(某行從表中刪除,其主鍵不能賦給新行)
注:可以一起使用多個列作為主鍵谎仲,所有列值的組合必須是唯一的浙垫,但其中單個列的值可以不唯一
檢索數(shù)據(jù)
SQL語句一般返回原始的、無格式的數(shù)據(jù),不同的DBMS和客戶端顯示數(shù)據(jù)的方式略有不同夹姥,數(shù)據(jù)的格式化是表示問題杉武,而不是檢索問題
select * from products;
一般而言,除非確實需要表中的每一列辙售,否則最好別使用*
通配符轻抱,檢索不需要的列通常會降低檢索速度和應(yīng)用程序的性能;當然旦部,通配符也有一個大優(yōu)點:可以檢索出名字未知的列
select distinct vend_id, prod_price from products;
使用distinct檢索不同的列值祈搜,注意distinct關(guān)鍵字作用于其后所有的列,不僅僅是跟在其后的一列士八,即取多個列組合起來的不同結(jié)果
當需要返回一定數(shù)量的行時容燕,各種數(shù)據(jù)庫的實現(xiàn)并不相同:
- SQL Server:
select top 5 prod_name from products;
- DB2:
select prod_name from products fetch first 5 rows only;
- Oracle:
select prod_name from products where rownum <=5;
- MySQL、SQLite等:
select prod_name from products limit 5;
當需要從指定位置開始檢索一定數(shù)量的行數(shù)時婚度,limit和offset組合使用
select prod_name from products limit 4 offset 3;
從第4行開始缰趋,檢索4行數(shù)據(jù)(起始行為第0行);MySQL陕见、MariaDB秘血、SQLite中可以把limit 4 offset 3
簡化為limit 3,4
,注意 ,
之前的值對應(yīng)offset评甜,,
之后的值對應(yīng)limit(反過來了)
使用注釋
- 行內(nèi)注釋
--文本
灰粮,可以嵌在行內(nèi),--之后的文本就是注釋
#文本
忍坷,在一行的開始處使用#粘舟,這一整行都將作為注釋
select prod_name from products; --這是一條注釋
#這是一條注釋
select prod_name from products;
- 多行注釋
/*文本*/
,從/*
到*/
之間的所有內(nèi)容都是注釋
/*select prod_name ,
vend_id
from products; */
select prod_name from products;
排序檢索
SQL語句由子句構(gòu)成佩研,有些子句是必需的柑肴,有些則是可選的。一個子句通常由一個關(guān)鍵字加上所提供的數(shù)據(jù)組成旬薯。例如select語句的from子句晰骑。
order by 子句:取一個或多個列的名字,據(jù)此對輸出進行排序绊序。
注意:在指定一條 order by 子句時硕舆,應(yīng)該保證它是select語句中最后一條子句。如果它不是最后的子句骤公,將會出錯抚官。
按列位置(相對位置)排序:
除了能用列名指出排序順序外,order by 還支持按相對位置進行排序阶捆。
select prod_id, prod_price, prod_name
from Products
order by 2, 3;
order by 2 表示按select清單中的第二個列prod_price進行排序凌节;order by 2, 3 表示先按prod_price钦听,再按prod_name進行排序。
這一技術(shù)的主要好處在于不用重新輸入列名倍奢;缺點是可能造成錯用列名彪见、對select清單進行更改時容易錯誤地對數(shù)據(jù)進行排序、如果進行排序的列不在select清單中娱挨,顯然不能使用這項技術(shù)余指。
如果有必要,可以混合使用實際列名和相對列位置
指定排序方向
數(shù)據(jù)排序默認是升序排序(從A到Z)跷坝,當然酵镜,也可以使用DESC關(guān)鍵字在order by 子句中進行降序排序
select prod_id, prod_price, prod_name
from Products
order by prod_price DESC, prod_name;
DESC關(guān)鍵字只應(yīng)用到直接位于其前面的列名,因此柴钻,上面的語句prod_price列以降序排序淮韭,而prod_name列(在每個價格內(nèi))仍然以默認升序排序
注意:如果想在多個列上進行降序排列,必須對每一列指定DESC關(guān)鍵字
過濾數(shù)據(jù)
SQL過濾與應(yīng)用過濾
SQL過濾之后贴届,數(shù)據(jù)也可以在應(yīng)用層過濾靠粪,但是通常這種做法及其不妥。優(yōu)化數(shù)據(jù)庫后可以更快速有效地對數(shù)據(jù)進行過濾毫蚓。而讓客戶端應(yīng)用(或開發(fā)語言)處理數(shù)據(jù)庫的工作將會極大地影響應(yīng)用的性能占键,并且使所創(chuàng)建的應(yīng)用完全不具備可伸縮性。此外元潘,如果在客戶端過濾數(shù)據(jù)畔乙,服務(wù)器不得不通過網(wǎng)絡(luò)發(fā)送多余的數(shù)據(jù),這將導致網(wǎng)絡(luò)帶寬的浪費翩概。
使用between關(guān)鍵字時牲距,必須指定兩個值--所需范圍的低端值和高端值,這兩個值必須用and關(guān)鍵字分隔钥庇。between匹配范圍中的所有的值牍鞠,包括指定的開始值和結(jié)束值,即左閉右閉[ ]區(qū)間评姨。
確定值是否為NULL难述,不能簡單地檢查是否等于NULL,select語句有一個特殊的where子句参咙,可用來檢查具有NULL值的列龄广,這個where子句就是 IS NULL 子句
select cust_name
from Customers
where cust_email IS NULL;
NULL和非匹配
通過過濾選擇不包含指定值的所有列時硫眯,我們可能希望返回包含NULL值的行蕴侧,但是這做不到,因為NULL比較特殊两入,所以在進行匹配過濾或非匹配過濾時净宵,不會返回這些結(jié)果。
高級數(shù)據(jù)過濾
在where子句中使用圓括號
任何時候使用具有AND和OR操作符的where子句,都應(yīng)該使用圓括號明確地分組操作符择葡。不要過分依賴默認求值順序紧武,即使它確實如你希望的那樣。使用圓括號沒有什么壞處敏储,它能消除歧義阻星。
IN操作符
where子句中用來指定要匹配的清單的關(guān)鍵字,功能與OR相當
其優(yōu)點如下:
- 在有很多合法選項時已添,IN操作符的語法更清楚妥箕、更直觀
- 在與其他AND和OR操作符組合使用IN時,求值順序更容易管理
- IN操作符一般比一組OR操作符執(zhí)行得更快
- IN操作符的最大優(yōu)點是可以包含其他select語句更舞,能夠動態(tài)地建立where子句
NOT操作符
where子句中用來否定其后條件的關(guān)鍵字
select prod_name
from Products
where NOT vend_id = 'DLL01'
order by prod_name;
上面的例子也可以使用 <> 操作符來完成
select prod_name
from Products
where vend_id <> 'DLL01'
order by prod_name;
為什么使用NOT畦幢?
對于簡單的where子句,使用NOT確實沒有什么優(yōu)勢缆蝉,但在更復(fù)雜的子句中宇葱,NOT是非常有用的。例如刊头,在與IN操作符聯(lián)合使用時黍瞧,NOT可以非常簡單地找出與條件列表不匹配的行
用通配符進行過濾
通配符本身實際上是SQL的where子句中有特殊含義的字符,SQL支持幾種通配符原杂。為在搜索子句中使用通配符雷逆,必須使用LIKE操作符。LIKE指示DBMS污尉,后跟的搜索模式利用通配符匹配而不是簡單的相等匹配進行比較膀哲。
最常使用的通配符是百分號(%),表示任何字符出現(xiàn)任意次數(shù)(0次被碗、1次或多次)某宪。
select prod_id, prod_name
from Products
where prod_name like 'Fish%';
此例子使用了搜索模式 'Fish%' ,將檢索任意以Fish起頭的詞锐朴,%告訴DBMS接受Fish之后的任意字符兴喂,不管它有多少字符
MySQL等DBMS默認搜索是不區(qū)分大小寫的,根據(jù)DBMS的不同及其配置焚志,搜索是可以區(qū)分大小寫的衣迷。如果區(qū)分大小寫,則 'fish%' 與 Fish bean bag toy就不匹配
注意NULL:通配符%看起來像是可以匹配任何東西酱酬,但有個例外壶谒,這就是NULL。子句 where prod_name like '%'
不會匹配產(chǎn)品名稱為NULL的行
另一個有用的通配符是下劃線(_)膳沽,它只匹配單個字符汗菜,而不是多個字符让禀。
select prod_id, prod_name
from Products
where prod_name like '__ inch teddy bear';
注意這個where子句中的搜索模式給出了后面跟有文本的兩個通配符,結(jié)果如下:8 inch teddy bear 產(chǎn)品沒有匹配陨界,因為搜索模式要求匹配兩個通配符而不是一個巡揍,%通配符則可以有任意多個。
與 % 能匹配任意個數(shù)的字符不同菌瘪,_ 總是剛好匹配一個字符腮敌,不能多也不能少。
使用通配符的技巧:
正如所見俏扩,SQL的通配符很有用缀皱,但這種功能是有代價的,即通配符搜索一般比前面討論的其他搜索要耗費更長的處理時間动猬,這里給出一些使用通配符時要記住的技巧:
- 不要過度使用通配符啤斗。如果其他操作符能達到相同的目的,應(yīng)該使用其他操作符
- 在確實需要使用通配符時赁咙,也盡量不要把它們用在搜索模式的開始處钮莲。把通配符置于開始處,搜索起來是最慢的
- 仔細注意通配符的位置彼水。如果放錯地方崔拥,可能不會返回想要的數(shù)據(jù)