菜鳥拙見,望請糾正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)。
![](http://static.javashuo.com/static/loading.gif)
日期和時間類型
![](http://static.javashuo.com/static/loading.gif)
字符串類型
有 4 種 TEXT 類型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。對應的這 4 種 BLOB 類型,可存儲的最大長度不一樣,可根據實際狀況選擇。
![](http://static.javashuo.com/static/loading.gif)
3:定義實體關係的原則
當定義一個實體與其餘實體之間的關係時,須要考量以下:
牽涉到的實體 :識別出關系所涉及的全部實體。
全部權: 考慮一個實體「擁有」另外一個實體的狀況。
基數 :考量一個實體的實例和另外一個實體實例關聯的數量。
關係與表數量
描述1:1關係最少須要1張表。
描述1:n關係最少須要2張表。
描述n:n關係最少須要3張表。
範式將幫助咱們來保證數據的有效性和完整性。規範化的目的以下:
消滅重複數據。
避免編寫沒必要要的,用來使重複數據同步的代碼。
保持表的瘦身,以及減從一張表中讀取數據時須要進行的讀操做數量
最大化彙集索引的使用,從而能夠進行更優化的數據訪問和聯結。
減小每張表使用的索引數量,由於維護索引的成本很高。
規範化旨在——挑出複雜的實體,從中抽取出簡單的實體。這個過程一直持續下去,直到數據庫中每一個表都只表明一件事物,而且表中每一個描述的都是這件事物爲止。
關係模式:
候選鍵:若一個屬性集能惟一標識一個元組,又不含有多餘屬性,那麼這個屬性集稱爲候選鍵
![](http://static.javashuo.com/static/loading.gif)
主鍵:及設計者設計數據庫時選做元組標識的一個候選鍵
主屬性:包含在任一一個候選鍵的屬性稱爲主屬性
函數依賴:某個屬性集決定另外一個屬性集時,稱另外一屬性集依賴於該屬性集。
部分函數依賴:
範式:
第一範式:數據庫表的每一列都是不可分割的基本數據項,同一列不能有多個值。及每一列不可再分及知足第一範式。
第二範式:在第一範式的基礎上,每個非主屬性徹底依賴於主關鍵字。徹底依賴及不能存在僅依賴主關鍵字的一部分屬性。
![](http://static.javashuo.com/static/loading.gif)
第三範式:在第二範式的基礎上,每一個非主屬性都不傳遞依賴於候選鍵時,則爲第三範式。
傳遞依賴:若X→Y,Y→A,而且Y→X,A不是Y的子集,則稱A傳遞依賴於X。及主屬性不能經過一個以上的路徑走到非主屬性。
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
BC範式:
![](http://static.javashuo.com/static/loading.gif)
若是關係模式R的全部不平凡的,徹底的函數依賴的決定因素(左邊的屬性集)都是候選碼,則R€BCNF,即左邊的都是候選鍵(注意不是主屬性)
若是一個關係模式達到了第三範式,而且它只有一個候選鍵,或則他的候選鍵都是單屬性,那麼就達到了BCNF
三:SQL基礎語速記(MySQL)
1:操做符
![](http://static.javashuo.com/static/loading.gif)
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····