關係型數據庫知識總結

菜鳥拙見,望請糾正html

一:關係型數據庫的設計階段

1:規劃階段:肯定是否須要使用數據庫,使用哪一種類型的數據庫,使用哪一個數據庫產品。mysql

2:概念階段:概念階段的主要工做是收集並分析需求。linux

識別需求,主要是識別數據實體和業務規則。該階段將參考或產出多種文檔,好比「用例圖」,「數據流圖」以及其餘一些項目文檔。該階段結束要能夠回答以下問題。sql

須要哪些數據?數據該被怎樣使用?哪些規則控制着數據的使用?誰會使用何種數據?客戶想在覈心功能界面或者報表上看到哪些內容?數據如今在哪裏?數據是否與其餘系統有交互、集成或同步?主題數據有哪些?核心數據價值幾何,對可靠性的要求程度?數據庫

3:邏輯階段:邏輯階段的主要工做是繪製E-R圖,或者說是建模。E-R圖以描述實體間的關係。還需考慮屬性的域(值類型、範圍、約束)。函數

4:實現階段:實現階段主要針對選擇的RDBMS定義E-R圖對應的表,考慮屬性類型和範圍以及約束。oop

5:物理階段:在實際物理設備商部署數據庫並測試和調優。post

二:設計原則與規範

1:命名規範:

表——「模塊名_表名」。表名最好不要用複數,不要過長。測試

存儲過程——使用「proc_」前綴。優化

視圖——使用「view_」前綴。

觸發器——使用「trig_」前綴。

2:選擇數據類型

數值類型:

嚴格數值數據類型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似數值數據類型(FLOAT、REAL和DOUBLE PRECISION)。

日期和時間類型

字符串類型

有 4 種 TEXT 類型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。對應的這 4 種 BLOB 類型,可存儲的最大長度不一樣,可根據實際狀況選擇。

3:定義實體關係的原則

當定義一個實體與其餘實體之間的關係時,須要考量以下:

牽涉到的實體 :識別出關系所涉及的全部實體。

全部權: 考慮一個實體「擁有」另外一個實體的狀況。

基數 :考量一個實體的實例和另外一個實體實例關聯的數量。

關係與表數量

描述1:1關係最少須要1張表。

描述1:n關係最少須要2張表。 

描述n:n關係最少須要3張表。

範式將幫助咱們來保證數據的有效性和完整性。規範化的目的以下:

消滅重複數據。

避免編寫沒必要要的,用來使重複數據同步的代碼。

保持表的瘦身,以及減從一張表中讀取數據時須要進行的讀操做數量

最大化彙集索引的使用,從而能夠進行更優化的數據訪問和聯結。

減小每張表使用的索引數量,由於維護索引的成本很高。

規範化旨在——挑出複雜的實體,從中抽取出簡單的實體。這個過程一直持續下去,直到數據庫中每一個表都只表明一件事物,而且表中每一個描述的都是這件事物爲止。

關係模式:

候選鍵:若一個屬性集能惟一標識一個元組,又不含有多餘屬性,那麼這個屬性集稱爲候選鍵

主鍵:及設計者設計數據庫時選做元組標識的一個候選鍵

主屬性:包含在任一一個候選鍵的屬性稱爲主屬性

函數依賴:某個屬性集決定另外一個屬性集時,稱另外一屬性集依賴於該屬性集。

部分函數依賴:

範式:

第一範式:數據庫表的每一列都是不可分割的基本數據項,同一列不能有多個值。及每一列不可再分及知足第一範式。

第二範式:在第一範式的基礎上,每個非主屬性徹底依賴於主關鍵字。徹底依賴及不能存在僅依賴主關鍵字的一部分屬性。

第三範式:在第二範式的基礎上,每一個非主屬性都不傳遞依賴於候選鍵時,則爲第三範式。

傳遞依賴:若X→Y,Y→A,而且Y→X,A不是Y的子集,則稱A傳遞依賴於X。及主屬性不能經過一個以上的路徑走到非主屬性。

 

BC範式:

 

若是關係模式R的全部不平凡的,徹底的函數依賴的決定因素(左邊的屬性集)都是候選碼,則R€BCNF,即左邊的都是候選鍵(注意不是主屬性)

若是一個關係模式達到了第三範式,而且它只有一個候選鍵,或則他的候選鍵都是單屬性,那麼就達到了BCNF

三:SQL基礎語速記(MySQL)

1:操做符

2:經常使用字符串函數

3:經常使用數值函數

4:經常使用日期時間函數

5:分組聚合函數

四:SQL語句速記(MYSQL)

1:增(insert)

基本格式:

insert [into] <表名> (列名1,列名2,列名3,......)  values (值1,值2,值3,......);

1):插入一行時,要求必須對該行全部的列賦值。可是賦值方式能夠是顯式賦值(及將列列出,values 賦予 null )和隱式賦值(及不寫出該列,也不寫該列的值)

例如:顯式賦值 :insert into <表名> (列名1,列名2,列名3)  values (值1,null,值3);

    隱式賦值:insert into <表名> (列名1,列名3......)  values (值1,值3,......);

2):從其餘表中複製數據:

例如:insert into <表1> select (值1,值2,值3);

2:刪(delect)

基本格式:

delete from <表名> where <條件表達式>;

刪除符合條件表達式的行記錄

1)注意:不能在delete和from中間指定列名,由於記錄要刪,老是按照行來刪除的,不存在刪除一行記錄的某幾列的值的狀況。

2)帶查詢的刪除

例如:

DELETE FROM <表1>

  WHERE joined >

  (SELECT avg(joined) FROM <表2> WHERE town = 'Stratford');

注意:在WHERE子句的子查詢中,不容許訪問要刪除行的表

3:刪除4個最高的罰款

DELETE FROM penalties

  ORDER BY amount DESC,playerno ASC

  LIMIT 4;

3:改(update)

 基本格式

update <表名> set <列名> = <值或值的表達式> where <條件表達式>

 例1:把全部罰款增長5%

UPDATE penalties  SET amount = amount*1.05; 

例2:把住在S 的球員的獲勝局數設爲0

UPDATE matches

  SET won = 0

  WHERE playerno IN

  (SELECT playerno FROM players WHERE town='S');

例3:多表查詢

UPDATE matches m,teams t

  SET m.won = 0,t.playerno = 112

WHERE t.teamno = m.teamno

AND t.division = 'first';

4:查(select)

基礎關鍵字

from:來自某張表或則幾張表

join:添加某張表

on :錶鏈接查詢,每關聯一個表就須要加上對應的on條件

group by:分組

mysql> select salary,count(*) from salary_tab
    -> where salary>=2000
    -> group by salary;   
+---------+----------+
| salary  | count(*) |
+---------+----------+
| 2000.00 |        1 |
| 3000.00 |        1 |
+---------+----------+

having :聚合條件過濾

order by :排序 ,desc降序,asc升序,默認升序:如:

select * from temp order by id desc;

distinct:去掉重複數據 如: select distinct num from t2;

as :列別名

concat:字符串鏈接,如查詢地址

concat函數,字符串鏈接

concat_ws函數,指定分隔符的字符串鏈接

mysql> select id,concat_ws(':',First,Last) "Full Name" from t1;

 

between v1 and v2:v1和v2之間

in :多個條件查詢,相似於or  如:

select * from temp where id in (1, 2, 3);

like:模糊查詢,如:

select * from temp where name like ‘%k%’;

limit:從結果集中選取最前面或最後面的幾行,一般與order by配合

limit  <獲取的行數> [OFFSET <跳過的行數>]

limit [<跳過的行數>,] <獲取的行數> 

mysql> select playerno,name from players order by playerno asc limit 3,5; 
mysql> select playerno,name from players order by playerno asc limit 5 offset 3;
解析:跳過前面的3行,從第4行開始取,取5行

 

count:統計行的數量

select count(*) from salary_tab

max和min函數

select min(salary) from salary_tab;

sum和avg函數

select avg(salary) from salary_tab;

多表連接查詢

1:內鏈接 inner join

只返回兩張表中全部知足鏈接條件的行,即便用比較運算符根據每一個表中共有的列的值匹配兩個表中的行。(inner關鍵字是可省略的)

①傳統的鏈接寫法:

  在FROM子句中列出全部要鏈接的表的名字(進行表別名),以逗號分隔;

  鏈接條件寫在WHERE子句中;

注意:一旦給表定義了別名,那麼原始的表名就不能在出如今該語句的其它子句中

mysql> select s.sname,c.cname,t.tname,x.xuefen
    -> from stu s,tea t,course c,xuanke x
    -> where s.sid=x.sid and t.tid=x.tid and c.cid=x.cid;
+--------+--------+-----------+--------+
| sname  | cname  | tname     | xuefen |
+--------+--------+-----------+--------+
| 張三    | linux  | 馮老師     |      4 |
| 李四    | linux  | 馮老師     |      2 |
| 張三    | mysql  | 相老師     |      2 |
| 李四    | mysql  | 相老師     |      2 |
| 張三    | hadoop | 相老師     |      6 |
| 李四    | hadoop | 相老師     |      2 |
+--------+--------+-----------+--------+
6 rows in set (0.08 sec)

 

②使用on子句(經常使用):

mysql> select s.sname,t.tname,c.cname,x.xuefen
    -> from stu s
    -> join xuanke x
    ->   on s.sid=x.sid
    -> join tea t
    ->   on x.tid=t.tid
    -> join course c
    ->   on c.cid=x.cid;

結果如上……

表之間的關係以JOIN指定,ON的條件與WHERE條件相同。

③使用using子句

mysql> select s.sname,t.tname,c.cname,x.xuefen
    -> from stu s
    -> join xuanke x
    ->   using(sid)
    -> join tea t
    ->   using(tid)
    -> join course c
   ->   using(cid);

結果如上……

表之間的關係以join指定,using(鏈接列)進行鏈接匹配,相似於on。(相對用的會比較少) 

2:外連接 outer join

使用外鏈接不但返回符合鏈接和查詢條件的數據行,還返回不符合條件的一些行。

在MySQL數據庫中外鏈接分兩類(不支持全外鏈接):

  左外鏈接、右外鏈接。(outer關鍵字可省略)。

共同點:都返回符合鏈接條件和查詢條件(即:內鏈接)的數據行

不一樣點:

  ①左外鏈接還返回左表中不符合鏈接條件,但符合查詢條件的數據行。(所謂左表,就是寫在left join關鍵字左邊的表)

  ②右外鏈接還返回右表中不符合鏈接條件,但符合查詢條件的數據行。(所謂右表,就是寫在right join關鍵字右邊的表)

mysql> select s.sname,x.xuefen
    -> from stu s
    -> left join xuanke x
    -> on s.sid=x.sid;
+--------+--------+
| sname  | xuefen |
+--------+--------+
| 張三   |      2  |
| 張三   |      4  |
| 張三   |      6  |
| 李四   |      2  |
| 李四   |      2  |
| 李四   |      2  |
| 王五   |   NULL  |
+--------+--------+
7 rows in set (0.00 sec)

解析:stu表是左表,xuanke表是右表:left join是左鏈接,stu表中」王五」沒有選課,在xueke表中沒有數據行,不符合鏈接條件,返回符合查詢條件的數據行,因此xuefen爲null。

mysql> select s.sname,x.xuefen
    -> from xuanke x
    -> right join stu s
    -> on x.sid=s.sid;

結果如上(用的是右鏈接的方式)

 

 


給鏈接查詢附加條件:

  一、寫在WHERE子句中

  二、使用AND和鏈接條件寫在一塊兒

可是:

  對於內鏈接,兩種寫法結果相同;

  對於外鏈接,兩種寫法結果不一樣。

mysql> select s.sname,x.xuefen
    -> from stu s
    -> left join xuanke x
    -> on x.sid=s.sid
    ->   where sname='張三';
+--------+--------+
| sname  | xuefen |
+--------+--------+
| 張三    |      2 |
| 張三    |      4 |
| 張三    |      6 |
+--------+--------+
3 rows in set (0.01 sec)

mysql> select s.sname,x.xuefen                                                                 
    -> from (select * from stu where sname='張三') s
    -> left join xuanke x
    -> on x.sid=s.sid;
+--------+--------+
| sname  | xuefen |
+--------+--------+
| 張三    |      2 |
| 張三    |      4 |
| 張三    |      6 |
+--------+--------+
3 rows in set (0.00 sec)

①先鏈接後過濾

  select ……from ……

  left join ……

  on 鏈接條件

    where 過濾條件;

②先過濾後鏈接

  select ……from (select ……from ……where 過濾條件)

  left join ……

  on 鏈接條件;

 

3:交叉連接——笛卡爾積

由於沒有鏈接條件,所進行的表與表間的全部行的鏈接。

特色:

  ①鏈接查詢沒有寫任何鏈接條件

  ②結果集中的總行數就是兩張表中總行數的乘積(笛卡爾積)

注意:在實際中,應該要避免產生笛卡爾積的鏈接,特別是對於大表

mysql> select * from stu,tea,course,xuanke;
  ……
  ……
108 rows in set (0.00 sec)

 

如果想專門產生笛卡爾積,可使用交叉鏈接

mysql> select *
    -> from stu
    -> crosss join tea;
+------+--------+---------+------+-----------+---------+
| sid  | sname  | sphonum | tid  | tname     | tphonum |
+------+--------+---------+------+-----------+---------+
|    1 | 張三    |     110 | 1113 | 相老師     |    1111 |
|    1 | 張三    |     110 | 1114 | 馮老師     |    1112 |
|    2 | 李四    |     120 | 1113 | 相老師     |    1111 |
|    2 | 李四    |     120 | 1114 | 馮老師     |    1112 |
|    3 | 王五    |     130 | 1113 | 相老師     |    1111 |
|    3 | 王五    |     130 | 1114 | 馮老師     |    1112 |
+------+--------+---------+------+-----------+---------+
6 rows in set (0.00 sec)

 

OVER····

相關文章
相關標籤/搜索