名詞解釋:sql
三級模式:數據庫
兩級映像與數據獨立性的關係:編程
概念模型三種聯繫的類型:安全
實體-聯繫(Entity-Relationship)模型通用表示方式:併發
關係模型三類完整性規則:dom
關係代數:是以關係爲運算對象的一組高級運算的集合。關係代數是一種抽象的查詢語句,是關係數據操縱語言的一種傳統表達方式,即代數方式的數據查詢過程。關係代數的運算對象是關係,運算結果也是關係。數據庫設計
笛卡兒積函數
B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}性能
選擇運算測試
投影運算
關係模式是一個五元組,能夠表示爲 R(U,D,dom,F)
學生狀況表(學號,姓名,性別,年齡,所在系)
。範式是符合某一種級別的關係模式的集合
1NF:任何關係模式都是第一範式。
2NF:不存在非主屬性部分函數依賴於碼
3NF:非主屬性既不部分也不傳遞函數依賴與碼
數據庫系統設計分爲 6 個階段:
E-R 模型轉換關係數據模型
實體的轉換:
SQL Server 中數據文件的類型
邏輯數據庫:
建立表格 / 修改表結構 / 刪除表格
-- 建立表格 CREATE TABLE student ( cno char(4) PRIMARY KEY, cname nvarchar(20) NOT NULL, sex nvarchar(4), birthday date ) -- 修改表格只須要將 CREATE 改成 ALTER -- 刪除表格 DROP TABLE [TABLE_NAME]
約束:約束是經過限制列中數據、行中數據和表之間數據來保證數據完整性的很是有效的方法。約束能夠確保把 有效數據 輸入到列中及維護表和表之間的特定關係
-- 在建立表的同時建立約束 CREATE TABLE student ( cno char(4) PRIMARY KEY, /*Primary Key*/ sex nvarchar(4) DEFAULT '男' CHECK(sex IN ('男','女')), /*Default+Check*/ birthday date DEAFAULT date(getdate()), /*Default*/ IDCardNUM char(18) UNIQUE, /*Unique 約束*/ class char(10) Foreign KEY Reference classes(class_num)/*foreing key*/ …… ) -- 在建立表以後添加約束 ALTER TALBE [表名] ADD CONSTRAINT [約束名] [約束類型] (列名) ALTER TALBE student ADD CONSTRAINT pk_st PRIMARY KEY (cno) ALTER TALBE student ADD CONSTRAINT cj_sex CHECK(sex in ('男', '女')) /*性別只能爲男或女*/
-- 單表查詢 SELECT * FROM 表名 -- 多表查詢 SELECT rdID, rdName FROM Reader; -- DISTINCT 關鍵字 SELECT DISTINCT specialty FROM student; /*查詢學生表中的專業名稱,過濾重複行*/ -- AS 關鍵字 SELECT DISTINCT specialty AS 專業名稱 FROM student;/*將查詢結果中 specialty 取一個列別名*/
-- 比較運算符 =、>、<、>=、<=、!=、<>、!>、!< SELECT * FROM sc WHERE score >= 60 -- 邏輯表達式 AND、OR、NOT SELECT * FROM student WHERE specialty = '計算機' AND ssex = '男' -- 肯定範圍的關鍵字 BETWEEN AND、NOT BETWEEN AND SELECT * FROM sc WHERE score BETWEEN 80 AND 90 -- 肯定集合的關鍵字 IN、NOT IN SELECT * FROM student WHERE specialty IN ('計算機','通訊') -- 字符匹配關鍵字 LIKE、NOT LIKE SELECT * FROM student WHERE sname LIKE '張%' /*查找姓張的學生*/ SELECT * FROM student WHERE sname LIKE '張_' /*查找姓張且姓字爲兩個字的學生*/ -- 空值判斷關鍵字 IS NULL、IS NOT NULL SELECT * FROM sc WHERE score IS NULL -- 複合條件查詢 SELECT * FROM student WHERE sex = '女' AND (specialty = '計算機' OR specialty = '通訊')
-- 簡單分組 SELECT * FROM student GROUP BY ssex -- HAVING 關鍵字:選修了兩門及以上課程的學生 SELECT * FROM student GROUP BY ssex HAVING COUNT(cno) >= 2 -- 聚合函數 count()、sum()、avg()、min()、max()
------------------------------------------------- a表 id name b表 id job parent_id 1 張三 1 23 1 2 李四 2 34 2 3 王武 3 34 4 a.id 同 parent_id 存在關係 -------------------------------------------------- -- 內鏈接 select a.*,b.* from a inner join b on a.id = b.parent_id 結果是: 1 張三 1 23 1 2 李四 2 34 2 -- 左外鏈接 select a.*,b.* from a left join b on a.id = b.parent_id 結果是: 1 張三 1 23 1 2 李四 2 34 2 3 王武 null -- 右外鏈接 select a.*,b.* from a right join b on a.id=b.parent_id 結果是: 1 張三 1 23 1 2 李四 2 34 2 null 3 34 4
-- 查詢與連曉燕在同一個單位的讀者; SELECT rdName FROM Reader WHERE rdDept = (SELECT rdDept FROM Reader WHERE rdName = '連小燕');
-- UNION(並集):查詢選修了課程 C001 和 課程 C004 的學生的姓名 SELECT sname FROM sc,student WHERE cno = 'C001' AND sc.sno = student.sno UNION SELECT sname FROM sc,student WHERE cno = 'C004' AND sc.sno = student.sno -- EXCEPT(差集):查詢沒有選課的學生的學號 SELECT sno FROM student EXCEPT SELECT sno FROM sc -- INTERSECT(交集):查詢即選修了課程 C001 又選修了課程 C004 的學生的姓名 SELECT sname FROM sc,student WHERE cno = 'C001' AND sc.sno = student.sno INTERSECT SELECT sname FROM sc,student WHERE cno = 'C004' AND sc.sno = student.sno
-- 默認升序 ASC SELECT * FROM SC ORDER BY sname ASC -- 降序排序 DESC(按成績降序,成績相同的話按學號升序排) SELECT sno,score FROM SC ORDER BY score DESC,sno ASC
視圖並非以一組數據的形式存儲在數據庫中,數據庫中只存儲視圖的定義,不存儲視圖對應的數據,這些數據仍存儲在導出視圖的基本表中,視圖其實是一個查詢結果。
-- 建立視圖 CREATE VIEW view_name AS SELECT column_name(s) FROM table_name WHERE condition -- 查看視圖 SELECT * FROM view_name -- 刪除視圖 DROP VIEW view_name
索引的類型
彙集索引:
非彙集索引:
CREATE INDEX index_name ON table_name(col_name)
DECLARE @var_name VARCHAR(20)
、DECLARE @MyCounter INT
SET @var_name = GETDATA()
、SELECT COUNT(sno)=@MyCounter from student
PRINT @var_name,@MyCounter
批出理語句使用
/* 多行註釋 */ -- 單行註釋 SELECT sno,sname FROM student GO -- 此處 GO 爲批處理語句
流程控制語句
-- SET 語句 DECLARE @myvar char(20); SET @myvar = 'This is a test'; SELECT @myvar; GO -- BEGIN END 語句(用於將多個 SQL 語句合併爲一個語句塊) BEGIN { sql_statement|statement_block } END -- IF……ELSE 語句: -- 若是 C001 號課的平均成績高於 80 分,則顯示「平均成績還不錯」,不然顯示「平均成績通常」 IF ( SELECT AVG(score) FROM sc WHERE cno = 'coo1') > 80 PRINT 'C001 號課的平均成績還不錯' ELSE PRINT 'C001 號課的平均成績通常' -- CASE 語句:以搜索 CASE 格式查詢全部學生的考試等級,包括學號、課程號和成績級別 SELECT sno,cno, CASE WHEN score >= 90 then 'a' WHEN score >= 80 then 'b' WHEN score >= 70 then 'c' WHEN score >= 60 then 'd' WHEN score < 60 then 'e' END AS score_level FROM sc -- WHILE 語句:求 1 到 100 的累加和,當和超過 1000 時中止累加,顯示累加和以及累加到的位置。 -- 結果:a=1035,i=45 DECLARE @i int,@a int SET @i = 1, @a = 0 WHILE @i <= 100 BEGIN SET @a = @a + @i IF @a >= 1000 BREAK SET @i = @i + 1 END SELECT @a AS 'a',@i AS 'i'
函數
-- 聚合函數 ADD(),AVG(),SUM()…… -- 日期函數 GETDATE():返回系統當前的日期和時間 DAY():返回日期表達式中的日 MOUTH():返回日期表達式中的月 YEAR():返回日期表達式中的年 -- 自定義函數:求選課表中某門課的平均成績 CREATE FUNCTION average(@cn char(4)) RETURNS float AS BEGIN DECLARE @aver float SELECT @aver = (SELECT avg(score) FROM sc WHERE cno = @cn) RETURN @aver END
遊標(定義、打開、讀取、關閉、釋放)
-- 利用遊標將sc表中選課成績小於50分的成績提升30%,將大於等於50分的成績提升50% -- 定義遊標 DECLARE SC_Cursor CURSOR DYNAMIC FOR SELECT Grade FROM SC FOR UPDATE OF Grade -- 打開遊標 OPEN SC_Cursor -- 讀取遊標 DECLARE @Grade INT FETCH NEXT FROM SC_Cursor INTO @Grade --假如檢索到了數據,才處理 WHILE @@FETCH_STATUS = 0 BEGIN -- 填充數據 IF @Grade < 50 UPDATE SC SET Grade = @Grade * 1.3 WHERE CURRENT OF SC_Cursor ELSE UPDATE SC SET Grade = @Grade * 1.5 WHERE CURRENT OF SC_Cursor -- 填充下一條數據 FETCH NEXT FROM SC_Cursor INTO @Grade END -- 關閉遊標 CLOSE SC_Cursor -- 釋放遊標 DEALLOCATE SC_Cursor GO
建立存儲過程(修改存儲過程只要將 CREATE 替換爲 ALTER)
-- 不帶參數的存儲過程 CREATE PROCEDURE students_avg AS SELECT sno,avg(score) AS 'avgscore' FROM sc GROUP BY sno GO -- 帶參數存儲過程 CREATE PROCEDURE usp_rdName @rdID CHAR(9), @rdName VARCHAR(20) OUTPUT AS SELECT @rdName = rdName FROM Reader WHERE rdID = @rdID GO -- 存儲過程當中可使用 raiserror 拋出異常
調用存儲過程
-- 執行不帶參數的存儲過程 EXECUTE students_avg -- 執行帶參數的存儲過程 DECLARE @Result VARCHAR(20) EXEC usp_rdName 'rd2017001',@Result OUTPUT PRINT @Result
刪除存儲過程
DROP PROCEDURE students_avg
觸發器
建立觸發器、激發觸發器、刪除觸發器(刪除觸發器所在的表,系統會自動刪除與該表相關的觸發器)。
-- 建立 DML 觸發器: GO CREATE TRIGGER DML_Limited ON student FOR DELETE AS DECLARE @count varchar(50) SET @count = STR(@@ROWCOUNT)+'個學生被刪除' SELECT @count RETURN -- 執行 DML 觸發器(查詢結果爲:5個學生被刪除) DELETE FROM student WHERE specialty = '計算機' -- 刪除 DML 觸發器 DROP TRIGGER DML_Limited -- 禁止在 student 表上的全部觸發器 ALTER TABLE student DISABLE TRIGGER ALL -- 建立 DDL 觸發器:禁止用戶修改 BooksDB 數據庫中的表; GO CREATE TRIGGER DDL_Limited ON DATABASE FOR DROP_TABLE,ALTER_TABLE AS PRINT '名爲 DDL_Limited 的觸發器禁止您修改 BooksDB 數據庫中的表' ROLLBACK -- 執行 DDL 觸發器 DROP TABLE Borrow -- 刪除 DDL 觸發器 DROP TRIGGER DDL_Limited -- 測試 AFTER 觸發器,理解 INSERTED 表和 DELETED 表的做用; GO CREATE TRIGGER tri_InsDelOnReader ON Reader for INSERT, DELETE AS SELECT * FROM inserted SELECT * FROM deleted PRINT 'Reader 表上的 AFTER 觸發器已執行!' GO -- 激發觸發器執行 INSERT INTO Reader VALUES('rd2017008', 3, '孫星', '計算機科學學院', '66666666', 0); -- 激發觸發器執行 DELETE FROM Reader WHERE rdID = 'rd2017008'
根據運行模式分類,事務分爲 4 種類型:
若是多個用戶同時訪問一個數據庫沒有加以控制,就可能發生問題,這些問題包括:
鎖的類型
INSERT INTO Reader VALUES('rd2017008', 3, '孫星', '計算機科學學院', '66666666', 0);
CREATE TABLE Account( cardID CHAR(4) NOT NULL PRIMARY KEY, Name CHAR(6), Balance INT CHECK(Balance > = 1) ) GO INSERT INTO Account VALUES('6666', '張三', 1000) INSERT INTO Account VALUES('8888', '李四', 1) --使用事務實現轉帳:捕獲到異常就回滾 BEGIN TRAN BEGIN TRY UPDATE account SET balance = balance + 1000 WHERE cardID = '8888' UPDATE account SET balance = balance - 1000 WHERE cardID = '6666' COMMIT END TRY BEGIN CATCH ROLLBACK END CATCH
-- 執行如下代碼打開隱式事務: SET IMPLICIT_TRANSACTIONS ON -- 建立一個數據表,開始一個新的事務 CREATE TABLE T1 (i INT PRIMARY KEY) GO -- 查詢表(查詢成功) SELECT * FROM T1 -- 取消事務後再查詢表中的數據(因爲表不復存在,因此會獲得一個錯誤信息。) ROLLBACK SELECT * FROM T1 -- 執行如下代碼關閉隱式事務: SET IMPLICIT_TRANSACTIONS OFF;
GRANT|REVOKE|DENY ALL ON 安全對象 TO 用戶
。安全對象 | ALL 對應的權限 |
---|---|
數據庫 | CREATE DATABASE, CREATE PROCEDURE, CREATE VIEW, CREATE TABLE, CREATE RULE 等 |
標量函數 | EXECUTE, REFERENCES |
表值函數 | SELECT, DELETE, INSERT, UPDATE, REFERENCES |
存儲過程 | EXECUTE, SYNONYM |
表 | SELECT, DELETE, INSERT, UPDATE, REFERENCES |
視圖 | SELECT, DELETE, INSERT, UPDATE, REFERENCES |
-- 建立登錄帳戶、建立數據庫帳戶、授予權限、拒絕權限實例 CREATE LOGIN wtq WITH PASSWORD = 'wtq888',DEFAULT_DATABASE = BooksDB GO CREATE LOGIN test WITH PASSWORD = 'test888',DEFAULT_DATABASE = BooksDB GO CREATE USER wtq FROM LOGIN wtq GO CREATE USER test FROM LOGIN test GO GRANT SELECT,INSERT ON ReaderType TO wtq DENY DELETE,UPDATE ON ReaderType TO wtq DENY DELETE,INSERT,REFERENCES,SELECT,UPDATE ON ReaderType TO test
-- teaching 的完整備份(差別備份只須要將 WITH 後面的 Format 改成 Differential ) BACKUP DATABASE teaching TO DISK = 'F:\BACKUP\teaching.Bak' WITH FORMAT NAME = 'teaching 的完整備份' -- teaching 的完整數據庫備份進行還原(差別還原使用 WITH RECOVERY) RESTORE DATABASE teaching TO DISK = 'F:\BACKUP\teaching.Bak' WITH REPLACE,NORECOVERY
// 引入 數據命名空間 和 SQL 命名空間 using System.Data using System.Data.SqlClient // 建立鏈接對象並實例化,例如鏈接一個名爲 School 的 SQL Server 數據庫 SqlConnection con = new SqlConnection(); con.ConnectionString = @"Data Source = .\SQLEXPRESS; AttachDbFilename = E:\data\ school_Data.MDF;Integrated Security = True;Connect Timeout = 30;User Instance = True"; // 打開數據庫鏈接 con.Open(); // 讀取數據 SqlCommand cmd = con.CreateCommand(); // 建立命令對象並實例化 cmd.CommandText = "SELECT * FROM student";// SqlCommand 的屬性 CommandText 是一條 SQL 語句 SqlDataReader dr = cmd.ExecuteReader(); // 創建DataReader對象迅速獲取查詢結果