SQL Server 數據庫(高級)完結篇

1.0 數據庫設計

1.1 什麼是數據庫設計?

        規劃和結構化數據庫中的數據對象及這些數據之間關係的過程

1.2 設計數據庫的重要性

不經過設計或者糟糕的數據庫設計最終很可能導致:
    ● 數據庫運行效率低下
    ● 更新、刪除和查詢數據時出現諸多問題

良好的數據庫設計最終可表現爲:
    ● 執行效率高
    ● 使應用程序更便於開發
    ● 容易進一步擴展

1.3 實體—關係

實體:凡是可以互相區別而被人們認識的事、物、概念等統統抽象爲實體
屬性:實體一般具有若干特徵,稱之爲實體的屬性;屬性對應表中的列
關係:實體與實體之間的關係抽象爲聯繫

1.4 數據庫設計步驟:

(1)需求分析階段;(2)概要設計階段;(3)詳細設計階段

1.5 繪製E-R圖

矩形表示實體集橢圓表示屬性菱形表示關係
直線用來連接實體集與屬性,同時也用來連接實體集與關係
直線上的箭頭用來表示實體集之間的映射基數

1.6 映射基數

一對一 、一對多 、多對一 、多對多

1.7 將E-R圖轉換爲表

(1) 將各實體轉化爲對應的表,將各屬性轉換爲各表中對應的列
(2) 標識每張表中的主鍵
(3) 將實體之間的關係轉換爲表與表之間的主外鍵關係

1.8 設計中的問題

1、 數據冗餘大
2、 插入異常
3、 刪除異常
4、 更新異常

1.9 一個好的數據庫設計應滿足如下條件:

◾ 儘可能少的數據冗餘
◾ 沒有插入異常
◾ 沒有刪除異常
◾ 沒有更新異常

1.10 規範設計(數據庫設計三大範式)

第一範式(1NF):關係中的每個屬性必須是不可再分的簡單項,不能是屬性組合,即屬性的取值必須是不可拆分的原子值
第二範式(2NF):◾ 表必須符合第一範式 ◾ 表中的每列必須依賴主鍵
第三範式(3NF):確保每列都和主鍵列直接相關,而不是間接相關
        定義:如果一個關係滿足2NF,並且除了主鍵外的其他列既不部份依賴也不傳遞依賴於主鍵列,則滿足第三範式

2.0 Transact-SQL編程

2.1 變量:局部變量 和 全局變量

局部變量(在方法中聲明的變量)

--聲明局部變量的語法:	declare @變量名 數據類型
--局部變量的賦值:	select @變量名 = 值 (直接賦值或查詢數據賦值)
--例:
	select @變量名 =111’  或 ( set @變量名=111)
	select @變量名 = 字段名 from 表明 [where 條件]

全局變量(聲明爲static的變量)
        全局變量SQL Server系統內部使用的變量,其作用範圍並不侷限於某一程序而是任何程序均可隨時調用
        全局變量不是有用戶的程序定義它們是在服務器級定義的,只能使用預先說明及定義的全局變量
        引用全局變量是必須以@@開頭,局部變量的名稱不能與全局變量的名稱相同,否則會在應用中出錯

全局變量 含 義
@@connections 返回SQL Server自上次啓動以來嘗試的連接次數,無論鏈接是成功還是失敗
@@cursor_rows 返回連接上打開的上一個遊標中的當前限定行的數目
@@error 返回執行上的一個Transact-SQL語句
@@identity 返回最後插入的標識值的系統函數
@@language 返回當前所用語言的名稱
@@max_connections 返回SQL Server實例允許同時進行的最大用戶連接數
@@procid 返回Transact-SQL當前模塊的對象標識符(ID)。Transact-SQL模塊可以是存儲過程、用戶定義函數或觸發器
@@rowcount 返回受上一句影響的行數
@@servername 返回運行在SQL Server的本地服務器的名稱
@@servicename 返回SQL Server正在其下運行的註冊表項的名稱。若當前實例爲默認實例,則@@servicename
@@version 返回當前的SQL Server的安裝版本、處理器體系結構、生成日期和操作系統
2.2 輸出語句

        T-SQL支持輸出語句,用於輸出處理的數據結果
                常用輸出語句有兩種: print變量或表達式 || select 變量或表達式

2.3 邏輯控制語句

        if-else語句

--語法結構:
if( 條件表達式 )
	begin
		命令行或程序塊
	end
else
	begin
	 	命令行或程序塊
	end

        while-continue-break語句

--語法結構:
while(條件表達式)
	begin
		命令行或程序塊
		[break]	→→ 跳出循環
		[continue] →→ 可以讓程序跳過continue命令之後的語句
		命令行或程序塊
	end

        case語句

--語法結構:
case
	begin
		when 條件表達式 then 運算式
		when 條件表達式 then 運算式
		[else 運算式]
	end

--批處理( go )
--		批處理可以提高語句的執行效率		go關鍵字標誌着批處理的結束

3.0 SQL高級查詢

3.1 子查詢簡介

        子查詢是一個嵌套在select、insert、update、delete語句的其他查詢中的查詢。任何允許使用表達式的地方都可以使用子查詢。子查詢也稱爲內部查詢或內部選擇,而包含子部查詢的語句也稱爲外部查詢或外部選擇

子查詢的特點和優勢:
(1)使用靈活
        ● 可以成爲SQL語句的多個部分
        ● 子查詢作爲查詢條件使用
        ● 子查詢作爲臨時表使用
        ● 子查詢作爲列使用
(2)降低SQL語句的複雜度,提高SQL語句的可讀性

3.2 使用in 和 not in完成子查詢

        innot in 通常在where子句中使用,在innot in 後接的子查詢中可以有多個值出現

3.3 使用exists 和not exists完成子查詢

        existsnot exists表示存在和不存在的意思。在語句中會判斷existsnot exists後接的子句是否存在和是否不存在

3.4 使用some、any、all進行查詢

在SQL查詢中,someanyall 後必須跟子查詢
        some和any的查詢功能是一樣的,where條件能夠滿足some和any所接的子查詢中的任意一個值,就表示where條件成立

all表示的是能夠滿足all所接的子查詢中的所有值才成立
--例:
	all(1,2,3)表示大於3>all表示至少大於一個值,即大於最小值
3.5 使用compute和compute by進行彙總查詢

computecompute by子句使您得以用同一select語句即查看明細行,有查看彙總行。可以計算子組的彙總值,也可以計算整個結果集的彙總值

compute不帶可選的by子句時,select語句有兩個結果集:
        ● 每個組的第一個結果集是包含選擇列表信息的所有明細行
        ● 第二個結果集有一行,其中包含compute子句中所指定的聚合函數的合計

compute子句需要下列信息:
        ● 可選by關鍵字。它基於每一列計算指定的行聚合
        ● 行聚合函數名稱 SUMAVGMINMAX、或 COUNT
        ● 要對其執行行聚函數的列

對結果先進行分組然後進行彙總計算時使用:compute by進行分組彙總查詢

3.6 排序函數語法:

排序函數 over( [分組子句] 排序子句[desc][asc] )
排序子句:order by 排序列,排序列···
分組子句:partition by分組列,分組列···

3.7 排序函數:

row_number() 特點:沒有並列編號,不跳空編號
rank() 特點:有並列編號,有跳空編號
dense_rank() 特點:有並列編號,不跳空編號

3.8 公式表表達式

        將公用表表達式(CET)視爲臨時結果集,在selectinsertupdatedeletecreate view語句的執行範圍內進行定義

--CET基本語法結構:
	with 公用表表名 (字段列表)
	as	( 命令行或程序塊 )
	select * from 公用表表名

4.0 索引和視圖

        索引:數據表中數據和相應存儲位置的列表;能根據簡單的信息查找到數據所在的位置
        作用:提高執行查詢的速度
        分類:聚集索引 和 非聚集索引
:默認情況下主鍵就是聚集索引,一張表只能有一個聚集索引
        聚集索引:表中數據行的物理存儲順序和索引順序完全相同
        非聚集索引:不改變表中數據行的物理存儲位置,數據和索引分開存儲,通過索引指向的地址與表中數據發生關係

4.1 聚集索引和非聚集索引的區別
聚集索引 非聚集索引
每個表只允許有一個聚集索引 最多可以有249個非聚集索引
物理地重排表中的數據以符合索引約束 創建一個鍵值列表鍵值指向數據在數據頁中的位置
用於經常查找數據的列 用於從中查找單個值的列
4.2 其他類型索引

        唯一索引:如果希望索引鍵都不相同,可以創建唯一索引,聚集索引和非聚集索引都可以是唯一索引
        包含性列索引:在SQL2008系統中索引的最大數量是16個,索引列的字節總數的最高值是900,如果當多個列的字節總數大於900,且又想將這些列都包含在索引中時,可以使用包含性列索引
        視圖索引:如果希望提高視圖的查詢效率,可以將視圖的索引物理化,也就是說將結果永久的儲存在索引中,可以創建視圖索引
        XML索引:與XML數據關聯的索引形式,是XML二進制BLOB的已拆分持久表示形式
        全文索引:一種特殊類型的基於標記的功能性索引,由SQL全文引擎服務創建和維護,用於幫助在字符串中搜索複雜的詞

--創建索引:
--語法:
	create 索引類型 index IX_name
	on table_name(字段)
	[where fillfactor = x]

        unique:唯一索引
        clustered:聚集索引
        nonclustered:非聚集索引
        table_anme:數據表名,也可以是視圖名
        fillfactor:設置填充因子的大小,指定0-100之間的值,該值指示索引頁填滿的空間所佔百分比,一般爲30

4.3 指定按索引查詢:

Select * from table_name with(index = IX_name) where 條件

4.4 適合創建索引的列:

        當數據表中的某一列被頻繁用於數據搜索時,或者該列用於對數據進行排序時可以創建成索引

4.5 視圖

● 視圖名稱必須遵循標識符的規則
● 可以對其他視圖創建視圖,嵌套不得超過32層,視圖最多可包含1024個字段
● 不能將規則或default定義以視圖相關聯
● 定義視圖的查詢不能包含compute子句、compute by子句或into關鍵字
● 定義視圖的查詢不能包含 order by子句,除非在select語句的選擇列表中還有一個top子句

下列情況必須指定視圖中每列的名稱

● 視圖中的任何列都是從算術表達式、內置函數或常量派生而來的
● 視圖中有兩列或多列具有相同名稱
● 希望爲視圖中的列指定一個與其原列不同的名稱,也可以在視圖中重命名列,無論重名與否,視圖列都會繼承其源列的數據類型

創建視圖

--語法:
	create view view_name(別名)
	[with encryption] 創建加密視圖
	as
	<select 語句>
	
--查看視圖
	Select * from view_name

5.0 事務和遊標

5.1 事務

        事務是一個不可分割的邏輯單元

特點:
原子性:事務內的所有工作要麼全部完成,要麼全部沒有完成
一致性:事務內的任何操作都不能違反數據庫的任何約束或規則
隔離性:事務之間是相互隔離的
持久性:事務完成後,他對數據庫的影響是持久的

5.2 事務的模式

顯式事務、自動提交事務、隱式事務

5.3 事務處理

begin transaction 標記一個本地事務的開始
commit transaction 用於提交事務
rollback transaction 用於事務回滾

使用@@error全局變量記錄執行過程中的錯誤

--語法:
	begin transaction tran_name
	declare @tran_error int -- →定義變量用於記錄錯誤
	--< T-SQL語句 >
	set(select) @tran_error = @tran_error + @@error
	if @tran_error <> 0
		begin
			--執行事務回滾
			rollback transaction
			print***end
	else
		begin
			--提交事務
			commit transaction
			print***end
		
5.4 遊標

遊標是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制

使用遊標,可以實現以下目標
● 允許定位到結果集中的特定行
● 從結果集的當前位置檢索一行或多行數據
● 支持對結果集中當前位置的行進行修改
:遊標不建議 使用

5.5 三種遊標

T-SQL遊標、API遊標、客戶端遊標

5.6 遊標的基本操作

定義遊標、打開遊標、循環讀取遊標、關閉遊標、刪除遊標

--定義一個遊標
declare遊標名 cursor scroll for select字段列表 from 表名
--打開遊標
open 遊標名
--定義變量,用於存放遊標讀取出來的值
declare @xxx 數據類型
--讀取遊標的第一條數據,並存放在變量中
fetch first from 遊標名 into @xxx
--循環記錄遊標讀取的數據
print '讀取的數據如下:'
while(@@FETCH_STATUS =0)
	begin
		--使用print輸出讀取的數據
		print'文字說明:'+xxx
		--讀取下一條記錄
		fetch next from 遊標名 into @xxx
	end
--讀取完成後關閉遊標
close 遊標名
go
--刪除遊標
deallocate 遊標名
go

全局變量 @@FETCH_STATUS 的值有三種:
        0:表示fetch語句成功
        -1:表示fetch語句執行失敗或此行不在結果集中
        -2:表示被提取的行不存在

6.0 存儲過程

        存儲過程:是一組爲了完成特定功能的SQL語句集合

常用系統存儲過程 說明
sp_databases 列出服務器上的所有數據庫
sp_tables 返回可在當前環境中查詢的對象列表
sp_columns 返回可在當前環境中查詢的指定表或視圖的列信息
sp_helpindex 報告有關表或視圖上索引的信息
sp_helpconstraint 返回某個表的約束
sp_stored_procedures 返回當前環境中的存儲過程列表
sp_helptext 顯示用於在多行中創建對象的定義
sp_helpdb 報告有關指定數據庫或所有數據庫信息
sp_defaultdb 更改Microsoft SQL Server登錄名的默認數據庫
sp_renamedb 更改數據庫的名稱
sp_rename 在當前數據庫中更改用戶創建對象的名稱,此對象可以是表、索引、列

用法:exec 存儲過程

6.1 存儲過程的使用
--使用系統存儲過程在D盤創建一個“Back”文件夾
select * from sys.configurations where name = 'xp_cmdshell' or name = 'show advanced options'
go
use master --使用系統數據庫
go
reconfigure --刷新配置
go
exec sp_configure 'show advanced options',1 --啓用 xp_cmdshell 高級配置
go
reconfigure --刷新配置
go
exec sp_configure 'xp_cmdshell',1 --打開xp_cmdshell進行文件夾操作
go
reconfigure --刷新配置
go
exec xp_cmdshell 'md D:\Back',no_output
go

--創建數據庫放在D盤的Back文件夾下
if exists(select * from sys.databases where name = 'StuInfo')
drop database StuInfo
go
create database StuInfo
on(
	name = 'StuInfo',
	filename = 'D:\Back\StuInfo.mdf'
)
log on(
	name = 'StuInfo_log',
	filename = 'D:\Back\StuInfo.ldf'
)
exec xp_cmdshell 'dir D:\Back\'
go

6.2 用戶定義的存儲過程
if exists(select * from sysobjects where name = 'proc_xxx')
drop proc proc_xxx
go
create proc proc_xxx
@xxx 數據類型,有參
@xxx 數據類型 =,默認參數
@xxx 數據類型 output 輸出參數
as
	SQL語句
go
declare @xxx 數據類型
select @xxx =exec proc_xxx 參數值, @xxx output
print '文字說明'+參數變量
go

--自定義錯誤
if exists(select * from sys.objects where name='proc_xxx')
drop proc proc_xxx 
go
create proc proc_xxx
@xxx 數據類型
as
	if @g <0 or @g>100 
	begin
		--定義錯誤信息
		例:raiserror('及格線必須在0~100之間',16,1)
		return
	end
	select @xxx
go
exec proc_xxx 參數值
go

7.0 觸發器

        觸發器是對錶進行插入、更新或者刪除的時候會自動執行的特殊存儲過程

對錶的操作 inserted邏輯表 deleted邏輯表
增加記錄(insert) 存放增加的記錄
刪除記錄(delete) 存放被刪除的記錄
修改記錄(update) 存放更新後的記錄 存放更新前的記錄
7.1 創建insert觸發器
if exists(select * from sysobjects where name = 'trigger_xxx_insert')
drop trigger trigger_xxx_insert
go

create trigger trigger_xxx_insert
on table_Name --對應表名
for insert --觸發器類型
as
--定義變量
declare @xxx
--賦值
select @xxx = xxx from  table_Name
--判斷操作類型
if @TransType = '存入'
	update backupTABLE set 字段名+= @xxx where 字段名=@xxx
else
	update backupTABLE set 字段名-= @xxx where 字段名=@xxx
--查詢當前賬戶總金額
select @xxx = 字段名  from table_Name where 字段名=@xxx
print '文字說明'+參數
go

--測試觸發器
insert SQL語句
print '原賬戶信息'
select * from table_Name
PRINT '交易信息'
select * from table_Name
PRINT '賬戶最新信息'
select * from table_Name
go

7.2 創建delete觸發器
if exists(select * from sys.objects where name = 'trigger_xxx_delete')
drop trigger trigger_xxx_delete
go 

create trigger trigger_xxx_delete
on TRANsInfo
for delete
as
	print'備份中...'
	if exists(select * from sys.objects where name ='backupTRANsInfo')
		insert into backupTRANsInfo select * from deleted
	else
		select * into backupTRANsInfo from deleted
	print'備份成功!'
go

--測試觸發器
set nocount on
print '刪除前原始表的數據'
select * from TRANsInfo
delete from TRANsInfo
print '刪除後備份表的數據'
select * from backupTABLE
go

7.3 創建update觸發器
if exists(select * from sys.objects where name = 'trigger_StockInfo_update')
drop trigger trigger_StockInfo_update
go

create trigger trigger_StockInfo_update
on StockInfo
for update
as
	--定義變量 交易前數量      交易後的數量      交易數量
	declare @BeforAmount int ,@AfteAmount int ,@TransAmount int
	--賦值
	select @BeforAmount = StockAmount from deleted --交易前數量
	select @AfteAmount = StockAmount from inserted --交易後的數量
	select @TransAmount = @BeforAmount - @AfteAmount --交易數量
	--判斷交易金額是否正常(>0)
	if @TransAmount>0
		begin
			--如果交易數量大於庫存數量
			if @TransAmount > @BeforAmount
				begin
					print'交易數量:'+convert(varchar(10),ABS(@BeforAmount - @AfteAmount))
					--提示錯誤信息
					raiserror('商品庫存不足',16,1)
					--回滾事務
					rollback transaction
				end
		end
go

--測試觸發器
set nocount on
select * from StockInfo
update StockInfo set StockAmount -= 100 where GoodsID = 1
select * from StockInfo
go

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章