bu資料庫
① 怎樣用php查詢資料庫里的一個數據並顯示(php查詢資料庫並輸出)
面向過程:
$sql="selectt_bumenfromt_xinxiwhereid=111";//Sql語句
$result=mysql_fetch_assoc(mysql_query($sql));//執行巧散sql語句並以關好寬逗聯數組保存友賣
print_r($result);//輸出數組
② 資料庫建立索引怎麼利用索引查詢
1.合理使用索引
索引是資料庫中重要的數據結構,它的根本目的就是為了提高查詢效率。現在大多數的資料庫產品都採用IBM最先提出的ISAM索引結構。
索引的使用要恰到好處,其使用原則如下:
在經常進行連接,但是沒有指定為外鍵的列上建立索引,而不經常連接的欄位則由優化器自動生成索引。
在頻繁進行排序或分組(即進行group by或order by操作)的列上建立索引。
在條件表達式中經常用到的不同值較多的列上建立檢索,在不同值少的列上不要建立索引。比如在雇員表的「性別」列上只有「男」與「女」兩個不同值,因此就無必要建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低更新速度。
如果待排序的列有多個,可以在這些列上建立復合索引(compound index)。
使用系統工具。如Informix資料庫有一個tbcheck工具,可以在可疑的索引上進行檢查。在一些資料庫伺服器上,索引可能失效或者因為頻繁操作而 使得讀取效率降低,如果一個使用索引的查詢不明不白地慢下來,可以試著用tbcheck工具檢查索引的完整性,必要時進行修復。另外,當資料庫表更新大量 數據後,刪除並重建索引可以提高查詢速度。
(1)在下面兩條select語句中:
SELECT * FROM table1 WHERE field1<=10000 AND field1>=0;
SELECT * FROM table1 WHERE field1>=0 AND field1<=10000;
如果數據表中的數據field1都>=0,則第一條select語句要比第二條select語句效率高的多,因為第二條select語句的第一個條件耗費了大量的系統資源。
第一個原則:在where子句中應把最具限制性的條件放在最前面。
(2)在下面的select語句中:
SELECT * FROM tab WHERE a=… AND b=… AND c=…;
若有索引index(a,b,c),則where子句中欄位的順序應和索引中欄位順序一致。
第二個原則:where子句中欄位的順序應和索引中欄位順序一致。
——————————————————————————
以下假設在field1上有唯一索引I1,在field2上有非唯一索引I2。
——————————————————————————
(3) SELECT field3,field4 FROM tb WHERE field1='sdf' 快
SELECT * FROM tb WHERE field1='sdf' 慢[/cci]
因為後者在索引掃描後要多一步ROWID表訪問。
(4) SELECT field3,field4 FROM tb WHERE field1>='sdf' 快
SELECT field3,field4 FROM tb WHERE field1>'sdf' 慢
因為前者可以迅速定位索引。
(5) SELECT field3,field4 FROM tb WHERE field2 LIKE 'R%' 快
SELECT field3,field4 FROM tb WHERE field2 LIKE '%R' 慢,
因為後者不使用索引。
(6) 使用函數如:
SELECT field3,field4 FROM tb WHERE upper(field2)='RMN'不使用索引。
如果一個表有兩萬條記錄,建議不使用函數;如果一個表有五萬條以上記錄,嚴格禁止使用函數!兩萬條記錄以下沒有限制。
(7) 空值不在索引中存儲,所以
SELECT field3,field4 FROM tb WHERE field2 IS[NOT] NULL不使用索引。
(8) 不等式如
SELECT field3,field4 FROM tb WHERE field2!='TOM'不使用索引。
相似地,
SELECT field3,field4 FROM tb WHERE field2 NOT IN('M','P')不使用索引。
(9) 多列索引,只有當查詢中索引首列被用於條件時,索引才能被使用。
(10) MAX,MIN等函數,使用索引。
SELECT max(field2) FROM tb 所以,如果需要對欄位取max,min,sum等,應該加索引。
一次只使用一個聚集函數,如:
SELECT 「min」=min(field1), 「max」=max(field1) FROM tb
不如:SELECT 「min」=(SELECT min(field1) FROM tb) , 「max」=(SELECT max(field1) FROM tb)
(11) 重復值過多的索引不會被查詢優化器使用。而且因為建了索引,修改該欄位值時還要修改索引,所以更新該欄位的操作比沒有索引更慢。
(12) 索引值過大(如在一個char(40)的欄位上建索引),會造成大量的I/O開銷(甚至會超過表掃描的I/O開銷)。因此,盡量使用整數索引。 Sp_estspace可以計算表和索引的開銷。
(13) 對於多列索引,ORDER BY的順序必須和索引的欄位順序一致。
(14) 在sybase中,如果ORDER BY的欄位組成一個簇索引,那麼無須做ORDER BY。記錄的排列順序是與簇索引一致的。
(15) 多表聯結(具體查詢方案需要通過測試得到)
where子句中限定條件盡量使用相關聯的欄位,且盡量把相關聯的欄位放在前面。
SELECT a.field1,b.field2 FROM a,b WHERE a.field3=b.field3
field3上沒有索引的情況下:
對a作全表掃描,結果排序
對b作全表掃描,結果排序
結果合並。
對於很小的表或巨大的表比較合適。
field3上有索引
按照表聯結的次序,b為驅動表,a為被驅動表
對b作全表掃描
對a作索引范圍掃描
如果匹配,通過a的rowid訪問
(16) 避免一對多的join。如:
SELECT tb1.field3,tb1.field4,tb2.field2 FROM tb1,tb2 WHERE tb1.field2=tb2.field2 AND tb1.field2=『BU1032』 AND tb2.field2= 『aaa』
不如:
declare @a varchar(80)
SELECT @a=field2 FROM tb2 WHERE field2=『aaa』
SELECT tb1.field3,tb1.field4,@a FROM tb1 WHERE field2= 『aaa』
(16) 子查詢
用exists/not exists代替in/not in操作
比較:
SELECT a.field1 FROM a WHERE a.field2 IN(SELECT b.field1 FROM b WHERE b.field2=100)
SELECT a.field1 FROM a WHERE EXISTS( SELECT 1 FROM b WHERE a.field2=b.field1 AND b.field2=100)
SELECT field1 FROM a WHERE field1 NOT IN( SELECT field2 FROM b)
SELECT field1 FROM a WHERE NOT EXISTS( SELECT 1 FROM b WHERE b.field2=a.field1)
(17) 主、外鍵主要用於數據約束,sybase中創建主鍵時會自動創建索引,外鍵與索引無關,提高性能必須再建索引。
(18) char類型的欄位不建索引比int類型的欄位不建索引更糟糕。建索引後性能只稍差一點。
(19) 使用count(*)而不要使用count(column_name),避免使用count(DISTINCT column_name)。
(20) 等號右邊盡量不要使用欄位名,如:
SELECT * FROM tb WHERE field1 = field3
(21) 避免使用or條件,因為or不使用索引。
2.避免使用order by和group by字句。
因為使用這兩個子句會佔用大量的臨時空間(tempspace),如果一定要使用,可用視圖、人工生成臨時表的方法來代替。
如果必須使用,先檢查memory、tempdb的大小。
測試證明,特別要避免一個查詢里既使用join又使用group by,速度會非常慢!
3.盡量少用子查詢,特別是相關子查詢。因為這樣會導致效率下降。
一個列的標簽同時在主查詢和where子句中的查詢中出現,那麼很可能當主查詢中的列值改變之後,子查詢必須重新查詢一次。查詢嵌套層次越多,效率越低,因此應當盡量避免子查詢。如果子查詢不可避免,那麼要在子查詢中過濾掉盡可能多的行。
4.消除對大型錶行數據的順序存取
在 嵌套查詢中,對表的順序存取對查詢效率可能產生致命的影響。
比如採用順序存取策略,一個嵌套3層的查詢,如果每層都查詢1000行,那麼這個查詢就要查詢 10億行數據。
避免這種情況的主要方法就是對連接的列進行索引。
例如,兩個表:學生表(學號、姓名、年齡……)和選課表(學號、課程號、成績)。如果兩個 表要做連接,就要在「學號」這個連接欄位上建立索引。
還可以使用並集來避免順序存取。盡管在所有的檢查列上都有索引,但某些形式的where子句強迫優化器使用順序存取。
下面的查詢將強迫對orders表執行順序操作:
SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008
雖然在customer_num和order_num上建有索引,但是在上面的語句中優化器還是使用順序存取路徑掃描整個表。因為這個語句要檢索的是分離的行的集合,所以應該改為如下語句:
SELECT * FROM orders WHERE customer_num=104 AND order_num>1001
UNION
SELECT * FROM orders WHERE order_num=1008
這樣就能利用索引路徑處理查詢。
5.避免困難的正規表達式
MATCHES和LIKE關鍵字支持通配符匹配,技術上叫正規表達式。但這種匹配特別耗費時間。例如:SELECT * FROM customer WHERE zipcode LIKE 「98_ _ _」
即使在zipcode欄位上建立了索引,在這種情況下也還是採用順序掃描的方式。如果把語句改為SELECT * FROM customer WHERE zipcode >「98000」,在執行查詢時就會利用索引來查詢,顯然會大大提高速度。
另外,還要避免非開始的子串。例如語句:SELECT * FROM customer WHERE zipcode[2,3] >「80」,在where子句中採用了非開始子串,因而這個語句也不會使用索引。
6.使用臨時表加速查詢
把表的一個子集進行排序並創建臨時表,有時能加速查詢。它有助於避免多重排序操作,而且在其他方面還能簡化優化器的工作。例如:
SELECT cust.name,rcvbles.balance,……other COLUMNS
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>0
AND cust.postcode>「98000」
ORDER BY cust.name
如果這個查詢要被執行多次而不止一次,可以把所有未付款的客戶找出來放在一個臨時文件中,並按客戶的名字進行排序:
SELECT cust.name,rcvbles.balance,……other COLUMNS
FROM cust,rcvbles
WHERE cust.customer_id = rcvlbes.customer_id
AND rcvblls.balance>;0
ORDER BY cust.name
INTO TEMP cust_with_balance
然後以下面的方式在臨時表中查詢:
SELECT * FROM cust_with_balance
WHERE postcode>「98000」
臨時表中的行要比主表中的行少,而且物理順序就是所要求的順序,減少了磁碟I/O,所以查詢工作量可以得到大幅減少。
注意:臨時表創建後不會反映主表的修改。在主表中數據頻繁修改的情況下,注意不要丟失數據。
7.用排序來取代非順序存取
非順序磁碟存取是最慢的操作,表現在磁碟存取臂的來回移動。SQL語句隱藏了這一情況,使得我們在寫應用程序時很容易寫出要求存取大量非順序頁的查詢。
③ SQLserver資料庫備份後,怎麼查詢備份的日誌
SQL Server的備份有三種形式:
一是全備份(full backup)
這個備份裡麵包含的內容是值得商榷的,我們知道資料庫有兩種文件,數據文件與日誌文件,全備份是不是將所有的數據文件與日誌文件打包,備份成一個文件? 那麼還原的時候是不是需要做恢復,將備份過後發生的事務接著備份時間點重新執行一邊? 上面的問題細想都是肯定的。全備份做的事情,就是將所有的緩存先flush到磁碟上,不管在進行的事務是否提交,這樣保證了日誌的連續性,數據與日誌的一致性,如果事務沒提交 ,在日誌文件上的標記是active的,這段日誌也就不會被清空,下次恢復的時候,就從這段日誌開始,接著使用新的日誌執行。因此 全備份之前肯定會執行一次checkpoint;、
二是差異備份(differential backup)
這個備份會不會也重復full backup的過程,先執行checkpoint,然後再將上一次備份之後,發生數據頁變化的這些數據頁都備份起來,這部分備份就不會有日誌。但是和全備份一樣,備份的容積體量比較大,差異備份備份的是數據頁,不管這一頁是不是只有一條數據更改了,還是全部更改了;
三是日誌備份(transaction log backup)
日誌備份中需要注意的就是對未提交事務的理解,沒有提交的事務其實還是佔用日誌文件的VLF,shrink並不能回收日誌空間;提交事務的日誌如被備份之後,就會將日誌VLF打上unactive或者truncated標記,這個時候執行shrink就可以回收這部分日誌VLF了。日誌備份體量小,比較適合頻率高的執行,比如每5分鍾執行一次。
全備份:
全備份用到的命令,涉及到兩方面的參數,一是指定相應的備份設備,可以是磁碟,也可以是磁帶;另一方面 就是備份可用的選項,比如是否壓縮,是否加密。
BACKUP DATABASE database
TO backup_device [ ,...n ]
[ WITH with_options [ ,...o ] ] ;
備份設備很講究,可以事先定義好邏輯設備,也可以直接指定物理設備。磁帶備份機倒是沒見過,但是常規的磁碟備份還是可以討論一下的:
我們可以將一個本機帶路徑的物理文件名指定為備份設備:
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup.bck';
也可以將網路上的一個帶路徑的物理文件名指定為備份設備:
backup database AdventureWorks2012
to disk = '\BackupSystemBackupDisk1AW_backupsAdventureWorksData.Bak';
這里有個有趣的現象,如果我們在全備份之後 ,沒有備份好日誌,這個時候故障突然發生了,我們需要作恢復,但是恢復的時候因為會重寫日誌,這樣就會丟失數據,如果不採取額外地措施,系統是會報錯的:
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup.bck'
Msg 3159, Level 16, State 1, Line 6
The tail of the log for the database 「lenistest」 has not been backed
up. Use BACKUP LOG WITH NORECOVERY to backup the log if it contains
work you do not want to lose. Use the WITH REPLACE or WITH STOPAT
clause of the RESTORE statement to just overwrite the contents of the
log.
Msg 3013, Level 16, State 1, Line 6
RESTORE DATABASE is terminating abnormally.
所以如果對丟失的數據不關心或者認為不會丟失數據,可以採用with replace選項來重寫原來的日誌文件進行強制恢復。
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup.bck'
with replace;
差異備份:
差異備份相對全備份,優越的地方在於備份數據量少,但是有趣的是差異備份不能獨立存在(日誌備份也不能獨立存在,他倆只能依附於全備份,也就是說在執行差異備份和日誌備份的時候,必須先有一個全備份做好在那裡), 差異備份必須以一個全備份做基準,在這基礎之上再判斷哪些數據頁是有過更新的,這些更新的數據頁計算出來並被備份起來。
use master;
go
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup.bck';
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup.bck'
with differential;
假如我們沒有事先做好全備份,就直接作差異備份了,那麼這是不成功的:
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup2.bck'
with differential;
Msg 3035, Level 16, State 1, Line 11
Cannot perform a differential backup for database 「lenistest」, because
a current database backup does not exist. Perform a full database
backup by reissuing BACKUP DATABASE, omitting the WITH DIFFERENTIAL
option.
Msg 3013, Level 16, State 1, Line 11
BACKUP DATABASE is terminating abnormally.
日誌備份:
日誌備份相對差異備份來說,體量更小,同樣它也需要全備份事先存在:
backup log lenistestto disk = 'E:Data_BUlenistest5__backup.bck';
假如我沒有事先做好全備份,我們看看直接備份日誌會出現什麼結果:
Msg 4214, Level 16, State 1, Line 15
BACKUP LOG cannot be performed because there is no current database
backup.
Msg 3013, Level 16, State 1, Line 15
BACKUP LOG is terminating abnormally.
提示先做全備份!
備份我們都討論完了,接下來我們看看還原。還原通常有兩個步驟,一是還原,二是恢復。當然我們也可以直接還原不恢復,但是可能會丟失數據,除非全備份之後 ,沒有任何操作。假設我們一天一個全備份,每15分鍾做一個差異備份 ,每5分鍾做一個日誌備份,我們該如何還原我們的資料庫呢?
通常我們首先要知道我們的備份文件名或者物理路徑,這個地方涉及到很多術語很難理解,比如說backup device, backupset, backup media, media set ,media family.
MSDN上有一個解釋,先看這個腳本:
backup database AdventureWorks2012
to tape = '\. ape0'
, tape = '\. ape1'
, tape = '\. ape2'
with format
, medianame = 'MyAdvWorks_MediaSet_1';
解釋說到,這個備份操作產生了一個 media set, 這個media set就是命名為MyAdvWorks_MediaSet_1, 這個media set還有個media header, media header一旦生成,就可以往裡面寫入備份文件了。這段腳本也同時生成了一個橫跨三個tape的備份文件, 他們統稱為backup set.
當我們指定3個backup device作為backup set(備份集)並且執行第一次全備份的時候,接下來所有的備份都需要同時指定這3個backup device作為backup set:
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup02.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
with format
, medianame = 'lenistestbackupset';
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
with noinit
, differential
, medianame = 'lenistestbackupset';
Msg 3231, Level 16, State 1, Line 10
The media loaded on 「E:Data_BUlenistest5__backup01.bck」 is formatted
to support 3 media families, but 2 media families are expected
according to the backup device specification.
Msg 3013, Level 16, State 1, Line 10
BACKUP DATABASE is terminating abnormally.
上面我先作了一次全備份,指定了三個backup device作為一份backup set, 接下來作差異備份的時候,我只指定了其中兩個backup device作為backup set, 操作失敗,提示就是少了一個backup device.
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
, disk = 'E:Data_BUlenistest5__backup02.bck'
with noinit
, differential
, medianame = 'lenistestbackupset';
這次我們指定了同樣個數的backup device,但backup device的順序顛倒了一下,操作成功。
到目前為止,我們的腳本已經新建了 1 個media set,名為 lenistestbackupset , 2 個backup set, 第一個backup set是全備份的backup set,另外一個backup set是差異備份。所以每一次備份都會產生一個backup set. Media set產生的時間則是第一次給資料庫作全備份的時候。
這個時候我們需要恢復資料庫,那麼第一步就是要先還原全備份,但是先不恢復,等全備份還原過後,再用差異備份做恢復:
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
, disk = 'E:Data_BUlenistest5__backup02.bck'
with file = 1
, replace
, norecovery;
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
, disk = 'E:Data_BUlenistest5__backup02.bck'
with file = 2
, recovery;
這里一定是用replace來重寫日誌。
select mf.media_set_id
, isnull(ms.name, 'no media name') as media_name
, mf.physical_device_name
, mf.family_sequence_number
, mf.media_family_id
, bs.database_name
, bs.backup_start_date
, bs.backup_finish_date
from backupmediafamily mf
inner join backupset bs
on mf.media_set_id = bs.media_set_id
left join backupmediaset ms
on bs.media_set_id = ms.media_set_id
where bs.database_name = 'lenistest';
上面的腳本可以抓出來這些media family, media set, backup set的信息,如果像上面的例子一樣, 我們用3個backup device來承載備份,那麼這3個backup device組成了一個media family, 按照family_sequence_number來編排,1,2,3。
下面實現一個備份到恢復的全過程例子,分別在full backup, differential backup, log backup之前各出入同樣的數據,看看是不是還原的時候,能正確還原過來:
insert into dbo.dataloading
(
object_id
, object_name
)
select object_id
, name as object_name
from sys.objects;
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup02.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
with format
, medianame = 'lenistestbackupset';
insert into dbo.dataloading
(
object_id
, object_name
)
select object_id
, name as object_name
from sys.objects;
backup database lenistest
to disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
, disk = 'E:Data_BUlenistest5__backup02.bck'
with noinit
, differential
, medianame = 'lenistestbackupset';
insert into dbo.dataloading
(
object_id
, object_name
)
select object_id
, name as object_name
from sys.objects;
backup log lenistest
to disk = 'E:Data_BUlenistest5__backup01.bck'
, disk = 'E:Data_BUlenistest5__backup03.bck'
, disk = 'E:Data_BUlenistest5__backup02.bck'
with noinit
, medianame = 'lenistestbackupset';
接著我們做還原與恢復:
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup01.bck', disk = 'E:Data_BUlenistest5__backup03.bck', disk = 'E:Data_BUlenistest5__backup02.bck'
with file = 1
, replace
, norecovery;
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup01.bck', disk = 'E:Data_BUlenistest5__backup03.bck', disk = 'E:Data_BUlenistest5__backup02.bck'
with file = 2
, norecovery;
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup01.bck', disk = 'E:Data_BUlenistest5__backup03.bck', disk = 'E:Data_BUlenistest5__backup02.bck'
with file = 3
, recovery;
這里的file選項就是backup set選項,表示第一個備份集,第二個備份集,第三個備份集。如果想還原到最新的故障發生時間點,前面的restore都不能recovery,只有在最後的時候才能作recovery.
如果我們只想恢復全備份的數據,只要執行recovery就可以了,但是數據肯定是少了:
restore database lenistest
from disk = 'E:Data_BUlenistest5__backup01.bck', disk = 'E:Data_BUlenistest5__backup03.bck', disk = 'E:Data_BUlenistest5__backup02.bck'
with file = 1
, replace
, recovery;
④ 什麼是資料庫系統
資料庫系統(database systems),是由資料庫及其管理軟體組成的系統。它是為適應數據處理的需要而發展起來的一種較為理想的數據處理系統,也是一個實際可運行的存儲、維護和應用系統提供數據的軟體系統,是存儲介質、處理對象和管理系統的集合體。
來源:http://ke..com/link?url=C_
⑤ 如何處理大量數據並發操作
處理大量數據並發操作可以採用如下幾種方法:
1.使用緩存:使用程序直接保存到內存中。或者使用緩存框架: 用一個特定的類型值來保存,以區別空數據和未緩存的兩種狀態。
2.資料庫優化:表結構優化;SQL語句優化,語法優化和處理邏輯優化;分區;分表;索引優化;使用存儲過程代替直接操作。
3.分離活躍數據:可以分為活躍用戶和不活躍用戶。
4.批量讀取和延遲修改: 高並發情況可以將多個查詢請求合並到一個。高並發且頻繁修改的可以暫存緩存中。
5.讀寫分離: 資料庫伺服器配置多個,配置主從資料庫。寫用主資料庫,讀用從資料庫。
6.分布式資料庫: 將不同的表存放到不同的資料庫中,然後再放到不同的伺服器中。
7.NoSql和Hadoop: NoSql,not only SQL。沒有關系型資料庫那麼多限制,比較靈活高效。Hadoop,將一個表中的數據分層多塊,保存到多個節點(分布式)。每一塊數據都有多個節點保存(集群)。集群可以並行處理相同的數據,還可以保證數據的完整性。
拓展資料:
大數據(big data),指無法在一定時間范圍內用常規軟體工具進行捕捉、管理和處理的數據集合,是需要新處理模式才能具有更強的決策力、洞察發現力和流程優化能力的海量、高增長率和多樣化的信息資產。
在維克托·邁爾-舍恩伯格及肯尼斯·庫克耶編寫的《大數據時代》中大數據指不用隨機分析法(抽樣調查)這樣捷徑,而採用所有數據進行分析處理。大數據的5V特點(IBM提出):Volume(大量)、Velocity(高速)、Variety(多樣)、Value(低價值密度)、Veracity(真實性)。
⑥ 資料庫外鍵怎麼設置
SQL 資料庫建表時怎麼設置外鍵,
1> -- 創建測試主表. ID 是主鍵.
2> CREATE TABLE test_main (
3> id INT,
4> value VARCHAR(10),
5> PRIMARY KEY(id)
6> );
7> go
-- 建表時設置外鍵
1> CREATE TABLE test_sub (
2> id INT,
3> main_id INT,
4> value VARCHAR(10),
5> PRIMARY KEY(id),
6> FOREIGN KEY (main_id) REFERENCES test_main
7> );
8> go
sql怎麼設置外鍵
可以在創建表的時候創建,也可以在創建表之後創建。
創建表時創建:
create table student
(id int primary key,
name char(4),
dept char(9)
sex char(4))
create table grade
(id int ,
grade int
constraint id_fk foreign key (id) references student (id)
)
或創建了兩表之後再建
alter table grade
add constraint id_fk foreign key (id) references student (id)
呵呵,希望能幫助你。
sql server中圖形界面如何設置外鍵
在那個屬性上右鍵 有約束 自己添加就OK了
mysql怎麼設置外鍵?
ALTER TABLE b ADD CONSTRAINT c FOREIGN KEY(c) REFERENCES a(c) ON DELETE CASCADE ON UPDATE CASCADE; 哎呀。。好像寫反了。我寫的是把表B的c設置為外鍵了。。你改一下吧。
如何在資料庫的建立表的時候設置表的外鍵
1> -- 創建測試主表. ID 是主鍵.
2> CREATE TABLE test_main (
3> id INT,
4> value VARCHAR(10),
5> PRIMARY KEY(id)
6> );
7> go
-- 建表時設置外鍵
1> CREATE TABLE test_sub (
2> id INT,
3> main_id INT,
4> value VARCHAR(10),
5> PRIMARY KEY(id),
6> FOREIGN KEY (main_id) REFERENCES test_main
7> );
8> go
sql server 2008 怎麼設置外鍵
建外鍵的前提是此外鍵必須是另外一個表的主鍵。建外鍵的步驟: 第一步打開要建外鍵表的設計器,右擊選擇「關系」。然後彈出「外鍵關系」窗體,我們選擇「添加」,然後點擊「表和列規范」後面的小按鈕,就會彈出另外一個窗體讓我們選擇主鍵表和列,選好之後點擊確定。然後我們INSERT和UPDATE規范,在更新規則和刪除規則有四個選項,分別是「不執行任何操作」、「級聯」、「設置為NULL」、「設置默認值」。默認的不執行任何操作。如果是「不執行任何操作」,當我們刪除或更新主鍵表的數據時,會告訴用戶不能執行刪除或更新該操作。「級聯」的意思是當我們刪除或更新主鍵表的數據時,會刪除或更新外鍵表中所涉及的相關數據的所有行。 「設置Null」的意思是當我們刪除或更新主鍵表的數據時,外鍵表中的外鍵列的值會設為Null,但前提是該列允許為空。 「設置默認值」的意思是如果我們將外鍵列定義了默認值,當我們刪除或更新主鍵表的數據時,外鍵表中的外鍵列的值設為定義的默認值。 當然我們可以用代碼創建,當我們在創建資料庫表T——Card時只要加上一句話就OK啦,「Foreign key (studentNo) references T_Student(studentNo)"。如果我們已經創建了改表,那如何用代碼實現了,這也很簡單也就一句話「 add constraint CMPKey(外鍵名) foreign key(studentNo) references T_Student(studentNo)」。
sql中怎樣創建外鍵約束
在創建表之後,添加外鍵約束:
alter table yuangong add constraint fk foreign key (部門罰) references bumen(部門號)
或者在創建表的時候添加外鍵
foreign key (部門號) references bumen(部門號)放在最後,用","與列分隔
資料庫中,一對多的時候外鍵設置在多的那張表嗎?如果一對一的時候,外鍵應該設置在哪裡?多對多的時候,
首先,外鍵引用的那個列在主表中必須是主鍵列或者唯一列。
所以1:n的肯定把外鍵建立在n的那張表上。
1:1,一般要看誰是主表,誰是附屬表,外鍵當然建立在附屬表中。
n:m的情況,需要建立一個關系表,兩個原表和其關系分別是1:n,1
:m
資料庫語句怎麼加外鍵
1,創建表的時候添加:foreign key (你的外鍵) references (表名)(欄位名);
2,創建好之後修改:
alter table dbo.mh_User
add constraint FK_mh_User_..._id foreign key (你的外鍵) references (表名)(欄位名);
Sql server怎樣創建主外鍵關系
在要設置關系的外鍵表中,右擊關系→添加→在表和列規范中選擇關聯的主表再選擇外鍵表與其關聯的欄位
⑦ 資料庫表中某行數據由於事務超時,連接斷開無法回滾被鎖,但在被鎖的表中查不到該行數據所在表,怎麼解鎖
鎖的概述
一. 為什麼要引入鎖
多個用戶同時對資料庫的並發操作時會帶來以下數據不一致的問題:
丟失更新
A,B兩個用戶讀同一數據並進行修改,其中一個用戶的修改結果破壞了另一個修改的結果,比如訂票系統
臟讀
A用戶修改了數據,隨後B用戶又讀出該數據,但A用戶因為某些原因取消了對數據的修改,數據恢復原值,此時B得到的數據就與資料庫內的數據產生了不一致
不可重復讀
A用戶讀取數據,隨後B用戶讀出該數據並修改,此時A用戶再讀取數據時發現前後兩次的值不一致
並發控制的主要方法是封鎖,鎖就是在一段時間內禁止用戶做某些操作以避免產生數據不一致
二 鎖的分類
鎖的類別有兩種分法:
1. 從資料庫系統的角度來看:分為獨占鎖(即排它鎖),共享鎖和更新鎖
MS SQL Server 使用以下資源鎖模式。
鎖模式 描述
共享 (S) 用於不更改或不更新數據的操作(只讀操作),如 SELECT 語句。
更新 (U) 用於可更新的資源中。防止當多個會話在讀取、鎖定以及隨後可能進行的資源更新時發生常見形式的死鎖。
排它 (X) 用於數據修改操作,例如 INSERT、UPDATE 或 DELETE。確保不會同時同一資源進行多重更新。
意向鎖 用於建立鎖的層次結構。意向鎖的類型為:意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。
架構鎖 在執行依賴於表架構的操作時使用。架構鎖的類型為:架構修改 (Sch-M) 和架構穩定性 (Sch-S)。
大容量更新 (BU) 向表中大容量復制數據並指定了 TABLOCK 提示時使用。
共享鎖
共享 (S) 鎖允許並發事務讀取 (SELECT) 一個資源。資源上存在共享 (S) 鎖時,任何其它事務都不能修改數據。一旦已經讀取數據,便立即釋放資源上的共享 (S) 鎖,除非將事務隔離級別設置為可重復讀或更高級別,或者在事務生存周期內用鎖定提示保留共享 (S) 鎖。
更新鎖
更新 (U) 鎖可以防止通常形式的死鎖。一般更新模式由一個事務組成,此事務讀取記錄,獲取資源(頁或行)的共享 (S) 鎖,然後修改行,此操作要求鎖轉換為排它 (X) 鎖。如果兩個事務獲得了資源上的共享模式鎖,然後試圖同時更新數據,則一個事務嘗試將鎖轉換為排它 (X) 鎖。共享模式到排它鎖的轉換必須等待一段時間,因為一個事務的排它鎖與其它事務的共享模式鎖不兼容;發生鎖等待。第二個事務試圖獲取排它 (X) 鎖以進行更新。由於兩個事務都要轉換為排它 (X) 鎖,並且每個事務都等待另一個事務釋放共享模式鎖,因此發生死鎖。
若要避免這種潛在的死鎖問題,請使用更新 (U) 鎖。一次只有一個事務可以獲得資源的更新 (U) 鎖。如果事務修改資源,則更新 (U) 鎖轉換為排它 (X) 鎖。否則,鎖轉換為共享鎖。
排它鎖
排它 (X) 鎖可以防止並發事務對資源進行訪問。其它事務不能讀取或修改排它 (X) 鎖鎖定的數據。
意向鎖
意向鎖表示 SQL Server 需要在層次結構中的某些底層資源上獲取共享 (S) 鎖或排它 (X) 鎖。例如,放置在表級的共享意向鎖表示事務打算在表中的頁或行上放置共享 (S) 鎖。在表級設置意向鎖可防止另一個事務隨後在包含那一頁的表上獲取排它 (X) 鎖。意向鎖可以提高性能,因為 SQL Server 僅在表級檢查意向鎖來確定事務是否可以安全地獲取該表上的鎖。而無須檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。
意向鎖包括意向共享 (IS)、意向排它 (IX) 以及與意向排它共享 (SIX)。
鎖模式
描述
意向共享 (IS) 通過在各資源上放置 S 鎖,表明事務的意向是讀取層次結構中的部分(而不是全部)底層資源。
意向排它 (IX) 通過在各資源上放置 X 鎖,表明事務的意向是修改層次結構中的部分(而不是全部)底層資源。IX 是 IS 的超集。與意向排它共享 (SIX) 通過在各資源上放置 IX 鎖,表明事務的意向是讀取層次結構中的全部底層資源並修改部分(而不是全部)底層資源。允許頂層資源上的並發 IS 鎖。例如,表的 SIX 鎖在表上放置一個 SIX 鎖(允許並發 IS 鎖),在當前所修改頁上放置 IX 鎖(在已修改行上放置 X 鎖)。雖然每個資源在一段時間內只能有一個 SIX 鎖,以防止其它事務對資源進行更新,但是其它事務可以通過獲取表級的 IS 鎖來讀取層次結構中的底層資源。
獨占鎖:只允許進行鎖定操作的程序使用,其他任何對他的操作均不會被接受。執行數據更新命令時,SQL Server會自動使用獨占鎖。當對象上有其他鎖存在時,無法對其加獨占鎖。
共享鎖:共享鎖鎖定的資源可以被其他用戶讀取,但其他用戶無法修改它,在執行Select時,SQL Server會對對象加共享鎖。
更新鎖:當SQL Server准備更新數據時,它首先對數據對象作更新鎖鎖定,這樣數據將不能被修改,但可以讀取。等到SQL Server確定要進行更新數據操作時,他會自動將更新鎖換為獨占鎖,當對象上有其他鎖存在時,無法對其加更新鎖。
2. 從程序員的角度看:分為樂觀鎖和悲觀鎖。
樂觀鎖:完全依靠資料庫來管理鎖的工作。
悲觀鎖:程序員自己管理數據或對象上的鎖處理。
MS SQL Server 使用鎖在多個同時在資料庫內執行修改的用戶間實現悲觀並發控制
三 鎖的粒度
鎖粒度是被封鎖目標的大小,封鎖粒度小則並發性高,但開銷大,封鎖粒度大則並發性低但開銷小
SQL Server支持的鎖粒度可以分為為行、頁、鍵、鍵范圍、索引、表或資料庫獲取鎖
資源描述
RID 行標識符。用於單獨鎖定表中的一行。
鍵 索引中的行鎖。用於保護可串列事務中的鍵范圍。
頁 8 千位元組 (KB) 的數據頁或索引頁。
擴展盤區 相鄰的八個數據頁或索引頁構成的一組。
表 包括所有數據和索引在內的整個表。
DB 資料庫。
四 鎖定時間的長短
鎖保持的時間長度為保護所請求級別上的資源所需的時間長度。
用於保護讀取操作的共享鎖的保持時間取決於事務隔離級別。採用 READ COMMITTED 的默認事務隔離級別時,只在讀取頁的期間內控制共享鎖。在掃描中,直到在掃描內的下一頁上獲取鎖時才釋放鎖。如果指定 HOLDLOCK 提示或者將事務隔離級別設置為 REPEATABLE READ 或 SERIALIZABLE,則直到事務結束才釋放鎖。
根據為游標設置的並發選項,游標可以獲取共享模式的滾動鎖以保護提取。當需要滾動鎖時,直到下一次提取或關閉游標(以先發生者為准)時才釋放滾動鎖。但是,如果指定 HOLDLOCK,則直到事務結束才釋放滾動鎖。
用於保護更新的排它鎖將直到事務結束才釋放。
如果一個連接試圖獲取一個鎖,而該鎖與另一個連接所控制的鎖沖突,則試圖獲取鎖的連接將一直阻塞到:
將沖突鎖釋放而且連接獲取了所請求的鎖。
連接的超時間隔已到期。默認情況下沒有超時間隔,但是一些應用程序設置超時間隔以防止無限期等待
五 SQL Server 中鎖的自定義
1 處理死鎖和設置死鎖優先順序
死鎖就是多個用戶申請不同封鎖,由於申請者均擁有一部分封鎖權而又等待其他用戶擁有的部分封鎖而引起的無休止的等待可以使用SET DEADLOCK_PRIORITY控制在發生死鎖情況時會話的反應方式。如果兩個進程都鎖定數據,並且直到其它進程釋放自己的鎖時,每個進程才能釋放自己的鎖,即發生死鎖情況。
2 處理超時和設置鎖超時持續時間。
@@LOCK_TIMEOUT 返回當前會話的當前鎖超時設置,單位為毫秒
SET LOCK_TIMEOUT 設置允許應用程序設置語句等待阻塞資源的最長時間。當語句等待的時間大於 LOCK_TIMEOUT 設置時,系統將自動取消阻塞的語句,並給應用程序返回"已超過了鎖請求超時時段"的 1222 號錯誤信息
示例
下例將鎖超時期限設置為 1,800 毫秒。
SET LOCK_TIMEOUT 1800
3) 設置事務隔離級別。
4 ) 對 SELECT、INSERT、UPDATE 和 DELETE 語句使用表級鎖定提示。
5) 配置索引的鎖定粒度
可以使用 sp_indexoption 系統存儲過程來設置用於索引的鎖定粒度
六 查看鎖的信息 1 執行 EXEC SP_LOCK 報告有關鎖的信息
2 查詢分析器中按Ctrl+2可以看到鎖的信息
七 使用注意事項
如何避免死鎖
1 使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務;
2 設置死鎖超時參數為合理范圍,如:3分鍾-10分種;超過時間,自動放棄本次操作,避免進程懸掛;
3 優化程序,檢查並避免死鎖現象出現;
4 .對所有的腳本和SP都要仔細測試,在正是版本之前。
5 所有的SP都要有錯誤處理(通過@error)
6 一般不要修改SQL Server事務的默認級別。不推薦強行加鎖
八 幾個有關鎖的問題
1 如何鎖一個表的某一行
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDSELECT * FROM table ROWLOCK WHERE id =
1
2 鎖定資料庫的一個表
SELECT * FROM table WITH (HOLDLOCK)
加鎖語句:
sybase:update 表 set col1=col1 where 1=0 ;MS SQL:select col1 from 表 (tablockx) where 1=0 ;oracle:LOCK TABLE 表 IN EXCLUSIVE MODE ;
加鎖後其它人不可操作,直到加鎖用戶解鎖,用commit或rollback解鎖
幾個例子幫助大家加深印象,設table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3
1)排它鎖
新建兩個連接,在第一個連接中執行以下語句
begin tranupdate table1set A='aa'where B='b2'waitfor delay '00:00:30'
--等待30秒commit tran
在第二個連接中執行以下語句
begin transelect * from table1where B='b2'commit tran
若同時執行上述兩個語句,則select查詢必須等待update執行完畢才能執行即要等待30秒
2)共享鎖
在第一個連接中執行以下語句
begin transelect * from table1 holdlock -holdlock人為加鎖where B='b2'waitfor delay '00:00:30'
--等待30秒commit tran
在第二個連接中執行以下語句
begin transelect A,C from table1where B='b2'update table1set A='aa'where B='b2'commit tran
若同時執行上述兩個語句,則第二個連接中的select查詢可以執行,而update必須等待第一個事務釋放共享鎖轉為排它鎖後才能執行 即要等待30秒
3)死鎖
增設table2(D,E)
D E
d1 e1
d2 e2
在第一個連接中執行以下語句
begin tranupdate table1set A='aa'where B='b2'waitfor delay '00:00:30'update table2set D='d5'where E='e1'commit tran
在第二個連接中執行以下語句
begin tranupdate table2set D='d5'where E='e1'waitfor delay '00:00:10'update table1set A='aa'where B='b2'commit tran
同時執行,系統會檢測出死鎖,並中止進程
補充一點:
SQL Server 2000支持的表級鎖定提示
HOLDLOCK 持有共享鎖,直到整個事務完成,應該在被鎖對象不需要時立即釋放,等於SERIALIZABLE事務隔離級別
NOLOCK 語句執行時不發出共享鎖,允許臟讀 ,等於 READ UNCOMMITTED事務隔離級別
PAGLOCK 在使用一個表鎖的地方用多個頁鎖
READPAST 讓SQL Server跳過任何鎖定行,執行事務,適用於READ UNCOMMITTED事務隔離級別只跳過RID鎖,不跳過頁,區域和表鎖
ROWLOCK 強制使用行鎖
TABLOCKX 強制使用獨占表級鎖,這個鎖在事務期間阻止任何其他事務使用這個表
UPLOCK 強制在讀表時使用更新而不用共享鎖
應用程序鎖:
應用程序鎖就是客戶端代碼生成的鎖,而不是SQL Server本身生成的鎖
處理應用程序鎖的兩個過程
sp_getapplock 鎖定應用程序資源
sp_releaseapplock 為應用程序資源解鎖
注意: 鎖定資料庫的一個表的區別
SELECT * FROM table WITH (HOLDLOCK) 其他事務可以讀取表,但不能更新刪除
SELECT * FROM table WITH (TABLOCKX) 其他事務不能讀取表,更新和刪除