- 數(shù)據庫三范式是什么?
第一范式:表中每個字段都不能再分。
第二范式:滿足第一范式并且表中的非主鍵字段都依賴于主鍵字段揪阶。
第三范式:滿足第二范式并且表中的非主鍵字段必須不傳遞依賴于主鍵字段。 - 什么是數(shù)據庫事務盏混?
事務具有四大特性:一致性置森、原子性续搀、隔離性帐我、持久性坎炼。
數(shù)據庫事務是指:幾個SQL語句,要么全部執(zhí)行成功拦键,要么全部執(zhí)行失敗谣光。比如銀行轉賬就是事務的典型場景。
數(shù)據庫事務的三個常用命令:Begin Transaction芬为、Commit Transaction萄金、RollBack Transaction。 - 什么是視圖碳柱?
視圖實際上是在數(shù)據庫中通過Select查詢語句從多張表中提取的多個表字段所組成的虛擬表捡絮。
l 視圖并不占據物理空間,所以通過視圖查詢出的記錄并非保存在視圖中莲镣,而是保存在原表中。
l 通過視圖可以對指定用戶隱藏相應的表字段涎拉,起到保護數(shù)據的作用瑞侮。
l 在滿足一定條件時,可以通過視圖對原表中的記錄進行增刪改操作鼓拧。
l 創(chuàng)建視圖時半火,只能使用單條select查詢語句。 - 什么是索引季俩?
索引是對數(shù)據庫表中一列或多列的值進行排序的一種結構钮糖,使用索引可快速訪問數(shù)據庫表中的特定信息。
l 索引分為:聚集索引、非聚集索引店归、唯一索引等阎抒。
l 一張表可以有多個唯一索引和非聚集索引,但最多只能有一個聚集索引消痛。
l 索引可以包含多列且叁。
l 合理的創(chuàng)建索引能夠提升查詢語句的執(zhí)行效率,但降低了新增秩伞、刪除操作的速度逞带,同時也會消耗一定的數(shù)據庫物理空間。 - 什么是存儲過程纱新?
存儲過程是一個預編譯的SQL語句展氓,優(yōu)點是允許模塊化的設計,就是說只需創(chuàng)建一次脸爱,以后在該程序中就可以調用多次带饱。如果某次操作需要執(zhí)行多次SQL,使用存儲過程比單純SQL語句執(zhí)行要快阅羹。 - 什么是觸發(fā)器勺疼?
觸發(fā)器是一中特殊的存儲過程,主要是通過事件來觸發(fā)而被執(zhí)行的捏鱼。它可以強化約束执庐,來維護數(shù)據的完整性和一致性,可以跟蹤數(shù)據庫內的操作從而不允許未經許可的更新和變化导梆」焯剩可以聯(lián)級運算。如看尼,某表上的觸發(fā)器上包含對另一個表的數(shù)據操作递鹉,而該操作又會導致該表觸發(fā)器被觸發(fā)。 - 寫出一條Sql語句:取出表A中第31到第40記錄 (MS-SQLServer)
解1:select top 10 * from A where id not in (select top 30 id from A)
解2:select top 10 * from A where id > (select max(id) from (select top 30 id from A )as A)
解3:select * from (select *, Row_Number() OVER (ORDER BY id asc) rowid FROM A) as A where rowid between 31 and 40 - 寫出一條Sql語句:取出表A中第31到第40記錄 (Mysql)
select * from A limit 30, 10 - 寫出一條Sql語句:取出表A中第31到第40記錄 (Oracle)
select *
from (select A.*,
row_number() over (order by id asc) rank
FROM A)
where rank >=31 AND rank<=40; - 在關系型數(shù)據庫中如何描述多對多的關系?
在關系型數(shù)據庫中描述多對多的關系,需要建立第三張數(shù)據表藏斩。比如學生選課,需要在學生信息表和課程信息表的基礎上,再建立選課信息表,該表中存放學生Id和課程Id躏结。 - 什么是數(shù)據庫約束,常見的約束有哪幾種?
數(shù)據庫約束用于保證數(shù)據庫表數(shù)據的完整性(正確性和一致性)≌颍可以通過定義約束\索引\觸發(fā)器來保證數(shù)據的完整性媳拴。
總體來講,約束可以分為:
主鍵約束:primary key;
外鍵約束:foreign key兆览;
唯一約束:unique屈溉;
檢查約束:check;
空值約束:not null抬探;
默認值約束:default子巾; - 列舉幾種常用的聚合函數(shù)?
Sum:求和\ Avg:求平均數(shù)\ Max:求最大值\ Min:求最小值\ Count:求記錄數(shù) - 什么是內聯(lián)接、左外聯(lián)接、右外聯(lián)接线梗?
l 內聯(lián)接(Inner Join):匹配2張表中相關聯(lián)的記錄椰于。
l 左外聯(lián)接(Left Outer Join):除了匹配2張表中相關聯(lián)的記錄外,還會匹配左表中剩余的記錄缠导,右表中未匹配到的字段用NULL表示廉羔。
l 右外聯(lián)接(Right Outer Join):除了匹配2張表中相關聯(lián)的記錄外,還會匹配右表中剩余的記錄僻造,左表中未匹配到的字段用NULL表示憋他。
在判定左表和右表時,要根據表名出現(xiàn)在Outer Join的左右位置關系髓削。 - 如何在刪除主表記錄時竹挡,一并刪除從表相關聯(lián)的記錄?
如果兩張表存在主外鍵關系立膛,那么在刪除主鍵表的記錄時揪罕,如果從表有相關聯(lián)的記錄,那么將導致刪除失敗宝泵。
在定義外鍵約束時好啰,可以同時指定3種刪除策略:一是將從表記錄一并刪除(級聯(lián)刪除);二是將從表記錄外鍵字段設置為NULL儿奶;三是將從表記錄外鍵字段設置為默認值框往。
級聯(lián)刪除示例:
alter table 從表名
add constraint 外鍵名
foreign key(字段名) references 主表名(字段名)
on delete cascade - 什么是游標?
游標實際上是一種能從包括多條數(shù)據記錄的結果集中每次提取一條記錄進行處理的機制闯捎。
游標的使用步驟: - 定義游標:declare cursor 游標名稱 for select查詢語句 [for {readonly|update}]
- 打開游標:open cursor
- 從游標中操作數(shù)據:fetch... ... current of cursor
- 關閉游標:close cursor
常用SQL代碼整理(MS-SQLServer)
創(chuàng)建數(shù)據庫
/創(chuàng)建數(shù)據庫libraryDB/
CREATE DATABASE libraryDB
ON
(
/數(shù)據庫文件的詳細描述/
NAME = 'libraryDB_mdf', --主數(shù)據庫文件的邏輯名
FILENAME = 'E:\library\libraryDB_mdf.mdf', --主數(shù)據文件的物理名
SIZE = 3MB, --初始大小
FILEGROWTH = 20% --增長率
)
LOG ON
(
/日志文件的詳細描述/
NAME = 'libraryDB_ldf', --日志文件的邏輯名
FILENAME = 'E:\library\libraryDB_ldf.ldf', --日志文件的物理名
SIZE = 1MB, --初始大小
MAXSIZE = 15MB, --最大值
FILEGROWTH = 10% --增長率
)
Go數(shù)據表(創(chuàng)建|修改|刪除)
--判斷BookType表是否存在椰弊,存在則刪除
if exists (select 1 from sysobjects where [name]='BookType')
begin
drop table BookType
end
--創(chuàng)建圖書類型表:BookType
create table BookType
(
TypeId int not null identity(1,1) primary key, --圖書類型編號(主鍵浪秘、標識列氓拼、從1開始宁舰、每次增加1)
TypeName varchar(50) not null, --圖書類型名稱
Remark varchar(100) --備注信息
)
--修改BookType表吓坚,增加備注字段
alter table BookType
alter column Remark varchar(100)
--刪除表BookType
drop table BookType創(chuàng)建主鍵
--為表添加主鍵
alter table productinfo
add constraint PK_ProductInfo_ProductId primary key(ProductId)
--刪除主鍵只需要將add替換為drop創(chuàng)建外鍵
--為表添加外鍵
alter table productpromotion
add constraint FK_Promotion_Product foreign key (ProductId) references ProductInfo(ProductId)
--刪除外鍵只需要將add替換為drop檢查約束
--創(chuàng)建檢查約束(商品編號的長度大于2)
alter table productinfo
add constraint CK_Product_Number check(len(ProductNumber)>2)--刪除外鍵只需要將add替換為drop
--創(chuàng)建檢查約束(性別為男或者女)
--check(Gender in ('男', '女'))惟一約束
--創(chuàng)建唯一約束(商品編號唯一)
alter table productinfo
add constraint UQ_Product_Number unique (ProductNumber)T-SQL編程(定義變量、為變量賦值)
--T-SQL中定義變量
declare @sum int;
declare @i int;
--set賦值(一次只能為一個變量賦值)
set @sum = 0;
--select賦值(一次可以為多個變量賦值)
select @sum=0,@i=1;T-SQL編程(if-else循環(huán))
--if實例
declare @i int;
set @i=7;
if(@i%2 = 0)
print '偶數(shù)'
else
print '奇數(shù)'
goT-SQL編程(while)
--請輸出1-10之間的數(shù)字
declare @i int;
set @i = 1;
while (@i<=10)
begin
print @i;
set @i = @i + 1;
endT-SQL編程(case)
--case的第一種語法格式(使用case將0顯示為:空閑 1顯示為:使用中)
select intComputerId,
'State'=case
when intInUse=0 then '空閑'
when intInUse=1 then '使用中'
end,
chvComputerName,chvDescription
from tblcomputer;
--case的第二種語法格式
select intComputerId,
'State'=case intInUse
when 0 then '空閑'
when 1 then '使用中'
end,
chvComputerName,chvDescription
from tblcomputer視圖
--創(chuàng)建視圖的語法示例
create view view_RecordDetail
as
select cp.chvComputerName, ci.chvUserName, ri.dtmStart, ri.dtmEnd, ri.mnyFee
from TblRecordInfo as ri--as為表取別名
inner join TblCardInfo as ci on ri.intCardId=ci.intCardId--內連接用inner join冗茸,同時應該為兩張表指定連接字段
inner join TblComputer as cp on ri.intComputerId=cp.intComputerId
--使用視圖(和表很相似)
Select * from view_RecodDetail存儲過程(無參數(shù))
--創(chuàng)建不帶參數(shù)的存儲過程
create procedure pro_ComputerUseState
as
begin
select * from tblcomputer;
end
--調用不帶參數(shù)的存儲過程
exec pro_ComputerUseState;存儲過程(含輸入參數(shù))
--如何創(chuàng)建有輸入參數(shù)的存儲過程
create procedure pro_getComputerState
@state int=0--參數(shù)默認為輸入參數(shù)
as
begin
select intComputerId,
'intInUse'=case intInuse
when 0 then '未使用'
when 1 then '以使用'
end,
chvComputerName,
chvDescription
from tblcomputer
where intInuse=@state
end
go
--調用帶有輸入參數(shù)的存儲過程
declare @state int;
set @state = 1;
exec pro_getComputerState @state;存儲過程(含輸入參數(shù)灸眼、輸出參數(shù))
--創(chuàng)建帶有輸入參數(shù)和輸出參數(shù)的存儲過程蝠猬,多個參數(shù)之間用逗號,隔開牲迫,最后一個參數(shù)后無需逗號
create proc pro_getComputerStateById
@intComputerId int,
@state int output
as
begin
select @state = intInUse
from tblcomputer
where intcomputerid=@intComputerId
end
--調用帶輸出參數(shù)的存儲過程耐朴,調用時一定要在輸出參數(shù)后加關鍵字output
declare @state int, @computerId int;
set @computerId = 7;
exec pro_getComputerStateById @computerId,@state output
select @state;觸發(fā)器
--判斷觸發(fā)器是否存在,存在則刪除觸發(fā)器
if exists (select * from sys.sysobjects where name = 'tr_insertRecord')
drop trigger tr_insertRecord
go
--如何定義|創(chuàng)建一個觸發(fā)器
create trigger tr_insertRecord
on TblRecordInfo
for insert--for等價于after,表示當新增完記錄之后才會執(zhí)行觸發(fā)器
as
begin
declare @cardid int, @startTime datetime;
select @cardid = intcardid, @startTime = dtmStart from inserted;
select '卡號:'+convert(nvarchar(5), @cardid);
select '上機開始時間:'+convert(nvarchar(20), @startTime);
end事務處理
--定義變量@sumError用于記錄事務過程中發(fā)生錯誤的次數(shù)
declare @sumError int;
set @sumError = 0;
begin transaction
update tblaccount set mnycurrentmoney = mnycurrentmoney + 200000 where chvAccountName='寶鋼集團'
--通過系統(tǒng)變量@@error可以獲取上次被執(zhí)行的sql是否執(zhí)行成功盹憎,如果執(zhí)行成功@@error的值為0,否則為1
set @sumError = @sumError + @@error
update tblaccount set mnycurrentmoney = mnycurrentmoney - 200000 where chvAccountName='安鋼集團'
set @sumError = @sumError + @@error
--判斷是否在執(zhí)行過程中出現(xiàn)錯誤
if(@sumError<>0)
begin
print '事務執(zhí)行失敗铐刘,即將回滾'
rollback transaction
end
else
begin
print '事務執(zhí)行成功陪每,即將提交'
commit transaction
end