SQL 必知必會(huì)

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í)使用whereorder 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ǔ)的理由是:

  1. 同一供應(yīng)商的每個(gè)產(chǎn)品,其供應(yīng)商的信息是相同的,對(duì)每個(gè)產(chǎn)品重復(fù)此信息既浪費(fèi)時(shí)間又浪費(fèi)空間;
  2. 如果供應(yīng)商信息發(fā)生變化,只需修改一次即可;
  3. 如果有重復(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';
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容