DB學習之SQLServer(一)sql
零: 關係範式(設計數據庫中 表的基本原則)
0、基本思想:
消除關係中的數據冗餘
消除數據依賴中的不合適部分
以解決數據插入、更新、刪除操做中的異常問題
一、第一範式 1NF(First Normal Form)
表中的每一個屬性不可再分
(不容許屬性以數組、集合等方式存儲)
Stu表
name age course
- - - - - - - - - - - -
Tom 23 JavaSE、Oracle 不知足1NF
結論:知足1NF的數據庫設計,纔是關係型數據庫(最基本的範式)
二、第二範式 1NF(Seconde Normal Form)
在1NF的基礎上,添加一個主鍵(主屬性)
Stu表
id(PK) name age cid cname
1 Tom 23 101 JavaSE
改成CoreJava的話,全部的101課程都要改
2 Tom 21 102 Oracle
3 James 23 101 JavaSE
結論:可能出現數據的冗餘(不夠獨立)(多個JavaSE)、不一致(一處改,處處都要改,容易形成不一致)
三、第三範式 3NF
在2NF的基礎上,解除非主屬性之間的依賴關係
Stu表(學生表)
id(PK) name age
1 Tom 23
2 Tom 21
3 James 23
Course表(課程表)
id(PK) name
101 JavaSE 解除了數據冗餘,數據獨立,僅存一份
102 Oracle
103 Web
sc表(學生課程關係表)(沒有獨立主鍵,只有聯合主鍵,sid和cid的組合是惟一的)
sid cid grade
1 101 99
1 102 98
1 103 99
2 101 87
2 102 97
2 103 82
3 101 78
3 102 87
3 103 67
總結:使用第三範式 避免了數據的冗餘、不一致問題
常見的數據庫的設計都使用3NF
一: DBMS(數據庫管理系統)
SqlServer2008 Oracle10g DB2 MySql
0:基本概念
基本思路:經過DBMS來管理DB,從而管理DB中的表(table)以及其它數據資源
DB:DataBase(數據庫) 受DBMS的管理
物理結構:
*.mdf:主數據文件(MSSqlServer中)
*.ldf: 日誌文件(MSSqlServer中)
邏輯結構:
管理器(DBMS)中可見的部分,能夠經過sql來操做
關係型數據庫
核心概念:實體關係模型 E-R Model
(數據模型、域模型)
屬於數據庫設計範疇,表示不一樣實體(表)之間的關係
藉助於E-R圖來表示
工具:紙和筆 E-R Win
Sybase PowerDesigner
table:表 二維表 表示關係
表名:實體名(Entity)、關係名、在數據庫中區分不一樣的表
行: row 記錄(元組)
列: column 字段(屬性、域、Field)
字段名、字段數據類型、寬度、約束
1:如何操做SqlServer?
使用其管理器 - > 須要權限驗證登陸:默認採用Windows身份登陸
- > 登陸到DBMS - > 建立數據庫 - > 建立表
database table
數據庫的組成:
文件類型:
MDF(main data file)主數據文件,屬於主文件組(只有1個)
LDF(log data file) 日誌文件(能夠藉助日誌文件,進行數據還原),不屬於任何文件組
NDF 輔助數據文件(後來添加的文件)
文件組:(管理、分配數據文件)
主文件組:只有一個,Primary
次文件組
初始大小:文件一開始建立時候的大小
自動增加:
路徑:實際工做中出於安全考慮,不要將MDF和LDF將在同一路徑下,
數據庫至少須要如下2個物理文件:
student.mdf 主數據文件 保存業務數據
student_log.ldf 日誌文件 數據恢復等管理
數據庫的操做:
1)分離數據庫:
將某個數據庫脫離管理器(DBMS)管理
注意:不能是當前正在使用的數據庫
選中數據庫-》右鍵-》任務-》分離
2)附加數據庫:
將某個數據庫加入到管理器(DBMS)管理
選中數據庫-》右鍵-》附加-》添加-》選擇.mdf文件
數據的完整性:數據準確性、一致性
1)實體完整性 (行完整性)行的惟一
2)域完整性 (列完整性)列的要求
3)引用完整性 (參照完整性)好比員工表的部門id要參照部門表id
實現方式:約束 constraint(保證數據庫的完整性[準確性,一致性])
完整性:實體完整性 PK UK 行的惟一性
域完整性 NN UK CK default 字段的約束,列的約束
參照完整性 FK
約束也是數據庫中的一種對象,必定是針對某張表的 某個字段 進行約束
約束受數據庫管理,要求約束名是惟一的,表若是被刪除,那約束自動解除
約束的分類: 同的數據庫產品統一
PK primary key
FK foreign key references
UK unique
NN not null
CK check
default
1)主鍵約束 PK primary key
PK = UK + NN 惟一 且 非空
保證明體(每一行)的完整性
一張表是沒法同時定義多個PK
聯合主鍵:聯合起來,惟一且非空(只能使用表級約束實現)
列級約束:約束直接定義在字段以後
create table emp(
id int constraint emp_id_pk primary key,
name varchar(30) not null,
salary float
);
表級約束:全部的字段以後,追加約束(能夠實現聯全主鍵)
create table emp1(
id int,
name varchar(30) not null,
salary float,
constraint emp1_id_pk primary key(id)
);
聯合主鍵應用:
create table stu1(
id1 int,
id2 int,
name varchar(30),
constraint stu1_id1_id2_pk primary key(id1,id2)
);
2)惟一約束 UK unique
惟一
constraint 約束名 unique(字段)
alter table stu add constraint stu_name_uk unique(name);
3)外鍵約束 FK foreign key
引用完整性/參照完整性(參照的表中的字段,必定是惟一的(PK或者UK),用表級約束)
結論:經過主外鍵關係 實現了實體間的 1對多的關係(1(父表)———*(子表))
父表 dept部門表
子表 emp員工表
規則 父先於子存在,子先於父消失
先刪子表(子表依賴於父表),再刪父表
先加父表(子表依賴於父表),再加子表
只能用表級約束/建立完表在用alter add constraint添加外鍵約束,不能用列級約束,切記
constraint 約束名 foreign key(子表/本表 中的字段a) references 父表(字段b) 約束名:當前表_父表名_當前表中被添加FK約束的字段名_fk
———————————————————————————
dept表(父表) 1——-* emp表(子表)
id(PK) name(UK NN) id(PK) name dept_id(FK)
1 銷售 101 Tom 1
2 行政 102 James 1
3 研發 103 Mary 2
———————————————————————————
use worker;
drop table emp;
drop table dept;
create table dept(
id int constraint dept_id_pk primary key,
name varchar(30) not null unique
);
create table emp(
id int primary key,
name varchar(30) not null,
salary float,
dept_id int,
constraint emp_dept_deptid_fk foreign key(dept_id) references dept(id)
);
4)非空約束 NN not null
非空
5)檢查約束 CK check
6)默認值約束 default
alter table 表名 add constraint 約束名 default 默認值 for 字段;
alter table test1 add constraint test1_age_dk default 20 for age;
數據庫中包含的對象:
表 table
索引 index(主要用於提升查詢效率)
視圖 view
共同點: create 建立 drop 刪除
表 table
索引 index(主要用於提升查詢效率)
彙集(聚簇)索引(只能有1個)
記錄的索引順序與數據表中數據行的物理順序相同
create clustered index 索引名 on 表名(字段名);
drop index 表名.索引名;
非彙集(非聚簇)索引(能夠有多個,實際工做中經常使用)
記錄的索引順序與數據表中數據行的物理順序不相同
創建非彙集索引 沒有clustered,能夠針對多個字段創建非彙集索引,
經常使用,由於id默認是彙集索引(是不能建立多個彙集索引的,只能有1個)
create index 索引名 on 表名(字段名);
drop index 表名.索引名;
索引的底層原理:
使用數據結構:B-Tree 平衡二叉查找樹
特色:查詢效率很高
索引的特色和使用場合:
適合:從海量數據中查詢少許結果(大海撈針),不多修改數據的狀況,提升查詢效率,
好比:性能 瓶頸 sql效率
數據庫優化:針對字段創建索引
注意:沒法刪除PK默認的索引
創建索引會帶來開銷
1.佔據表空間 空間開銷
2.下降增、刪、改的效率 時間開銷(由於須要從新調整索引結構)
視圖 view()
用途:簡化sql語句,訪問權限設定,本質就是保存一條sql語句,
經過視圖名來代替一條sql語句,
不會佔據表空間、不會提升查詢效率
通常將比較複雜的sql建立視圖
建立視圖:
create view my_view0 as select * from myemp where salary>5000.0;
更改視圖:
alter view my_view0 as select * from myemp where salary>6000.0;
經過視圖,插入數據:本質基礎表中插入數據
insert into my_view0 values(4, 'Tony', 9000.0);
刪除視圖:
drop view my_view0;
數據庫中的函數:數據庫提供的函數能夠簡化sql
1)單行函數: 一條記錄 -》 一個結果
LEN(‘ABC’) 返回3,表示3個字符長度
2)多行函數:(組函數、彙集函數) 多條記錄 -》 一個結果
SUM() 求總和
AVG() 求平均值
COUNT() 統計記錄條數
MAX() 最大值
MIN() 最小值
組函數常常和group by子句配合使用
語法:where以後,
若是須要在分組後進一步過濾,可使用having子句
若是不寫group by,默認將全部 記錄做爲一組
注意:使用了組函數,就要求select以後的內容
要麼也使用組函數
要麼使用group by 字段
(總之必須和組相關)
2:SQL(Structured Query Language)結構化查詢語言
(1)DDL 數據定義語言 定義(數據庫、表)結構
create 建立
create database 數據庫名 on primary() log on(); 建立數據庫
create table 表名(); 建立表
create table 表名 add constraint ; 建立表中字段對應的約束
create index/view 建立索引/視圖
drop 刪除
drop database 數據庫名;
drop table 表名;
drop index/view 刪除索引/視圖
alter 改變
alter index/view 改變索引/視圖
alter table 表名 add constraint 約束名 primary key(字段); 添加約束(PK)
alter table 表名 add constraint 約束名 default 默認值 for 字段; 添加約束(DK)
alter table 表名 drop constraint 約束名 primary key(字段); 刪除約束()
(2)DML 數據操縱語言 操縱表中的數據(一行數據,一行的無組)
DML:select DQL Query查詢
增刪改查CURD(Create Update Read Delete)
insert
delete
update
select DQL(數據查詢語言)
[] 表示裏面的內容可省略
* 表示全部列/通配符
- - 單行註釋
/**/ 多行註釋
insert 插入數據
insert [into] 表名 values(列值1,列值2,全部字段值); 插入全部的列
insert [into] 表名(字段名1,字段名2,) values(列值1,列值2,); 插入指定的列
(不插入的列,默認是空值,null)
delete 刪除數據,能刪除:0、 一、 n行記錄
delete from 表名; 刪除全部行數據
delete from 表名 where 記錄匹配條件; 刪除表中的數據(記錄、行)
update 修改表中的數據
update 表名 set 字段1=新值,字段2=新值,; 修改全部行
update 表名 set 字段1=新值,字段2=新值, 修改指定行
where 記錄的匹配條件;
select 查詢數據
語法結構:(能夠不寫from,僅限MSSQL中,Oracle必需要寫)
select *,字段名,表達式,常量,函數調用
from 表1,表2,(可多表查詢)
where 查詢條件(分組前的過濾條件) 能夠組合(and or not)
= > >= < <= != <> between a and b in
is null is not null like % _ [] [^]
group by 字段名 根據該字段來分組
having 分組後的過濾條件
order by 字段名 排序規則
select * from 表名; 查詢全部行
select後面跟的內容:
as 給查詢的字段取別名(as可省略)
字段名 [as] 別名
+ 查詢結果的拼接,將多個列合併成1個列顯示
select以後可加常量(查詢結果新增長1列,第行都顯示’試用‘,新增長顯示的列沒有字段名)
select name,salary,'試用' from worker;
select 1+2; (僅限MSSQL中,能夠這樣寫)
select getdate() 當前系統時間; (僅限MSSQL中,能夠這樣寫)
select ‘試用’ as 類型; (僅限MSSQL中,能夠這樣寫)
distinct 去除查詢結果中的重複值(只能位於,selece和字段之間)
去重(排重)、排序(某些數據庫版本中同時還自動排好序)
from 表1,表2...
多表查詢
爲何須要多表查詢?
爲了知足3NF(拆表),避免了數據的冗餘,不一致性,
爲了造成良好的設計,進行拆表,數據分佈在多張表中(合久必分),
實際開發中,須要使用一條sql,同時查找多表的數據(分久必合)
- - - 錶鏈接(多表查詢)emp(員工表) 8條記錄 dept(部門表) 4條記錄
select * from emp,dept; 8*4=32條記錄——笛卡爾積
笛卡爾積:全部記錄都會匹配一次,不合理,只有8條是合理的
去除笛卡爾積,用where過濾
-- 查詢員工信息以及所在部門名稱
select *
from emp e, dept d
where e.dept_id=d.id;
-- 查詢員工id,name,salary以及部門名稱,要求薪水大於7000.0
select e.id, e.name, e.salary, d.name
from emp e, dept d
where e.dept_id=d.id and e.salary>7000.0
給表象起別名的好處:
1.簡化表名
2.區分不一樣表 相同字段 e.id d.id
3.提升sql效率
where:選擇、過濾出須要 行(記錄)
比較運算符:
= > >= < <= !> !<
!= <>(也表示不等於) ==
字段名 between a and b———[a,b]之間的值,則返回真
字段名 in(m,n,k,) 只要出如今括號中,則返回真
字段名 like ‘匹配字符串’ 模糊查詢
匹配字符串:
% 0個或多個字符(任意個字符)
_ 任意1個字符
[] 在範圍內的1個字符
[^] 不在範圍內的1個字符
null 空值null帶來的影響
空值和任何值包括空值和空值本身比較,都返回假
is null 判斷是否爲空
is not null 判斷是否不爲空
邏輯表達式:
and 而且 邏輯與
or 或者 邏輯或
not 非 邏輯非
group by 字段名 根據該字段來分組(寫在where以後)
若是不寫group by,默認將全部 記錄做爲一組
組函數常常和group by子句配合使用
語法:where以後,
若是須要在分組後進一步過濾,可使用having子句
若是不寫group by,默認將全部 記錄做爲一組
-- 查詢出全部員工的總薪水和平均薪水
select sum(salary) 總薪水, avg(salary) 平均薪水 from emp;
-- 查詢出每一個部門的總薪水和平均薪水,以及每一個部門的員工人數
select dept_id, sum(salary) 總薪水, count(id) 該部門員工數, avg(salary) 平均薪水 from emp group by dept_id;
-- 求出每一個部門中最高薪水和最低薪水
select dept_id, max(salary) 最高薪水, min(salary) 最低薪水 from emp
group by dept_id;
having 分組後的過濾條件
-- 求出12 部門的平均工資(分組前過濾),巧妙
select max(dept_id), avg(salary) 平均工資
from emp
where dept_id=12;
-- 求出12 部門的平均工資(分組前過濾)
select dept_id, avg(salary) 平均工資
from emp
where dept_id=12
group by dept_id;
-- 求出12 部門的平均工資(分組後過濾)
select dept_id, avg(salary) 平均工資
from emp
group by dept_id having dept_id=12;
order by 字段名 能夠根據不一樣的字段對查詢結果排序
位置: select語句的最後
本質: 在返回的查詢結果後,改變結果的返回順序
order by 字段 排序規則,;
排序規則:
[asc] 升序,默承認不寫
desc 降序
select * from myemp order by name, salary desc;——先對name按升序,相同則按salary按降序排序
sp_helpdb 查詢當前DBMS中全部的數據庫
select * from sys.databases; 查詢當前DBMS中全部的數據庫
= show databases;(MySQL中的寫法)
select * from sys.tables; 查詢當前數據庫中全部的表
= show tables;(MySQL中的寫法)
sp_help 表名; 查詢表的結構
select * into 新表名 from 源表名; 複製表(整張表所有複製,內容會複製)
會根據源表的結構建立新表
同時將查詢回的結果插入到新表中
select * into 新表名 from 源表名 where 條件; 複製表(表的局部複製,內容會複製)
select * into 新表名 from 源表名 where 1<>1; 複製表(表的結構的複製,內容不復制,無記錄)
(3)TCL 事務控制語言 Transcation事務
事務:要麼一塊兒成功,要麼一塊兒失敗的 一組原子操做
銀行轉帳操做就是一個事務,不可分割的操做—原子操做
A帳戶:-5000
B帳戶:+5000
事務和日誌有關,根據日誌恢復數據
begin transaction; 開始事務(sqlserver中這麼寫)
各類sql操做
commit 提交事務,所有成功
rollback 回滾事務,所有失敗
- - 單行註釋
/**/ 多行註釋
3:SQLServer經常使用的數據類型
數值類型
int 整數
float 浮點數
字符類型
char(10) 定長,固定分配10個字符空間
‘abc’ 分配10個字符空間,其他使用空白補充
== ‘abc ’
varchar(10) 可變長,最多分配10個字符空間,
‘abc’ 只分配3個字符空間,節約數據庫空間
日期類型
datatime
注意:添加時,要加’’,2個單引號
4:SQL腳本
4.1建立數據庫
利用SQL語句,建立一個數據庫,數據庫名字Lib
磁盤中的位置:D:\SQLServer\Lib
mdf文件:
初始化的大小是5W,
每次增加1,
大小沒有限制
名字lib_dat
log文件:
初始化的大小是3W,
每次增加10%,
最大的容量是8W
名字lib_log
建立數據庫的基本的格式:
create database 數據庫名字
on primary( 數據庫中主要存儲文件)
log on( 數據庫中日誌文件)
create database Lib
on primary
(
name = lib_dat,
filename = 'C:\SQLServer\lib\libdat.mdf',
size = 5,
maxsize = unlimited,
filegrowth = 1
)
log on
(
name = lib_log,
filename = 'C:\SQLServer\lib\liblog.ldf',
size = 3,
maxsize = 10,
filegrowth = 10%
)
4.2建立表
3種方式:
1)使用SQL語句來建立表(最經常使用的)
SQL語句來建立表的基本格式
use 數據庫名字
CREATE TABLE 表的名字
(
字段名1(屬性名/列名) 數據類型 (各類約束),
字段名2 數據類型 (各類約束),
字段名3 數據類型 (各類約束),
...
)
[GO]
主鍵約束:primary key(固定的格式)
非空約束:添加數據的時候,被非空約束,所修飾的列,必須有內容 ,
not null除了主鍵約束之後,其餘的約束,是根據須要才添加
2) 利用工具在數據庫中來建立表
a)特色:方便,簡單,使用極少
(大型數據庫,通常要麼是用專業建表工具來生成表,要麼經過Sql來建表,
只有SQLServer系列數據庫等才支持用工具建表)
b)經過工具來往表中添加數據
c)select * from 表名:顯示當前表中全部的數據
3) 利用模板來建立表(開發中基本不用)
數據庫