SQL 必知必會(huì)
在mac終端操作sqlite:
- cd 數(shù)據(jù)庫(kù)所在的目錄
- sqlite3 數(shù)據(jù)庫(kù)文件名 //帶后綴)(此時(shí)已經(jīng)打開(kāi)數(shù)據(jù)庫(kù))
- .tables //顯示數(shù)據(jù)庫(kù)中所有已經(jīng)創(chuàng)建的表
- .schema //顯示所有表的模式
- .headers on //顯示字段名(查詢時(shí)才會(huì)顯示)
- .mode column/list/line
- 執(zhí)行sql語(yǔ)句必須在末尾加分號(hào)
distinct
SELECT DISTINCT name FROM TB_BOOK_TAG;
關(guān)鍵字distinct,用于去除name列中所有行中重復(fù)元素。
limit
SELECT name FROM TB_BOOK_TAG LIMIT 5;
關(guān)鍵字limit,返回name列指定行數(shù)。
SELECT name FROM TB_BOOK_TAG LIMIT 5 OFFSET 0;
等同于下面寫(xiě)法(shortcut)
SELECT name FROM TB_BOOK_TAG LIMIT 0,5;
limit ... offset ...
關(guān)鍵字LIMIT ... OFFSET ...,limit后跟的數(shù)字指定顯示多少行,offset后跟的數(shù)字表示從什么位置開(kāi)始。(0是第一行)
注釋
--this is a comment
關(guān)鍵--加注釋,單行注釋。
/* comments */
關(guān)鍵/**/,多行注釋。
order by
SELECT * FROM TB_BOOK_TAG ORDER BY name;
關(guān)鍵字:order by + 字段名,按該字段所屬列的首字母進(jìn)行排序。要確保該子句是select語(yǔ)句中最后一條子句,否則會(huì)出現(xiàn)錯(cuò)誤。
SELECT publisher,pubdate FROM TB_BOOK_ENTITY ORDER BY publisher,pubdate;
關(guān)鍵字:order by + 字段名 + 字段名,首先按publisher進(jìn)行排序,然后按照pubdate進(jìn)行排序。對(duì)于第二個(gè)字段的排序,當(dāng)且僅當(dāng)具有多個(gè)相同的publisher時(shí)才會(huì)對(duì)其按照pubdate進(jìn)行排序,如果publisher列中所有值都是唯一的,則不會(huì)按pubdate進(jìn)行排序。
desc
SELECT publisher,pubdate FROM TB_BOOK_ENTITY ORDER BY pubdate DESC;
關(guān)鍵字:desc,order by 默認(rèn)是按升序進(jìn)行排序,當(dāng)在字段名后加desc后,將對(duì)該字段進(jìn)行降序排列。
SELECT pubdate,price FROM TB_BOOK_ENTITY ORDER BY pubdate DESC,price;
pubdate按降序排列,price,仍然按照升序排列(在pubdate相同的行)。所以,如果想在多個(gè)列上進(jìn)行降序,必須對(duì)每一列都指定desc關(guān)鍵字。
where
SELECT * FROM TB_BOOK_TAG WHERE count = 1;
關(guān)鍵字:where,指定搜索條件進(jìn)行過(guò)濾。where子句在表名(from子句)之后給出。在同時(shí)使用where和order by時(shí),應(yīng)該讓order by位于where之后。
| 操作符 | 說(shuō)明 |
|---|---|
| = | 等于 |
| <> | 不等于 |
| != | 不等于 |
| < | 小于 |
| <= | 小于等于 |
| !< | 不小于 |
| > | 大于 |
| >= | 大于等于 |
| !> | 不大于 |
| BETWEEN | 在指定的兩個(gè)值之間 |
| IS NULL | 為NULL值 |
注意:NULL和非匹配
通過(guò)過(guò)濾選擇不包含(如<>)指定值的所有行時(shí),你可能希望返回含NULL值的行,但是這做不到,因?yàn)镹ULL有特殊的含義,數(shù)據(jù)庫(kù)不知道它們是否匹配,所以在進(jìn)行匹配過(guò)濾或非匹配過(guò)濾時(shí),不會(huì)返回這些結(jié)果。
where...and...
select * from contacts where name = "fff" and mobile = "d";
關(guān)鍵字:and,組合where子句。
where...or...
select * from contacts where name = "fff" or mobile = "d";
關(guān)鍵字:or,組合where子句。
注意:在同時(shí)使用and和or時(shí)要注意求值順序,and優(yōu)先級(jí)大于or。因此在任何時(shí)候使用具有and和or操作符的where子句時(shí),都應(yīng)該使用圓括號(hào)明確地分組操作符
where...in...
select * from contacts where mobile in ('12', '444') order by mobile;
關(guān)鍵字:in,用來(lái)指定條件范圍,范圍中的每個(gè)條件都可以進(jìn)行匹配。in操作符一般比一組or操作符執(zhí)行的更快。in最大的優(yōu)點(diǎn)是可以包含其他select語(yǔ)句,能夠更動(dòng)態(tài)的建立where子句。
not
select * from contacts where not mobile = '12';
關(guān)鍵字:not,where子句中用來(lái)否定其后條件的關(guān)鍵字。上面的例子也可以用<>。在簡(jiǎn)單語(yǔ)句中,not沒(méi)有什么優(yōu)勢(shì),但是,在更復(fù)雜的子句中,not非常有用。例如,在與in操作符聯(lián)合使用時(shí),not可以非常簡(jiǎn)單的找出與條件列表不匹配的行。如下例子:
SELECT * FROM CONTACTS WHERE NOT mobile IN ('111111', '3333');
like
通配符(wildcard)用來(lái)匹配值的一部分的特殊字符。
搜索模式(search pattern)由字面值,通配符或兩者組合構(gòu)成的搜索條件。
通配符搜索只能用于文本字段(字符串),非文本數(shù)據(jù)類型字段不能使用通配符搜索
%通配符
在搜索字符串中,%表示任何字符出現(xiàn)任意次數(shù)
select * from tb_book_tag where name like '計(jì)算機(jī)%';
注意字符串后面所跟的空格:
許多DBMS會(huì)用空格來(lái)填補(bǔ)字段內(nèi)容。例如,如果某列有50個(gè)字符,而存儲(chǔ)文本為Fish bean bag toy(17個(gè)字符),則為填滿該列會(huì)在文本末尾追加33個(gè)空格。如果此時(shí)用‘F%y’來(lái)檢索,便檢索不到上述字符串。簡(jiǎn)單解決辦法是‘F%y%’。更好的解決辦法是用函數(shù)去掉空格。
'%' 不會(huì)匹配為NULL的行
下劃線_通配符
用途和%一樣,但它只匹配單個(gè)字符,而不是多個(gè)。
select * from tb_book_tag where name like '計(jì)算機(jī)__';
使用通配符的技巧
SQL通配符搜索比其他搜索更耗時(shí)。
1. 不要過(guò)度使用通配符,如果其他操作能達(dá)到目的,使用其他操作。
2. 在確實(shí)需要使用的時(shí)候,也盡量不要把它用在搜索模式的開(kāi)始處。把通配符置于開(kāi)始處,搜索起來(lái)是最慢的。
3. 特別要注意通配符的位置不要放錯(cuò)。
創(chuàng)建計(jì)算字段
計(jì)算字段并不實(shí)際存在于數(shù)據(jù)庫(kù)表中,計(jì)算字段是運(yùn)行時(shí)在SELECT語(yǔ)句內(nèi)創(chuàng)建的。
select rtrim('~ ') || name from tb_book_tag;
關(guān)鍵字:||和rtrim()。 ||拼接操作符。rtrim()去除文本右邊的空格。trim()去除兩邊的空格。
as
select name || 'is foolish' as title from contacts;
關(guān)鍵字:as,全稱alias。它指示SQL創(chuàng)建一個(gè)包含指定計(jì)算結(jié)果的名為title的計(jì)算字段,任何客戶端應(yīng)用可以按名稱引用這個(gè)列,就像一個(gè)實(shí)際表列一樣。
執(zhí)行算術(shù)計(jì)算
+ - * /
select mobile, (mobile + 1)*2 as count_mobile from contacts;
關(guān)鍵字:+或-或*或/;
函數(shù)
一下所用到的是適用于sqlite的函數(shù),不一定適用于其他DBMS。
upper()
select name ,upper(name) as name_upper from contacts;
關(guān)鍵字:upper()轉(zhuǎn)大寫(xiě)
sqlite中常用于文本處理函數(shù):
| 函數(shù) | 說(shuō)明 |
|---|---|
| length() | 返回字符串的長(zhǎng)度 |
| lower() | 將字符串轉(zhuǎn)小寫(xiě) |
| ltrim() | 去掉字符串左邊的空格 |
| rtrim() | 去掉字符串右邊的空格 |
| upper() | 將字符串轉(zhuǎn)大寫(xiě) |
avg()
select avg(mobile) as avg_id from contacts;
關(guān)鍵字:avg(),對(duì)表中某列所有行或特定行中的數(shù)據(jù)求平均值。該函數(shù)會(huì)忽略值為NULL的行。
count()
select count(*) as num_cust from contacts;
select count(name) as num_name from contacts;
關(guān)鍵字:count(),使用count(*),對(duì)表中行的數(shù)目進(jìn)行計(jì)數(shù),不管表列中是否包含NULL值。使用count(column_name),對(duì)特定列中具有值的行進(jìn)行計(jì)數(shù),忽略NULL值。
sum()
select sum(mobile) as sum_mobile from contacts;
關(guān)鍵字:sum(), 忽略NULL值
聚集不同值
count(distinct name)
select count(distinct name) from tb_book_tag;
組合聚集函數(shù)
select count(*) as num_items, min(count) as count_min, max(count) as count_max, avg(count) as count_avg from tb_book_tag;
分組數(shù)據(jù)
group by
select name, count(*) as num_names from tb_book_tag group by name order by name;
關(guān)鍵字:group by,group by子句必須出現(xiàn)在where子句之后,order by子句之前。
group by...having...
select name , count(*) as amounts from tb_book_tag group by name having amounts >= 10;
關(guān)鍵字:having。對(duì)分組進(jìn)行過(guò)濾。而where對(duì)分組不起作用,它是針對(duì)表中每一行來(lái)過(guò)濾。
使用子查詢
select cust_id
from orders
where order_num in (select order_num
from orderitems
where prod_id = 'RGAN01');
注意:
作為子查詢的select語(yǔ)句只能查詢單個(gè)列。企圖檢索多個(gè)列將返回錯(cuò)誤。
同時(shí)要注意性能問(wèn)題。
使用子查詢作為計(jì)算字段
select cust_name,
cust_state,
(select count(*)
from orders
where orders.cust_id = customers.cust_id) as orders from customers
order by cust_name;
聯(lián)結(jié)表
關(guān)系表
為理解關(guān)系表,來(lái)看一個(gè)例子:
有一個(gè)包含產(chǎn)品目錄的數(shù)據(jù)庫(kù)表,其中每類物品占一行,對(duì)于每種物品,要存儲(chǔ)的信息包括產(chǎn)品描述,價(jià)格以及生產(chǎn)該產(chǎn)品的供應(yīng)商。
現(xiàn)有同一供應(yīng)商生產(chǎn)的多種物品,那么在何處存儲(chǔ)供應(yīng)商名聯(lián)系方法等信息?將這些數(shù)據(jù)與產(chǎn)品信息分開(kāi)存儲(chǔ)的理由是:
- 同一供應(yīng)商的每個(gè)產(chǎn)品,其供應(yīng)商的信息是相同的,對(duì)每個(gè)產(chǎn)品重復(fù)此信息既浪費(fèi)時(shí)間又浪費(fèi)空間;
- 如果供應(yīng)商信息發(fā)生變化,只需修改一次即可;
- 如果有重復(fù)數(shù)九,則很難保證每次輸入該數(shù)據(jù)的方式都相同,
相同的數(shù)據(jù)出現(xiàn)多次決不是一件好事,這是關(guān)系數(shù)據(jù)庫(kù)設(shè)計(jì)的基礎(chǔ)。關(guān)系表的設(shè)計(jì)就是要把信息分解成多個(gè)表,一類數(shù)據(jù)一個(gè)表。各表通過(guò)某些共同的值相互關(guān)聯(lián)(所以才叫關(guān)系數(shù)據(jù)庫(kù))。
如果數(shù)據(jù)存儲(chǔ)在多個(gè)表中,怎樣用一條select語(yǔ)句就檢索出數(shù)據(jù)?
答案是使用聯(lián)結(jié),聯(lián)結(jié)是一種機(jī)制,用來(lái)在一條select語(yǔ)句中關(guān)聯(lián)表
select vend_name, prod_name, prod_price
from products, vendors
where vendors.vend_id = products.vend_id;
等同于下面的寫(xiě)法:
select vend_name, prod_name, prod_price
from vendors inner join products
on vendors.vend_id = products.vend_id;
在聯(lián)結(jié)兩個(gè)表時(shí),實(shí)際要做的是將第一個(gè)表中的每一行與第二個(gè)表中的每一行配對(duì)。where子句作為過(guò)濾條件,只包含那些匹配給定條件的行。沒(méi)有where子句,第一個(gè)表中的每一行將與第二個(gè)表中的每一行配對(duì),而不管他們邏輯上是否能匹配在一起。這種聯(lián)結(jié)稱為等值聯(lián)結(jié)(equijoin),也稱為內(nèi)聯(lián)結(jié)(inner join)。
笛卡爾積(cartesian product):
由于沒(méi)有聯(lián)結(jié)條件的表關(guān)系返回的結(jié)果為笛卡爾積。檢索出的行的數(shù)目將是第一個(gè)表中的行數(shù)乘以第二個(gè)表中的行數(shù)。
返回笛卡爾積的聯(lián)結(jié)也叫叉聯(lián)結(jié)(cross join)。
SQL不限制一條select語(yǔ)句可以聯(lián)結(jié)的表的數(shù)目。如下:
select prod_name, vend_name, prod_price, quantity
from orderitems, products, vendors
where products.vend_id = vendors.vend_id
and orderitems.prod_id = products.prod_id
and order_num = 20007;
注意:性能考慮
DBMS在運(yùn)行時(shí)關(guān)聯(lián)指定的每個(gè)表,以處理聯(lián)結(jié)。這種處理可能非常耗資源,因此應(yīng)該注意不要聯(lián)結(jié)不必要的表。
創(chuàng)建高級(jí)聯(lián)結(jié)
使用表別名
select cust_name, cust_contact
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';
使用表別名的兩個(gè)主要理由:
- 縮短SQL語(yǔ)句
- 允許在一條select語(yǔ)句中多次使用相同的表
自聯(lián)結(jié)
select cust_id, cust_name, cust_contact
from customers
where cust_name = (select cust_name
from customers
where cust_contact = 'Jim Jones');
以上子查詢效果等同于自聯(lián)結(jié):
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';
通常情況下,許多DBMS處理聯(lián)結(jié)遠(yuǎn)比處理子查詢快得多
外聯(lián)結(jié)
select customers.cust_id, orders.order_num
from customers
left outer join orders
on customers.cust_id = orders.cust_id;
檢索包括沒(méi)有訂單顧客在內(nèi)的所有顧客。
SQLite支持left outer join,但不支持right outer join.
組合查詢
主要有兩種情況需要使用組合查詢:
- 在一個(gè)查詢中從不同的表返回結(jié)構(gòu)數(shù)據(jù)
- 對(duì)一個(gè)表執(zhí)行多個(gè)查詢,按一個(gè)查詢返回?cái)?shù)據(jù)
union
select cust_name, cust_contact, cust_email
from customers
where cust_state in ('IL', 'IN', 'MI')
union
select cust_name, cust_contact, cust_email
from customers
where cust_name = 'Fun4All';
union規(guī)則
- union必須由兩條或兩條以上的select語(yǔ)句組成,語(yǔ)句之間用關(guān)鍵字union分隔。
- union中的每個(gè)查詢必須包含相同的列,表達(dá)式或聚集函數(shù)(不過(guò),各個(gè)列不需要以相同的次序列出)。
- 列數(shù)據(jù)類型必須兼容:類型不必完全相同,但必須是DBMS可以隱含轉(zhuǎn)換的類型。
union all
DBMS不取消重復(fù)行。
對(duì)組合查詢結(jié)果排序
select cust_name, cust_contact, cust_email
from customers
where cust_state in ('IL', 'IN', 'MI')
union
select cust_name, cust_contact, cust_email
from customers
where cust_name = 'Fun4All'
order by cust_name, cust_contact;
在用union組合查詢時(shí),只能使用一條order by子句,它必須位于最后一條select語(yǔ)句之后,DBMS用它來(lái)排序所有的select語(yǔ)句返回的所有結(jié)果。
插入數(shù)據(jù)
插入完整的行
insert into... values
insert into customers
values ('1000000006', 'Chenzhen', 'Hennansheng', 'henan', 'China', '476300', 'China', 'John jdge', 'chen@gaiml.com');
這種寫(xiě)法簡(jiǎn)單,但不安全,高度依賴表中列定義的次序,還依賴于其容易獲得的次序信息。編寫(xiě)依賴列次序的SQL語(yǔ)句是很不安全的,這樣做遲早會(huì)出問(wèn)題。
更安全的方法:
insert into customers(cust_id,
cust_name,
cust_address,
cust_city,
cust_state,
cust_zip,
cust_country,
cust_contact,
cust_email)
values('1000000007',
'Chenzhen',
'Hennansheng',
'henan',
'shangqiu',
'476300',
'China',
'John jdge',
'chen@gaiml.com');
插入行時(shí),DBMS將用values列表中的相應(yīng)值填入列表中的對(duì)應(yīng)項(xiàng)。其優(yōu)點(diǎn)是,即使表的結(jié)構(gòu)改變,這條insert語(yǔ)句仍然可以正常工作。
insert into... select...from...
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;
select語(yǔ)句從CustNew檢索出要插入的值,而不是列出他們。DBMS不關(guān)心select返回的列名,它使用的是列的位置,因此select的第一列(不管列名如何)將用來(lái)填充表列中指定的第一列,如此等等。
insert select 語(yǔ)句可以包含where子句。
從一個(gè)表復(fù)制到另一個(gè)表
create table custcopy as select * from customers;
要想只復(fù)制部分列,可以明確給出列名。
更新和刪除數(shù)據(jù)
update...set... where...
update customers
set cust_email = 'chenzhen@gmainl.com'
where cust_id = '1000000008';
更新多個(gè)列時(shí),只需使用一條set命令:
update customers
set cust_email = 'lala@qq.com',
cust_contact = 'sam'
where cust_id = '1000000008';
沒(méi)有where子句,DBMS將會(huì)更新表中所有行。
delete
delete不需要列名或通配符,因?yàn)樗鼊h除的是整行而不是刪除列,要?jiǎng)h除指定列,使用update
delete from custcopy
where cust_id = '1000000008';
如果省略where子句,它將刪除表中的每個(gè)顧客。如果想從表中刪除所有行,不要使用delete,可使用truncate table語(yǔ)句,它的速度更快,因?yàn)椴挥涗洈?shù)據(jù)的變動(dòng)。
創(chuàng)建和操縱表
create
create table Super
(
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, default 10.2
prod_desc varchar(1000) null
);
not null,可以阻止插入沒(méi)有值的列。默認(rèn)是null。
SQLite獲得系統(tǒng)時(shí)間的函數(shù)date('now')
更新表
alert table
使用alert table更改表的結(jié)構(gòu),必須給出下面的信息:
- 在
alter table之后給出要更改的表名。 - 列出要做出哪些更改。
alter table Vendors
add vend_phone char(20);
SQLite對(duì)使用alter table執(zhí)行的操作有所限制。最重要的一個(gè)限制是,它不支持使用alter table定義主鍵和外鍵。
使用alter table要極為小心,應(yīng)該在進(jìn)行改動(dòng)錢(qián)做完整的備份(表結(jié)構(gòu)和數(shù)據(jù)的備份)。數(shù)據(jù)庫(kù)表的更改不能撤銷,如果增加了不需要的列,也許無(wú)法刪除他們。
刪除表 drop table
drop table Super;
使用視圖
視圖是虛擬的表。與包含數(shù)據(jù)的表不一樣,視圖只包含使用時(shí)動(dòng)態(tài)檢索數(shù)據(jù)的查詢。
視圖(View)只不過(guò)是通過(guò)相關(guān)的名稱存儲(chǔ)在數(shù)據(jù)庫(kù)中的一個(gè) SQLite 語(yǔ)句。視圖(View)實(shí)際上是一個(gè)以預(yù)定義的 SQLite 查詢形式存在的表的組合。
SQLite僅支持只讀視圖,所以視圖可以創(chuàng)建,可以讀,但其內(nèi)容不能更改。
刪除視圖 drop view
drop view customeremaillist;
創(chuàng)建視圖create view
create view ProductCustomers as
select cust_name, cust_contact, prod_id
from Customers, Orders, OrderItems
where Customers.cust_id = Orders.cust_id
and OrderItems.order_num = Orders.order_num;
where子句與where子句
從視圖檢索數(shù)據(jù)時(shí)如果使用了一條where子句,則兩組子句(一組子在視圖中,另一組,另一組是傳遞給視圖的)將自動(dòng)組合。
視圖為虛擬的表。它們包含的不是數(shù)據(jù),而是根據(jù)需要檢索數(shù)據(jù)的查詢。視圖提供了一種封裝select語(yǔ)句的層次,可用來(lái)簡(jiǎn)化數(shù)據(jù)處理,重新格式化或保護(hù)基礎(chǔ)數(shù)據(jù)。
管理事務(wù)處理
使用事務(wù)處理(transaction processing),通過(guò)確保成批的SQL操作要么完全執(zhí)行,要么完全不執(zhí)行,來(lái)維護(hù)數(shù)據(jù)庫(kù)的完整性。
關(guān)于事務(wù)處理的一些術(shù)語(yǔ):
- 事務(wù)(transaction)指一組SQL語(yǔ)句;
- 回退(rollback)指撤銷指定SQL語(yǔ)句的過(guò)程;
- 提交(commit)指將未存儲(chǔ)的SQL語(yǔ)句結(jié)果寫(xiě)入數(shù)據(jù)庫(kù)表;
- 保留點(diǎn)(savepoint)指事務(wù)處理中設(shè)置的臨時(shí)占位符,可以對(duì)它發(fā)布回退(與回退整個(gè)事務(wù)處理不同)。
可以回退哪些語(yǔ)句:
insert,update,delete
管理事務(wù)的關(guān)鍵在于將SQL語(yǔ)句分解為邏輯塊,并明確規(guī)定數(shù)據(jù)何時(shí)應(yīng)該回退,何時(shí)不應(yīng)該回退。
begin;
delete from orders where order_num = 20009;
delete from orderitems where order_num = 20009;
commit;
高級(jí)SQL特性
約束,索引,觸發(fā)器。
約束(constraint)
主鍵
create table Orders
(
order_num integer not null primary key,
cust_id char(10) not null references Customers(cust_id)
);
表中任意列只要滿足以下條件,都可以用于主鍵。
- 任意兩行主鍵值都不相同。
- 每行都具有一個(gè)主鍵值(既列中不允許NULL)。
- 包含主鍵的列從不修改或更新。
- 主鍵值不能重用。
外鍵
外鍵是表中的一列,其值必須列在另一表的主鍵中。
外鍵有助防止意外刪除。
在定義外鍵后,DBMS不允許刪除在另一個(gè)表中具有關(guān)聯(lián)行的行。例如不能刪除關(guān)聯(lián)訂單的顧客,刪除改顧客的唯一方法是首先刪除相關(guān)的訂單。
唯一約束 unique
唯一約束用來(lái)保證一列中的數(shù)據(jù)是唯一的。與主鍵的區(qū)別如下:
- 表可包含多個(gè)唯一約束,但每個(gè)表只允許一個(gè)主鍵。
- 唯一約束列可包含NULL值。
- 唯一約束列可修改或更新。
- 唯一約束列的值可重復(fù)使用。
- 與主鍵不一樣,唯一約束不能用來(lái)定義外鍵。
檢查約束 check
create table OrderItems
(
...
quantity integer not null check (quantity > 0),
...
)
索引 create index
索引用來(lái)排序數(shù)據(jù)以加快搜索和排序操作的速度。想象一本書(shū)后的索引。
在開(kāi)始創(chuàng)建索引前,應(yīng)該記住以下內(nèi)容:
- 索引改善檢索操作的性能,但降低了數(shù)據(jù)插入,修改,和刪除的性能。在執(zhí)行這些操作時(shí),DBMS必須動(dòng)態(tài)的更新索引。
- 索引數(shù)據(jù)可能要占用大量的存儲(chǔ)空間。
- 并非所有數(shù)據(jù)都適合做索引。
- 索引用于數(shù)據(jù)過(guò)濾和數(shù)據(jù)排序。
- 可以在索引中定義多個(gè)列(例如,州加上城市)。這樣的索引僅在以州加城市的順序排序時(shí)有用。如果想按城市排序,則這種索引沒(méi)有用處。
CREATE INDEX index_name
ON table_name (column_name);
刪除索引 drop index
DROP INDEX index_name;
觸發(fā)器 Trigger
觸發(fā)器是特殊的存儲(chǔ)過(guò)程,它在特定的數(shù)據(jù)庫(kù)活動(dòng)發(fā)生時(shí)自動(dòng)執(zhí)行。
CREATE TRIGGER trigger_name [BEFORE|AFTER] event_name
ON table_name
BEGIN
-- Trigger logic goes here....
END;
示例:
CREATE TRIGGER audit_log AFTER INSERT
ON COMPANY
BEGIN
INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, datetime('now'));
END;
列出觸發(fā)器
SELECT name FROM sqlite_master
WHERE type = 'trigger';