一、概念
創(chuàng)新互聯(lián)公司,專注為中小企業(yè)提供官網(wǎng)建設(shè)、營銷型網(wǎng)站制作、響應(yīng)式網(wǎng)站開發(fā)、展示型成都做網(wǎng)站、網(wǎng)站設(shè)計等服務(wù),幫助中小企業(yè)通過網(wǎng)站體現(xiàn)價值、有效益。幫助企業(yè)快速建站、解決網(wǎng)站建設(shè)與網(wǎng)站營銷推廣問題。
SQL?(Structured?Query?Language)?數(shù)據(jù)庫,指關(guān)系型數(shù)據(jù)庫。主要代表:SQL?Server,Oracle,MySQL(開源),PostgreSQL(開源)。
NoSQL(Not?Only?SQL)泛指非關(guān)系型數(shù)據(jù)庫。主要代表:MongoDB,Redis,CouchDB。
二、區(qū)別
1、存儲方式
SQL數(shù)據(jù)存在特定結(jié)構(gòu)的表中;而NoSQL則更加靈活和可擴(kuò)展,存儲方式可以省是JSON文檔、哈希表或者其他方式。SQL通常以數(shù)據(jù)庫表形式存儲數(shù)據(jù)。舉個栗子,存?zhèn)€學(xué)生借書數(shù)據(jù):
而NoSQL存儲方式比較靈活,比如使用類JSON文件存儲上表中熊大的借閱數(shù)據(jù):
2、表/數(shù)據(jù)集合的數(shù)據(jù)的關(guān)系
在SQL中,必須定義好表和字段結(jié)構(gòu)后才能添加數(shù)據(jù),例如定義表的主鍵(primary?key),索引(index),觸發(fā)器(trigger),存儲過程(stored?procedure)等。表結(jié)構(gòu)可以在被定義之后更新,但是如果有比較大的結(jié)構(gòu)變更的話就會變得比較復(fù)雜。在NoSQL中,數(shù)據(jù)可以在任何時候任何地方添加,不需要先定義表。例如下面這段代碼會自動創(chuàng)建一個新的"借閱表"數(shù)據(jù)集合:
NoSQL也可以在數(shù)據(jù)集中建立索引。以MongoDB為例,會自動在數(shù)據(jù)集合創(chuàng)建后創(chuàng)建唯一值_id字段,這樣的話就可以在數(shù)據(jù)集創(chuàng)建后增加索引。
從這點來看,NoSQL可能更加適合初始化數(shù)據(jù)還不明確或者未定的項目中。
3、外部數(shù)據(jù)存儲
SQL中如何需要增加外部關(guān)聯(lián)數(shù)據(jù)的話,規(guī)范化做法是在原表中增加一個外鍵,關(guān)聯(lián)外部數(shù)據(jù)表。例如需要在借閱表中增加審核人信息,先建立一個審核人表:
再在原來的借閱人表中增加審核人外鍵:
這樣如果我們需要更新審核人個人信息的時候只需要更新審核人表而不需要對借閱人表做更新。而在NoSQL中除了這種規(guī)范化的外部數(shù)據(jù)表做法以外,我們還能用如下的非規(guī)范化方式把外部數(shù)據(jù)直接放到原數(shù)據(jù)集中,以提高查詢效率。缺點也比較明顯,更新審核人數(shù)據(jù)的時候?qū)容^麻煩。
4、SQL中的JOIN查詢
SQL中可以使用JOIN表鏈接方式將多個關(guān)系數(shù)據(jù)表中的數(shù)據(jù)用一條簡單的查詢語句查詢出來。NoSQL暫未提供類似JOIN的查詢方式對多個數(shù)據(jù)集中的數(shù)據(jù)做查詢。所以大部分NoSQL使用非規(guī)范化的數(shù)據(jù)存儲方式存儲數(shù)據(jù)。
5、數(shù)據(jù)耦合性
SQL中不允許刪除已經(jīng)被使用的外部數(shù)據(jù),例如審核人表中的"熊三"已經(jīng)被分配給了借閱人熊大,那么在審核人表中將不允許刪除熊三這條數(shù)據(jù),以保證數(shù)據(jù)完整性。而NoSQL中則沒有這種強(qiáng)耦合的概念,可以隨時刪除任何數(shù)據(jù)。
6、事務(wù)
SQL中如果多張表數(shù)據(jù)需要同批次被更新,即如果其中一張表更新失敗的話其他表也不能更新成功。這種場景可以通過事務(wù)來控制,可以在所有命令完成后再統(tǒng)一提交事務(wù)。而NoSQL中沒有事務(wù)這個概念,每一個數(shù)據(jù)集的操作都是原子級的。
7、增刪改查語法
8、查詢性能
在相同水平的系統(tǒng)設(shè)計的前提下,因為NoSQL中省略了JOIN查詢的消耗,故理論上性能上是優(yōu)于SQL的。
方法1:
第一步:
backup
log
database_name
with
no_log
或者
backup
log
database_name
with
truncate_only
--no_log和truncate_only是在這里是同義的,隨便執(zhí)行哪一句都可以
第二步:
1.收縮特定數(shù)據(jù)庫的所有數(shù)據(jù)和日志文件,執(zhí)行
dbcc
shrinkdatabase
(database_name,[,target_percent])--database_name是要收縮的數(shù)據(jù)庫名稱;target_percent是數(shù)據(jù)庫收縮后的數(shù)據(jù)庫文件中所要的剩余可用空間百分比
2.收縮一次一個特定數(shù)據(jù)庫中的數(shù)據(jù)或日志文件,執(zhí)行
dbcc
shrinkfile(file_id,[,target_size])
--file_id是要收縮的文件的標(biāo)識
(id)
號,若要獲得文件
id,請使用
file_id
函數(shù)或在當(dāng)前數(shù)據(jù)庫中搜索
sysfiles;target_size是用兆字節(jié)表示的所要的文件大?。ㄓ谜麛?shù)表示)。如果沒有指定,dbcc
shrinkfile
將文件大小減少到默認(rèn)文件大小
兩個dbcc都可以帶上參數(shù)notruncate或truncateonly,具體意思看幫助。
方法2(這個方法在sqlserver2000的環(huán)境下做一般能成功,在sqlserver7及以下版本就不一定了):
第一步:
先備份整個數(shù)據(jù)庫以備不測
第二步:
備份結(jié)束后,在query
analyzer中執(zhí)行如下的語句:
exec
sp_detach_db
yourdbname,true
--卸除這個db在mssql中的注冊信息
第三步:
到日志的物理文件所在的目錄中去刪除該日志文件或者將該日志文件移出該目錄
第四步:
在query
analyzer中執(zhí)行如下的語句:
exec
sp_attach_single_file_db
yourdbname,'d:\mssql7\data\yourdbname_data.mdf'
--以單文件的方式注冊該db,如果成功則mssql將自動為這個db生成一個500k的日志文件。
以上方法在清除log日志中均有效。
但,能否讓sql
server
不產(chǎn)生log日志呢?以上方法好像均無效。
我這兒正好有個case:
我客戶的sql
server每天都會產(chǎn)生4,500m的log日志,每天都清除一下,非常不便。有沒有辦法實現(xiàn)不產(chǎn)生log日志呢?
我分析了一下客戶產(chǎn)生log日志的原因,并且做了相應(yīng)測試。
客戶是每天將數(shù)據(jù)庫清空,從總系統(tǒng)中將數(shù)據(jù)導(dǎo)入到sql
server里。我感決sqlserver在插入時產(chǎn)生log不大,在delete整個庫時產(chǎn)生log極大。
比如:
select
*
into
test_2
from
b_bgxx
共45000條記錄,產(chǎn)生十幾m
log,如果
delete
from
test_2
產(chǎn)生80多m
log
,這明顯存在問題。
雖然可以換成:
truncate
table
test_2
但我還是希望能找到不產(chǎn)生log的方法。就如oracle不產(chǎn)生歸檔一樣。
--?修改存儲過程PZ_JF_TimePeriodCardTimes
ALTER?PROCEDURE?[dbo].[PZ_JF_TimePeriodCardTimes]
@StaffID?int,???????????--?員工ID
@BeginDate?datetime,????--?開始日期
@EndDate?datetime,??????--?結(jié)束日期
@TimeBegin?nvarchar(5),?--?時間段開始
@TimeEnd?nvarchar(5),???--?時間段結(jié)束
@CardTimes?int,??????????--?時間區(qū)間內(nèi)的刷卡次數(shù)?
@UserNo?nvarchar(100)?
AS
BEGIN????
--?如果StaffID為0則將之設(shè)為null,StaffID應(yīng)該是輸入?yún)?shù)
if?@StaffID=0?begin?set?@StaffID=null?end?
--?自定義變量@UserID,初始值為0
Declare?@UserID?int=0?
--?將變量@UserID設(shè)為滿足條件且EnableYN='Y'的那個userid的值
select?@UserID=userid?from?Ghrs_User?where?
UserNo=@UserNo
and?EnableYN='Y'
--?自定義變量@TempAdd?,初始值為0
Declare?@TempAdd?int=0
--?如果結(jié)束時間小于開始時間設(shè)置?@TempAdd?的值為1
if?@TimeEnd@TimeBegin?begin?set?@TempAdd=1?end?
select?StaffNo,StaffName,convert(nvarchar(10),b.CDate?,121)from?Ghra_Staff,Ghrb_Calendar?b
where?b.CDate?between?@BeginDate?and??@EndDate?--條件1:Ghrb_Calendar中的CDate的值在開始時間和結(jié)束時間之內(nèi)
and?Ghra_Staff.StaffID=ISNULL(?@StaffID,Ghra_Staff.staffID)?--條件2:如果@StaffID是null此過濾條件無效,@StaffID不是null,
and?dbo.FUserStaffPriv(@UserID,staffid)='Y'??--?條件3:FUserStaffPriv(@UserID,staffid)的結(jié)果是'Y'????
and?(select?COUNT(1)from?Ghrb_CardRecord
where?StaffID?=?Ghra_Staff.StaffID
and?EnableYN='Y'
and?CardTime?between??convert(nvarchar(10),b.CDate?,121)+'?'+?@TimeBegin?
and?convert(nvarchar(10),Dateadd(Day,@TempAdd,b.CDate)?,121)+'?'+?@TimeEnd????
)=?@CardTimes??--條件4:StaffID一致、EnableYN為'Y',CardTime在開始時間和結(jié)束時間之間
END
1、 創(chuàng)建語法
create?proc?|?procedure?pro_name
[{@參數(shù)數(shù)據(jù)類型}?[=默認(rèn)值]?[output],
{@參數(shù)數(shù)據(jù)類型}?[=默認(rèn)值]?[output],
....
]
as
SQL_statements
2、 創(chuàng)建不帶參數(shù)存儲過程
--創(chuàng)建存儲過程
if?(exists?(select?*?from?sys.objects?where?name?=?'proc_get_student'))
drop?proc?proc_get_student
go
create?proc?proc_get_student
as
select?*?from?student;
--調(diào)用、執(zhí)行存儲過程
exec?proc_get_student;
3、 修改存儲過程
--修改存儲過程
alter?proc?proc_get_student
as
select?*?from?student;
4、 帶參存儲過程
--帶參存儲過程
if?(object_id('proc_find_stu',?'P')?is?not?null)
drop?proc?proc_find_stu
go
create?proc?proc_find_stu(@startId?int,?@endId?int)
as
select?*?from?student?where?id?between?@startId?and?@endId
go
exec?proc_find_stu?2,?4;
5、 帶通配符參數(shù)存儲過程
--帶通配符參數(shù)存儲過程
if?(object_id('proc_findStudentByName',?'P')?is?not?null)
drop?proc?proc_findStudentByName
go
create?proc?proc_findStudentByName(@name?varchar(20)?=?'%j%',?@nextName?varchar(20)?=?'%')
as
select?*?from?student?where?name?like?@name?and?name?like?@nextName;
go
exec?proc_findStudentByName;exec?proc_findStudentByName?'%o%',?'t%';
擴(kuò)展資料:
SQL存儲過程優(yōu)點:
1、重復(fù)使用。存儲過程可以重復(fù)使用,從而可以減少數(shù)據(jù)庫開發(fā)人員的工作量。
2、減少網(wǎng)絡(luò)流量。存儲過程位于服務(wù)器上,調(diào)用的時候只需要傳遞存儲過程的名稱以及參數(shù)就可以了,因此降低了網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量。
3、安全性。參數(shù)化的存儲過程可以防止SQL注入式攻擊,而且可以將Grant、Deny以及Revoke權(quán)限應(yīng)用于存儲過程。
參考資料來源:百度百科—存儲過程
sql
server存儲過程
輸出結(jié)果集
還是比較簡單的.
直接在
存儲過程里面執(zhí)行
sql
語句就可以了。
例如:
--
測試返回結(jié)果集的存儲過程
create
procedure
testproc
as
begin
select
'hello
1'
as
a,
'world
1'
as
b
union
all
select
'hello
2'
as
a,
'world
2'
as
b;
end
go
剩下的,
就是你用
別的開發(fā)語言,
例如
c#
什么的
,
調(diào)用這個存儲過程,
獲取結(jié)果集了。