MySql文法大全
一、SQL速成
結構查詢語言(SQL)是用于查詢關系資料庫的标準語言,它包括若幹關鍵字和一緻的文法,便于資料庫元件(如表、索引、字段等)的建立和操縱。
以下是一些重要的SQL快速參考,有關SQL的文法和在标準SQL上增加的特性,請查詢MySQL手冊。
1.建立表
表是資料庫的最基本元素之一,表與表之間可以互相獨立,也可以互相關聯。建立表的基本文法如下:
create tabletable_name
(column_namedata無效{identity |null|notnull}, …)
其中參數table_name和column_name必須滿足使用者資料庫中的識别器(identifier)的要求,參數data無效是一個标準的SQL類型或由使用者資料庫提供的類型。使用者要使用non-null從句為各字段輸入資料。
createtable還有一些其他選項,如建立臨時表和使用select子句從其他的表中讀取某些字段組成新表等。還有,在建立表是可用PRIMARY KEY、KEY、INDEX等辨別符設定某些字段為主鍵或索引等。
書寫上要注意:
在一對圓括号裡的列出完整的字段清單。
字段名間用逗号隔開。
字段名間的逗号後要加一個空格。
最後一個字段名後不用逗号。
所有的SQL陳述都以分号";"結束。
例:
mysql>CREATE TABLE test (blob_col BLOB,index(blob_col(10)));
2.建立索引
索引用于對資料庫的查詢。一般資料庫建有多種索引方案,每種方案都精于某一特定的查詢類。索引可以加速對資料庫的查詢過程。建立索引的基本文法如下:
create indexindex_name
on table_name(col_name[(length)],... )
mysql>CREATE INDEX part_of_name ON customer (name(10));
3.改變表結構
在資料庫的使用過程中,有時需要改變它的表結構,包括改變字段名,甚至改變不同資料庫字段間的關系。可以實作上述改變的指令是alter,其基本文法如下:
alter table table_namealter_spec [,alter_spec ...]
mysql>ALTER TABLE t1 CHANGE a b INTEGER;
4.删除資料對象
很多資料庫是動态使用的,有時可能需要删除某個表或索引。大多數資料庫對象可以下面的指令删除:
dropobject_name
mysql>DROP TABLE tb1;
5.執行查詢
查詢是使用最多的SQL指令。查詢資料庫需要憑借結構、索引和字段類型等因素。大多數資料庫含有一個優化器(optimizer),把使用者的查詢語句轉換成可選的形式,以提高查詢效率。
值得注意的是MySQL不支援SQL92标準的嵌套的where子句,即它隻支援一個where子句。其基本文法如下:
SELECT [STRAIGHT_JOIN][SQL_SMALL_RESULT] [SQL_BIG_RESULT] [HIGH_PRIORITY]
[DISTINCT |DISTINCTROW | ALL]
select_expression,...
[INTO {OUTFILE |DUMPFILE}’file_name’export_options]
[FROMtable_references
][WHEREwhere_definition]
[GROUP BYcol_name,...]
[HAVINGwhere_definition]
[ORDER BY{unsigned_integer | col_name | formula} ][ASC | DESC],...]
[LIMIT][offset,] rows]
[PROCEDUREprocedure_name] ]
其中where從句是定義選擇标準的地方,where_definition可以有不同的格式,但都遵循下面的形式:
字段名操作表達式
字段名操作字段名
在第一種形式下,标準把字段的值與表達式進行比較;在第二種形式下,把兩個字段的值進行比較。根據所比較的資料類型,search_condition中的操作可能選以下幾種:
=檢查是否相等
!=檢查是否不等
>(或>=)檢查左邊值是否大于(或大于等于)右邊值
<(或<=)檢查左邊值是否小于(或小于等于)右邊值
[not] between檢查左邊值是否在某個範圍内
[not] in檢查左邊是否某個特定集的成員
[not] like檢查左邊是否為右邊的子串
is [not] null檢查左邊是否為空值
在這裡,可以用通配符_代表任何一個字元,%代表任何字元串。使用關鍵字<AND>、<OR>和<NOT>可以生成複雜的詞,它們運作檢查時使用布爾表達式的多重标準集。
mysql>select t1.name,t2.salary from employee ASt1,info AS t2 where t1.name =t2.name;
mysql>select college,region,seed from tournament
ORDER BYregion,seed;
mysql>select col_name from tbl_name WHERE col_name >0;
6.修改表中資料
在使用資料庫過程中,往往要修改其表中的資料,比如往表中添加新資料,删除表中原有資料,或對表中原有資料進行更改。它們的基本文法如下:
資料添加:
insert [into]table_name [(column(s))]
values(expression_r(s))
mysql>INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
資料删除:
删除from table_namewhere search_condition
資料更改:
更新table_name
setcolumn1=expression1,
column2=expression2,…
wheresearch_condition
7.資料庫切換
當存在多個資料庫時,可以用下面的指令定義使用者想使用的資料庫:
usedatabase_name
8.統計函數
SQL有一些統計函數,它們對于生成資料表格很有幫助。下面介紹幾個常用的統計函數:
sum(exepression)計算表達式的和
avg(exepression)計算表達式的平均值
count(exepression)對表達式進行簡單的計數
count (*)統計記錄數
max(exepression)求最大值
min(exepression)求最小值
其中exepression為任何有效的SQL表達式,它可以是一個或多個記錄,也可以是别的SQL函數的組合。
二、MySQL使用導引
1.運用MySQL建立新資料庫
在shell下運作:
$>mysqladmin create database01
Database "database01"created.
2.啟動MySQL
$>mysql
Welcome to the MySQLmonitor. Commands end with ; or g.
Your MySQL connectionid is 22 to server version: 3.21. 29a-gamma-debug
無效’help’for help.
3.更換資料庫
mysql>use database01
databasechanged.
4.建立表
mysql>create table table01 (field01integer,field02 char(10));
QueryOK,0 rows affected (0.00sec)
5.列出表清單
mysql>show tables;
Tables indatabase01
Table01
table02
6.列出表中的字段清單
mysql>show columns from table01;
Field無效Null Key DefaultExtra
field01 int(11)YES
field02 char(10)YES
7.表的資料填寫
插入資料
mysql>insert into table01(field01,field02) values(1,’first’);
QueryOK,1 row affected (0.00sec)
8.字段的增加
...一次一個字段
mysql>alter table table01 add column field03char(20);
QueryOK,l row affected (0.04sec)
Records: 1 Duplicates:0 Warnings: 0
...一次多個字段
mysql>alter table table01 add column field04date,add column field05time;
注意:每一列都必須以"addcolumn"重新開始。
它運作了嗎?讓我們看看。
mysql>select * from table01;
field01 field02field03 field04 field05
1 first NULL NULLNULL
9.多行指令輸入
MySQL指令行界面允許把陳述作為一行輸入,也可以把它展開為多行輸入。這兩者之間并沒有文法上的差別。使用多行輸入,你可以将SQL陳述一步步分解,進而使你更容易了解。
在多行方式下,注釋器把每一行都添加到前面的行後,直到你用分号";"來結束這個SQL陳述。一旦鍵入分号并按Enter鍵,這個陳述即被執行。
下面的例子是同一個嚴格的SQL陳述的兩種輸入方法:
單行輸入
Mysql>create table table33 (field01integer,field02 char(30));
多行輸入
Mysql>create table table33
->(field01
->integer,
->field02
->char(30));
注意不能将單詞斷開,如:
正确
mysql>create table table33
錯誤
->(field01 inte
->ger,
當插入或更改資料時,不能将字段的字元串展開到多行裡,否則硬回車将被儲存到資料中:
标準操作
mysql>insert into table33(field02)
->values
->(’who thought of foo?’);
硬回車儲存到資料中
->(’who thought
->offoo?’);
結果如下:
mysql>select * from table33;
field01field02
NULL who thought offoo?
NULL whothought
Of foo?
10.表的資料嵌入
mysql>insert into table01(field01,field02,field03,field04,field05) values
->(2,’second’,’another’,’1999-10-23’,’10:30:00’);
标準日期格式是"yyyy-mm-dd"。
标準時間格式是"hh:mm:ss"。
引号内要求所給的是上述的标準日期和時間格式。
日期也可以"yyyymmdd"形式,時間也可以"hhmmss"形式輸入,但其值不需要再加引号。
數字值不需要加引号。這種儲存與資料類型無關,這些資料類型都有格式化的專欄來包含(例如:文本,日期,時間,整數等)。
MySQL有一個很有用的指令緩沖區。它儲存着你目前已經鍵入的SQL語句利用它,對于相同的指令,你就不必一遍又一遍地重複輸入。下一步我們就來看這樣的一個例子。
利用指令緩沖區(及任意的日期和時間格式)增加另一個資料
按兩次鍵盤上的向上箭頭鍵。
回車。
在圓括号内輸入新的值,并以分号結尾。
(3,’athird’,’more’,19991024,103004);
新值存在裡面了嗎?
2 second another1999-10-23 10:30:00
3 a third more1999-10-24 10:30:04
11.表的資料更新
一次修改一個字段
再次注意文法。文本需要加引号但數字不要。
mysql>更新table01 setfield03=’new info’where field01=1;
一次改變多個字段
記住在每一個更新的字段間用逗号隔開。
mysql>更新table01 setfield04=19991022,field05=062218 wherefield01=1;
一次更新多個資料
mysql>更新table01 set field05=152901where field04>19990101;
QueryOK,3 rows affected (0.00sec)
12.删除資料
mysql>删除from table01 wherefield01=3;
13.退出
mysql>quit
Bye
現在你已經了解了一些運作MySQL中的資料庫的根本指令。由于MySQL是通過執行SQL調用來操作的,在你的處理過程中需要一個強有力工具的充足的數組。例如,通過聯接相關的字段,你可以同時顯示幾個表中的資料。同樣,SQL允許綜合顯示、更新或者删除多個符合具體标準的資料。如果你還想精通掌握它,下一步就要學習所有SQL的知識。
--1、查找員工的編号、姓名、部門和出生日期,如果出生日期為空值,顯示日期不詳,并按部門排序輸出,日期格式為yyyy-mm-dd。
selectemp_no,emp_name,dept,isnull(convert(char(10),birthday,120),'日期不詳') birthday
fromemployee
order bydept
--2、查找與喻自強在同一個機關的員工姓名、性别、部門和職稱
selectemp_no,emp_name,dept,title
whereemp_name<>'喻自強' and dept in
(selectdept from employee
whereemp_name='喻自強')
--3、按部門進行彙總,統計每個部門的總工資
selectdept,sum(salary)
group bydept
--4、查找商品名稱為14寸顯示器商品的銷售情況,顯示該商品的編号、銷售數量、單價和金額
selecta.prod_id,qty,unit_price,unit_price*qty totprice
fromsale_item a,product b
wherea.prod_id=b.prod_id and prod_name='14寸顯示器'
--5、在銷售明細表中按産品編号進行彙總,統計每種産品的銷售數量和金額
selectprod_id,sum(qty) totqty,sum(qty*unit_price) totprice
fromsale_item
group byprod_id
--6、使用convert函數按客戶編号統計每個客戶1996年的訂單總金額
selectcust_id,sum(tot_amt) totprice
fromsales
whereconvert(char(4),order_date,120)='1996'
group bycust_id
--7、查找有銷售記錄的客戶編号、名稱和訂單總額
selecta.cust_id,cust_name,sum(tot_amt) totprice
fromcustomer a,sales b
wherea.cust_id=b.cust_id
group bya.cust_id,cust_name
--8、查找在1997年中有銷售記錄的客戶編号、名稱和訂單總額
wherea.cust_id=b.cust_id andconvert(char(4),order_date,120)='1997'
--9、查找一次銷售最大的銷售記錄
selectorder_no,cust_id,sale_id,tot_amt
wheretot_amt=
(selectmax(tot_amt)
fromsales)
--10、查找至少有3次銷售的業務員名單和銷售日期
selectemp_name,order_date
fromemployee a,sales b
whereemp_no=sale_id and a.emp_no in
(selectsale_id
group bysale_id
havingcount(*)>=3)
order byemp_name
--11、用存在量詞查找沒有訂貨記錄的客戶名稱
selectcust_name
fromcustomer a
where notexists
(select*
from salesb
wherea.cust_id=b.cust_id)
--12、使用左外連接配接查找每個客戶的客戶編号、名稱、訂貨日期、訂單金額訂貨日期不要顯示時間,日期格式為yyyy-mm-dd按客戶編号排序,同一客戶再按訂單降序排序輸出
selecta.cust_id,cust_name,convert(char(10),order_date,120),tot_amt
fromcustomer a left outer join sales b ona.cust_id=b.cust_id
order bya.cust_id,tot_amt desc
--13、查找16M DRAM的銷售情況,要求顯示相應的銷售員的姓名、性别,銷售日期、銷售數量和金額,其中性别用男、女表示
selectemp_name姓名,性别= case a.sex when 'm'then '男'
when 'f'then '女'
else'未'
end,
銷售日期=isnull(convert(char(10),c.order_date,120),'日期不詳'),
qty數量, qty*unit_priceas金額
fromemployee a, sales b, sale_item c,product d
whered.prod_name='16M DRAM' and d.prod_id=c.prod_id and
a.emp_no=b.sale_id and b.order_no=c.order_no
--14、查找每個人的銷售記錄,要求顯示銷售員的編号、姓名、性别、産品名稱、數量、單價、金額和銷售日期
selectemp_no編号,emp_name姓名,性别= case a.sex when 'm'then '男'
prod_name産品名稱,銷售日期=isnull(convert(char(10),c.order_date,120),'日期不詳'),
fromemployee a left outer join sales b on a.emp_no=b.sale_id ,sale_item c,product d
whered.prod_id=c.prod_id and b.order_no=c.order_no
--15、查找銷售金額最大的客戶名稱和總貨款
selectcust_name,d.cust_sum
fromcustomer a,
(selectcust_id,cust_sum
from(select cust_id, sum(tot_amt) as cust_sum
group bycust_id ) b
whereb.cust_sum =
( selectmax(cust_sum)
group bycust_id ) c )
)d
wherea.cust_id=d.cust_id
--16、查找銷售總額少于1000元的銷售員編号、姓名和銷售額
selectemp_no,emp_name,d.sale_sum
fromemployee a,
(selectsale_id,sale_sum
from(select sale_id, sum(tot_amt) as sale_sum
group bysale_id ) b
whereb.sale_sum <1000
wherea.emp_no=d.sale_id
--17、查找至少銷售了3種商品的客戶編号、客戶名稱、商品編号、商品名稱、數量和金額
selecta.cust_id,cust_name,b.prod_id,prod_name,d.qty,d.qty*d.unit_price
fromcustomer a, product b, sales c, sale_item d
wherea.cust_id=c.cust_id and d.prod_id=b.prod_id and
c.order_no=d.order_no and a.cust_id in (
selectcust_id
from(select cust_id,count(distinct prod_id) prodid
from(select cust_id,prod_id
from salese,sale_item f
wheree.order_no=f.order_no) g
havingcount(distinct prod_id)>=3) h )
--18、查找至少與世界技術開發公司銷售相同的客戶編号、名稱和商品編号、商品名稱、數量和金額
selecta.cust_id,cust_name,d.prod_id,prod_name,qty,qty*unit_price
c.order_no=d.order_no and not exists
(selectf.*
fromcustomer x ,sales e, sale_item f
wherecust_name='世界技術開發公司' and x.cust_id=e.cust_id and
e.order_no=f.order_no and not exists
( selectg.*
fromsale_item g, sales h
whereg.prod_id = f.prod_id and g.order_no=h.order_no and
h.cust_id=a.cust_id)
)
19、查找表中所有姓劉的職工的工号,部門,薪水
selectemp_no,emp_name,dept,salary
whereemp_name like '劉%'
20、查找所有定單金額高于2000的所有客戶編号
wheretot_amt>2000
21、統計表中員工的薪水在4000-6000之間的人數
selectcount(*)as人數
wheresalary between 4000 and 6000
22、查詢表中的同一部門的職工的平均工資,但隻查詢"住址"是"上海市"的員工
selectavg(salary) avg_sal,dept
where addrlike '上海市%'
23、将表中住址為"上海市"的員工住址改為"北京市"
updateemployee
set addrlike '北京市'
where addrlike '上海市'
24、查找業務部或會計部的女員工的基本資訊。
selectemp_no,emp_name,dept
wheresex='F'and dept in ('業務','會計')
25、顯示每種産品的銷售金額總和,并依銷售金額由大到小輸出。
selectprod_id ,sum(qty*unit_price)
order bysum(qty*unit_price) desc
26、選取編号界于'C0001'和'C0004'的客戶編号、客戶名稱、客戶位址。
selectCUST_ID,cust_name,addr
fromcustomer
wherecust_id between 'C0001' AND 'C0004'
27、計算出一共銷售了幾種産品。
selectcount(distinct prod_id) as '共銷售産品數'
28、将業務部員工的薪水上調3%。
setsalary=salary*1.03
wheredept='業務'
29、由employee表中查找出薪水最低的員工資訊。
select*
wheresalary=
(selectmin(salary )
fromemployee )
30、使用join查詢客戶姓名為"客戶丙"所購貨物的"客戶名稱","定單金額","定貨日期","電話号碼"
selecta.cust_id,b.tot_amt,b.order_date,a.tel_no
fromcustomer a join sales b
ona.cust_id=b.cust_id and cust_name like '客戶丙'
31、由sales表中查找出訂單金額大于"E0013業務員在1996/10/15這天所接每一張訂單的金額"的所有訂單。
wheretot_amt>all
(selecttot_amt
wheresale_id='E0013'and order_date='1996/10/15')
order bytot_amt
32、計算'P0001'産品的平均銷售單價
selectavg(unit_price)
whereprod_id='P0001'
33、找出公司女員工所接的定單
selectsale_id,tot_amt
wheresale_id in
(selectsale_id from employee
wheresex='F')
34、找出同一天進入公司服務的員工
selecta.emp_no,a.emp_name,a.date_hired
fromemployee a
joinemployee b
on(a.emp_no!=b.emp_no and a.date_hired=b.date_hired)
order bya.date_hired
35、找出目前業績超過232000元的員工編号和姓名。
selectemp_no,emp_name
whereemp_no in
havingsum(tot_amt)<232000)
36、查詢出employee表中所有女職工的平均工資和住址在"上海市"的所有女職工的平均工資
selectavg(salary)
where sexlike 'f'
union
where sexlike 'f' and addr like '上海市%'
37、在employee表中查詢薪水超過員工平均薪水的員工資訊。
Select*
wheresalary>( select avg(salary)
fromemployee)
38、找出目前銷售業績超過10000元的業務員編号及銷售業績,并按銷售業績從大到小排序。
Selectsale_id ,sum(tot_amt)
havingsum(tot_amt)>10000
order bysum(tot_amt) desc
39、找出公司男業務員所接且訂單金額超過2000元的訂單号及訂單金額。
Selectorder_no,tot_amt
From sales,employee
Wheresale_id=emp_no and sex='M' andtot_amt>2000
40、查詢sales表中訂單金額最高的訂單号及訂單金額。
Selectorder_no,tot_amt from sales
wheretot_amt=(select max(tot_amt) from sales)
41、查詢在每張訂單中訂購金額超過4000元的客戶名及其位址。
Selectcust_name,addr from customer a,sales b
wherea.cust_id=b.cust_id and tot_amt>4000
42、求出每位客戶的總訂購金額,顯示出客戶号及總訂購金額,并按總訂購金額降序排列。
Selectcust_id,sum(tot_amt) from sales
Group bycust_id
Order bysum(tot_amt) desc
43、求每位客戶訂購的每種産品的總數量及平均單價,并按客戶号,産品号從小到大排列。
Selectcust_id,prod_id,sum(qty),sum(qty*unit_price)/sum(qty)
From salesa, sale_item b
Wherea.order_no=b.order_no
Group bycust_id,prod_id
Order bycust_id,prod_id
44、查詢訂購了三種以上産品的訂單号。
Selectorder_no
Group byorder_no
Havingcount(*)>3
45、查詢訂購的産品至少包含了訂單3号中所訂購産品的訂單。
Selectdistinct order_no
Fromsale_item a
Whereorder_no<>'3'and not exists(
Select *from sale_item b where order_no ='3' and not exists
(select *from sale_item c where c.order_no=a.order_no andc.prod_id=b.prod_id))
46、在sales表中查找出訂單金額大于"E0013業務員在1996/11/10這天所接每一張訂單的金額"的所有訂單,并顯示承接這些訂單的業務員和該訂單的金額。
Selectsale_id,tot_amt from sales
wheretot_amt>all(select tot_amt
wheresale_id='E0013' and order_date='1996-11-10')
47、查詢末承接業務的員工的資訊。
Fromemployee a
Where notexists
(select *from sales b where a.emp_no=b.sale_id)
48、查詢來自上海市的客戶的姓名,電話、訂單号及訂單金額。
Selectcust_name,tel_no,order_no,tot_amt
Fromcustomer a ,sales b
Wherea.cust_id=b.cust_id and addr='上海市'
49、查詢每位業務員各個月的業績,并按業務員編号、月份降序排序。
Selectsale_id,month(order_date), sum(tot_amt)
group bysale_id,month(order_date)
order bysale_id,month(order_date) desc
50、求每種産品的總銷售數量及總銷售金額,要求顯示出産品編号、産品名稱,總數量及總金額,并按産品号從小到大排列。
Selecta.prod_id,prod_name,sum(qty),sum(qty*unit_price)
Fromsale_item a,product b
Wherea.prod_id=b.prod_id
Group bya.prod_id,prod_name
Order bya.prod_id
51、查詢總訂購金額超過'C0002'客戶的總訂購金額的客戶号,客戶名及其住址。
Selectcust_id, cust_name,addr
Fromcustomer
Wherecust_id in (select cust_id from sales
Havingsum(tot_amt)>
(Selectsum(tot_amt) from sales where cust_id='C0002'))
52、查詢業績最好的的業務員号、業務員名及其總銷售金額。
selectemp_no,emp_name,sum(tot_amt)
wherea.emp_no=b.sale_id
group byemp_no,emp_name
havingsum(tot_amt)=
(selectmax(totamt)
from(select sale_id,sum(tot_amt) totamt
group bysale_id) c)
53、查詢每位客戶所訂購的每種産品的詳細清單,要求顯示出客戶号,客戶名,産品号,産品名,數量及單價。
selecta.cust_id, cust_name,c.prod_id,prod_name,qty, unit_price
fromcustomer a,sales b, sale_item c ,product d
wherea.cust_id=b.cust_id and b.order_no=c.order_no andc.prod_id=d.prod_id
54、求各部門的平均薪水,要求按平均薪水從小到大排序。
selectdept,avg(salary)
order byavg(salary)
jxwpx1人了這篇文章
類别:資料庫系列┆技術圈(0)┆閱讀(116)┆評論(1)┆推送到技術圈┆傳回首頁
上一篇sql語句下一篇SoX編譯出錯
相關文章
MySQL指令大全-指令詳解mysql錯誤大全以及解決方法mysql不能導入資料|mysql load data文法|mys..MYSQL人事工資管理系統--設計視圖(四)遠端通路MySQL失敗的原因分析修改破解MYSQL密碼方法大全(轉自木馬論壇h..從php+mysql環境的注入,到整台伺服器的淪陷mysql資料庫‘複制’的辦法MySQL修改密碼方法總結php操作ysql資料庫常用的類
文章評論
[1樓]jxwpx
2010-12-1817:43:59
mysql存儲引擎:InnoDB和MyISAM的差別與優劣
關鍵字: mysql innodbmyisam
MyISAM:這個是預設類型,它是基于傳統的ISAM類型,ISAM是Indexed Sequential Access Method(有索引的順序通路方法)的縮寫,它是存儲記錄和檔案的标準方法.與其他存儲引擎比較,MyISAM具有檢查和修複表格的大多數工具. MyISAM表格可以被壓縮,而且它們支援全文搜尋.它們不是事務安全的,而且也不支援外鍵。如果事物復原将造成不完全復原,不具有原子性。如果執行大量的SELECT,MyISAM是更好的選擇。
InnoDB:這種類型是事務安全的.它與BDB類型具有相同的特性,它們還支援外鍵.InnoDB表格速度很快.具有比BDB還豐富的特性,是以如果需要一個事務安全的存儲引擎,建議使用它.如果你的資料執行大量的INSERT或UPDATE,出于性能方面的考慮,應該使用InnoDB表,
對于支援事物的InnoDB類型的标,影響速度的主要原因是AUTOCOMMIT預設設定是打開的,而且程式沒有顯式調用BEGIN開始事務,導緻每插入一條都自動Commit,嚴重影響了速度。可以在執行sql前調用begin,多條sql形成一個事物(即使autocommit打開也可以),将大大提高性能。
===============================================================
InnoDB和MyISAM是在使用MySQL最常用的兩個表類型,各有優缺點,視具體應用而定。下面是已知的兩者之間的差别,僅供參考。
InnoDB
InnoDB給MySQL提供了具有事務(commit)、復原(rollback)和崩潰修複能力(crash recovery capabilities)的事務安全(transaction-safe (ACIDcompliant))型表。InnoDB提供了行鎖(locking on rowlevel),提供與Oracle類型一緻的不加鎖讀取(non-lockingread in SELECTs)。這些特性均提高了多使用者并發操作的性能表現。在InnoDB表中不需要擴大鎖定(lock escalation),因為InnoDB的列鎖定(row levellocks)适宜非常小的空間。InnoDB是MySQL上第一個提供外鍵限制(FOREIGN KEYconstraints)的表引擎。
InnoDB的設計目标是處理大容量資料庫系統,它的CPU使用率是其它基于磁盤的關系資料庫引擎所不能比的。在技術上,InnoDB是一套放在MySQL背景的完整資料庫系統,InnoDB在主記憶體中建立其專用的緩沖池用于高速緩沖資料和索引。InnoDB把資料和索引存放在表空間裡,可能包含多個檔案,這與其它的不一樣,舉例來說,在MyISAM中,表被存放在單獨的檔案中。InnoDB表的大小隻受限于作業系統的檔案大小,一般為2GB。
InnoDB所有的表都儲存在同一個資料檔案ibdata1中(也可能是多個檔案,或者是獨立的表空間檔案),相對來說比較不好備份,免費的方案可以是拷貝資料檔案、備份binlog,或者用mysqldump。
MyISAM
MyISAM是MySQL預設存貯引擎.
每張MyISAM表被存放在三個檔案。frm檔案存放表格定義。資料檔案是MYD (MYData)。索引檔案是MYI(MYIndex)引伸。
因為MyISAM相對簡單是以在效率上要優于InnoDB..小型應用使用MyISAM是不錯的選擇.
MyISAM表是儲存成檔案的形式,在跨平台的資料轉移中使用MyISAM存儲會省去不少的麻煩
以下是一些細節和具體實作的差别:
1.InnoDB不支援FULLTEXT類型的索引。
2.InnoDB中不儲存表的具體行數,也就是說,執行selectcount(*) from table時,InnoDB要掃描一遍整個表來計算有多少行,但是MyISAM隻要簡單的讀出儲存好的行數即可。注意的是,當count(*)語句包含where條件時,兩種表的操作是一樣的。
3.對于AUTO_INCREMENT類型的字段,InnoDB中必須包含隻有該字段的索引,但是在MyISAM表中,可以和其他字段一起建立聯合索引。
4.DELETEFROM table時,InnoDB不會重建立立表,而是一行一行的删除。
5.LOADTABLE FROM MASTER操作對InnoDB是不起作用的,解決方法是首先把InnoDB表改成MyISAM表,導入資料後再改成InnoDB表,但是對于使用的額外的InnoDB特性(例如外鍵)的表不适用。
另外,InnoDB表的行鎖也不是絕對的,如果在執行一個SQL語句時MySQL不能确定要掃描的範圍,InnoDB表同樣會鎖全表,例如update table set num=1 where name like“a%”
任何一種表都不是萬能的,隻用恰當的針對業務類型來選擇合适的表類型,才能最大的發揮MySQL的性能優勢。
以下是InnoDB和MyISAM的一些聯系和差別!
1.4.0以上mysqld都支援事務,包括非max版本。3.23的需要max版本mysqld才能支援事務。
2.建立表時如果不指定type則預設為myisam,不支援事務。
可以用show create tabletablename指令看表的類型。
2.1對不支援事務的表做start/commit操作沒有任何效果,在執行commit前已經送出,測試:
執行一個msyql:
usetest;
drop tableif exists tn;
createtable tn (a varchar(10)) type=myisam;
drop tableif exists ty;
createtable ty (a varchar(10)) type=innodb;
begin;
insertinto tn values('a');
insertinto ty values('a');
select *from tn;
select *from ty;
都能看到一條記錄
執行另一個mysql:
隻有tn能看到一條記錄
然後在另一邊
commit;
才都能看到記錄。
3.可以執行以下指令來切換非事務表到事務(資料不會丢失),innodb表比myisam表更安全:
alter table tablename type=innodb;
3.1innodb表不能用repair table指令和myisamchk -r table_name
但可以用checktable,以及mysqlcheck [OPTIONS] database [tables]
4.啟動mysql資料庫的指令行中添加了以下參數可以使新發