隨着時代的發展,人類活動產生的信息愈來愈多,你們常說,如今這個時代是大數據時代。在這樣一個前提下,數據的存儲成爲咱們必需要認真對待和研究的問題了。SQL(Structured Query Language)結構化查詢語言,是當今三大主流關係型數據庫(MsSQL,MySQL,Oracle)的通用操做語言,今天就給你們分享一下我對數據庫和 SQL 的一些認識,但願對你們有用。數據庫
一 數據庫簡介安全
1,什麼是數據庫網絡
在理解什麼是數據庫以前,咱們首先要明白另外一個問題,即什麼是數據?ide
一我的的身高、體重、年齡;一輛車的品牌、顏色,尺寸;一個運動員在完成比賽期間所用的時間,速度,心率;即便你計算機上的圖片、視頻等都是數據。個人結論就是:用於描述事物或事件的屬性,而且能被人們識別的符號就是數據。函數
明白了什麼是數據,不難推測出:數據庫就是數據存儲的倉庫,各類數據的集合。固然數據庫中的數據都是有序的,有組織的,這是爲了能讓管理數據更方便。大數據
2,什麼是數據庫管理系統spa
你可能經常聽到人們常說:MsSQL 數據庫、MySQL 數據庫、Oracle 數據庫等等,其實他們多數指的是不一樣的數據庫管理系統。SQL server 是微軟旗下的數據庫管理系統,MySQL 和 Oracle 目前都屬於甲骨文公司。code
數據庫管理系統本質上是一套軟件,專門用於幫助用戶管理數據庫中的數據。視頻
3,什麼是關係型數據庫server
根據數據庫組織和存儲數據的方式,數據庫一般分爲四類:層次式數據庫、網絡式數據庫、關係型數據庫、非關係型數據庫。
前兩種基本已經成爲了歷史,如今主流的是後兩種,但佔市場絕對優點的仍然是關係型數據庫(Relational Database Management System:RDBMS)。顧名思義,關係型數據庫是依照數據與數據之間的關係來組織存儲數據的。
爲了方便後面的書寫,這裏進行一個聲明:今後以後,文中提到的全部數據庫均指關係型數據庫。
4,數據庫和 SQL 有什麼聯繫
SQL,指結構化查詢語言,全稱是 Structured Query Language。
SQL 是用於訪問和處理數據庫的標準的計算機語言。
SQL 是一種 ANSI(American National Standards Institute 美國國家標準化組織)標準的計算機語言。
SQL 是一種命令式語言。
當今三大數據庫管理系統均支持標準 SQL。
二 如何存儲
如今,咱們已經知道什麼是數據庫、數據庫管理系統和 SQL 了。那麼,既然數據庫是用來存儲數據的,那麼數據庫具體是經過什麼方式來進行存儲的呢?它又是怎樣保證數據的有效性、合法性呢?既然說現今社會主流的仍然是關係型數據庫(RDBMS),那麼數據庫又是怎麼在數據與數據之間肯定關係的呢?
1,數據的存儲方式
開門見山的說:數據庫是經過「表」來存儲數據,根據不一樣的數據庫管理系統,以不一樣的文件格式最終被保存到物理磁盤上(可能是硬盤)。
這裏的表相似 Excel 表格,表中的數據由不一樣的行和列組成,每一列在數據庫中咱們稱爲一個字段,每一行數據稱爲一條記錄或元組,它算是數據在數據庫中的基本單元。
若是用一張表來記錄一類事物,那麼每一條記錄能夠當作這類事物單獨的個體,而不一樣的列則是用來記錄事物的每一個具體的特性。例如一個Person 表,用來記錄人員信息,每一個人員均可以擁有本身的姓名,年齡,性別,身高等信息,那麼這個表應該具備姓名,年齡,性別等這些列。
name | age | sex | height | birthday |
張三 | 20 | 男 | 180 | 2000-01-01 |
李四 | 18 | 女 | 170 | 2002-01-01 |
王五 | 25 | 男 | 165 | 1995-01-01 |
在這個表中,每一行就是一條記錄,表明一個具體的人,每一列都是用來描述人的不一樣特徵的,從表中能夠看出,每一個人都擁有不一樣的特性。
2,確保數據的有效性
上面的表格有一個問題:不能確保數據的有效性、合法性。爲何這麼說呢?
試想一下,這個世界上人那麼多,總會有其餘人也叫張三,而且年齡正好也是20,正好也是個身高180的大漢,那麼在表中豈不是有兩條如出一轍的記錄?那咱們怎麼來區分到底誰是誰呢?還有,在不加任何限制的狀況下,我能夠隨意錄入人員的年齡,好比我錯把王五的年齡記錄成了250,這世上尚未能活250歲的人吧,顯然這樣的數據是不合常理的。
那麼數據庫是怎麼解決這個問題的呢?答案是:約束。
約束做用於表的列,約束用於規定表中的數據存儲規則。若是咱們在錄入數據時,不符合約束的規定,那麼你將不能把該數據錄入數據庫中。
3,約束
數據庫中主要的約束有如下幾種:
NOT NULL - 指示某列不能存儲 NULL 值,即空,什麼都沒有。
UNIQUE - 保證每行的某一列必須具備惟一的值,不能重複。
PRIMARY KEY - NOT NULL 和 UNIQUE 的結合。確保某列(或多個列的結合,即聯合主鍵)有惟一標識,有助於更容易更快速地找到表中的一個特定的記錄。
FOREIGN KEY - 保證表中某一列的數據來自另外一個表中的某一列。能使用外鍵約束的列,其數據在另外一個表中必須是主鍵。數據庫正是經過外鍵來創建表與表之間的聯繫。
CHECK - 保證列中的值符合指定的條件,確保數據的合理性。
DEFAULT - 規定沒有給列賦值時的默認值。
本章主要講解數據庫如何存儲數據和如何確保數據的有效性,下一章將詳細介紹如何建立表,如何爲表的字段添加約束,以及如何向表中插入和刪除數據等。
三 如何操做
1,基礎語法
前面提到,SQL 是命令式語言,因此它的語法其實很是簡單,每一條命令就是一條語句,每條語句以「;」結束(非必須)。而且 SQL 語句對大小寫不敏感,不過爲了方便閱讀和維護代碼,請儘可能統一命令的大小寫。
SQL 中的命令總共分爲四大類:
A:DDL(Data Definition Language)數據定義語言
主要命令包括:create(建立)、alter(修改)、drop(刪除)
B:DQL(Data Query Language)數據查詢語言
主要命令包括:select
C:DML(Data Manipulation Language)數據操縱語言
主要命令包括:insert(插入)、update(修改),delete(刪除)
不少時候,select 命令也被認爲是 DML 語言的一種,因此,若是你在其餘地方聽到這種說法時,沒必要感到詫異。
D:DCL(data Control Language)數據控制語言
主要命令包括:grant(受權)、revoke(回收)、commit(提交)、rollback(回滾)等
數據控制語言主要是針對數據庫安全性方面的操做,能夠簡單理解爲權限管理,這部分命令 DBA 常用,通常數據開發人員用的較少。
2,使用方式
DDL:
1 create database "my_db";--建立一個庫 2 use "my_db";--選擇剛剛穿件的庫 3 create table "my_tb" 4 ( 5 --字段名1 數據類型 約束, 6 --字段名2 數據類型 約束, 7 --...... 8 );--在「my_db」中建立表「my_tb」 9 10 alter table "my_tb" 11 add 字段名 數據類型;--修改表,並向其新增一列 12 alter table "my_tb" 13 alter 字段名 數據類型;--修改表中某一列的數據類型 14 15 drop table "my_tb";--刪除表 16 drop database "my_db";--刪除庫 17 truncate table 表名;--清空表中的數據
DQL:數據查詢語言是 SQL 的重中之重,將在下一頁單獨講解,這裏僅給出 select 命令的基礎用法。
1 /*以上面的 Person 表爲例*/ 2 select name ,age from Person;--查詢Person表中全部人員的姓名及年齡 3 select * from Person;--查詢Person表中的全部數據,*是通配符
DML:
1 /*以 Person 表爲例*/ 2 insert into Person (name,age,sex,height) 3 values('小明',12,'男',150); 4 --向表中插入一條數據,指定插入的列 5 insert into Person 6 values ('小黑',22,'男',170); 7 --若是須要插入每一列的數據,能夠不指定具體的列 8 update Person set sex='女' where name='小明'; 9 --修改小明的性別爲女 10 delete from Person where name='小明'; 11 --刪除姓名爲小明的記錄
3,建立約束
建立約束有兩種方式,其一:在建立表時同時建立約束,其二:同過 alter 命令向已建立的表添加約束。
建立表時:
1 /*建立表時即添加約束*/ 2 create table tablename 3 ( 4 id int identity(1,1) primary key, 5 name varchar(50) not null, 6 idcard char(18) unique, 7 city varchar(50) foreign key(city) references City(id),--city列的值經過外鍵綁定City表的id列 8 age int check (age>0 and age<150), 9 email varchar(50) not null 10 )
表已建立時:
1 /*經過 alter 命令添加約束*/ 2 alter table tablename 3 add 4 constraint ck_email check (email like '%@%'); 5 --經過 constraint 能夠指定約束的名字,建立表時添加約束也可使用,但它不是必須的
聯合主鍵:
1 --建立表時: 2 create table tablename 3 ( 4 col1 ... , 5 col2 ... , 6 ......, 7 constraint pk_name PRIMARY KEY (col1,col2) 8 ) 9 --表已建立: 10 alter table tablename 11 add 12 constraint pk_name PRIMARY KEY (col1,col2)
4,數據類型
不一樣數據庫支持的數據類型有較大差別,即便相同的數據庫不一樣的版本也存在必定差別,因此在使用時請儘可能以官方文檔爲依據,這裏僅列出部分經常使用的通用的數據類型:
bigint(整型)、varchar(n)(可變長度字符串)、boolean(布爾值)、float(浮點型)、date(日期)、time(時間),timestamp(日期+時間型)、xml(XML型)。
四 如何查詢
相較於其餘命令,數據庫開發中用的最多的就是 select 了,沒有之一。
1,普通查詢
經過幾條簡單的查詢語句來講明:
1 insert into Person values('張五',30,男,175,'1990-01-01'); 2 insert into Person (name,sex,height,birthday) 3 values('張六',男,175,'1990-01-01'); 4 --先插入兩條新數據 5 select * from Person as P 6 where P.birthday between '1990-01-01' and '2010-01-01' 7 and P.name like '%張%' 8 and P.age is not null 9 --查詢生日在1990-2010間姓名包含張而且年齡不爲空的全部人員信息
經過上面的例子,我要說明查詢語句的一些基本用法。
首先是緊跟在 select 命令以後的信息,它表示須要被查詢的字段,* 星號表示通配符,意爲查詢全部表中的字段。
其次是 from 關鍵字,它表示從哪一個表中查詢數據,緊跟在其後的是被查詢的表名。
as 關鍵字的做用是給表起一個別名,主要是爲了簡化代碼,被查詢的字段,也可使用 as 起一個更通俗易懂的別名。
where 關鍵字用於指定過濾條件,經過 where 咱們能夠只查詢咱們須要的數據,提升查詢速度。
and 關鍵字用來鏈接不一樣的過濾條件。
between...and... 是一個組合範圍關鍵字,如上例所示,它能夠用來指定時間範圍,還能夠用來指定數字的取值範圍等。
like 用來指定模糊查詢,% 表示零個或多個任意字符,_ 表示任意單個字符,[ ] 表示指定字符中的一個,[^ ] 表示不在指定字符中的一個。
一個特別的:在過濾條件中,判斷某列的值是否爲空,應該使用 is 或 not is 關鍵字,而不是使用 = 等號或 != 不等號 。
2,分組和排序
SQL 中的分組使用 group by 實現,group by 一般和聚合函數一塊兒使用,單獨使用 group by 分組沒有現實意義。
SQL 中的聚合函數從列的計算中獲取值,通常返回一個單一的值。SQL 中除了聚合函數,還有另外一類標量函數,它們基於輸入的值返回一個單一的值。
聚合函數 | 含義 | 標量函數 | 含義 |
AVG() | 返回平均值 | UCASE() | 轉換爲大寫 |
COUNT() | 返回行數 | LCASE() | 轉換爲小寫 |
FIRST() | 返回第一個記錄 | SUBSTRING() | 截取字符串 |
LAST() | 返回最後一個記錄 | LEN() | 返回字段長度 |
MAX() | 返回最大值 | ROUND() | 四捨五入 |
MIN() | 返回最小值 | NOW() | 返回系統時間 |
SUM() | 返回總和 | FORMAT() | 格式化字符串 |
不一樣數據庫對函數的實現有必定差別,但經常使用的函數使用方式都相同:如上黑體字列出的聚合函數。
單獨使用聚合函數:
1 select avg(age) as "平均年齡" from Person;--計算全部人的平均年齡 2 select max(age) as "最大年齡",min(age) as "最小年齡" from Person;--計算最大年齡和最小年齡 3 select count(name) as "人數" from Person;--統計表中的人數 4 --count()經過指定列來統計個數,忽略 NULL 值
聚合函數 + group by:
1 select sex,sum(name) as "人數" from Person 2 group by sex 3 having sum(name)>2;--查詢性別人數之和大於的的性別和人數 4 --group by 後面爲聚合(或者叫分組)的字段,查詢中用來分組的字段都必須出如今 group by 以後,having 用來對聚合後的數據再過濾
若是有多個字段須要被用來分組,那麼他們的分組順序是從左至右的,而且最右邊的字段將被當作聚合函數計算的最小分組。
使用 order by 排序:
1 select * from Person order by age desc; 2 --按年齡從大到小排序查詢全部信息,desc 表示倒序。默認是asc 表示升序,能夠省略。group by 能夠和 order by 一塊兒使用,但 order by 永遠在查詢語句的最後
3,鏈接查詢
鏈接查詢分爲三類:內鏈接,外鏈接,全鏈接。
咱們知道,現實世界中的事物都存在各類聯繫,經過事物之間的種種聯繫,你能夠收集到更多在一類事物上不存在的信息。正如著名的七人理論:你最多隻須要經過7我的就能和世上任何一我的認識。這也是一種典型的關係模型。
咱們的關係型數據庫正是經過各類各樣的外鍵把不一樣表關聯起來的。只要根據他們的關係,咱們就能夠在不一樣的表中查找咱們想要的任何數據了。
A:內鏈接
內鏈接的用法以下:
1 select * from tableA,tableB;--方式一 2 select * from tableA A 3 join tableB B 4 on 1=1;--方式二(join 是inner join 的縮寫,on 用來指定組合產生新數據鏈接的條件,這裏1=1始終爲真,意爲沒有任何限制的鏈接兩個表)
內鏈接會使用兩個表中的數據產生一個笛卡爾積,簡單的說就是:數據庫把兩個表中的數據認爲是多對多的關係,用表 A 的每一條數據去和表 B 中的每一條數據組合成新的數據。
最終的結果是:總記錄的條數是兩個表記錄條數的乘積,字段數是兩個表字段數的總和。
很顯然,一般狀況下,笛卡爾積並非咱們須要的數據。方式一能夠經過 where 來設置過濾條件,而方式二則是經過 on 指定鏈接條件。好比以下sta和sal兩個表:
sta表 | id | name | sal_grade | sal表 | sal_grade | sal |
1 | 張三 | 3 | 1 | 8000 | ||
2 | 李四 | 2 | 2 | 6000 | ||
3 | 王五 | 1 | 3 | 4000 |
1 select * from sta,sal;--會返回 9 條記錄,每條記錄有 5 個字段 2 select * from sta,sal 3 where sta.sal_grade = sal.sal_grade;--只會返回9條記錄中sta.sal_grade = sal.sal_grade的數據,共3條 4 select * from sta join sal 5 on sta.sal_grade = sal.sal_grade;--也只返回 3 條記錄,但他們的原理是有差異的,where 是在產生笛卡爾積後過濾,而 join 方式是在肯定鏈接關係時就開始過濾,最終不會產生笛卡爾積,除非 on 指定的條件爲真 6 select sta.id,sta.name,sal.sal from sta join sal 7 on sta.sal_grande = sal.sal_grande;--只查詢須要的字段,而不是兩個表中全部的字段
B:外鏈接
外鏈接又分爲左外鏈接和右外鏈接,左外鏈接會返回全部左表中的記錄,不管是否知足鏈接條件,而右外鏈接恰好相反,會返回右表中全部的記錄,不管是否知足鏈接條件。這裏的左和右是指 join 關鍵字的左和右。
外鏈接最終的輸出結果表現爲:總記錄數不能肯定,由於可能存在一對多的關係。而字段數仍爲兩個表字段數之和。那些知足鏈接條件的記錄,每一個字段都會有肯定的值,而那些不知足鏈接條件的記錄,則只有左表或右表的字段有值,另外一個表的字段爲 NULL(具體取決因而左外鏈接仍是右外鏈接)。
1 insert into sta values(4,'張五',5); 2 select sta.id,sta.name,sal.sal from sta 3 left join sal 4 on sta.sal_grande = sal.sal_grande;--返回 4 條記錄,但張五的工資字段爲 NULL,由於 sal 表中並無 sal_grande 爲 5 的記錄能夠匹配
C:全鏈接和交叉鏈接
全鏈接使用 full join,結果集的數量不肯定,字段數是兩個表字段數的總和,可是,依然會返回左右表中不知足鏈接條件的記錄,只是另外一邊表的字段則均爲 NULL。
交叉鏈接使用 cross join,產生的結果還是笛卡爾積,等價於內鏈接。
insert into sal values(4,2000); select * from sta full join sal on sta.sal_grande = sal.sal_grande;--返回 5 條記錄,但name爲張五的記錄中sal表的字段值均爲 NULL,工資等級爲 4 的記錄中 sta 表的字段均值爲 NULL
4,聯合查詢
鏈接查詢是把表的字段橫向組合到一塊兒,從而產生新的數據,而聯合查詢是把兩個表的記錄縱向組合到一塊兒,聯合查詢的要求是:兩個表的字段數量和對應字段的數據類型必須相同。SQL 經過 union 聯合兩張表。
1 select col1,col2,col3 from tableA 2 union 3 select col1,col2,col3 from tableB
請注意,union 聯合表後,默認只選取不一樣的記錄,若是你但願在聯合後的記錄中容許相同的數據存在,請使用 union all。