結項總結
最近項目完結,有點閑暇時間,來總結總結項目中用到的之前沒用過的sql語句和數據庫知識。下面用自己的理解來記錄一下~
- 范式
第一范式:要求我們字段要划分到最小單元,即表頭不能有合並單元格項
第二范式:要求數據庫設計有主鍵
第三范式:要求外鍵字段不能有除了引用表主鍵以外的字段
- 聚合函數
sum、count、ave等等。比如學成成績表中,我們要計算成績在60-80分之間的總分和人數,可以這樣寫
select count(case when score >= 60 and score <= 80 then 1 else null end) as stuNum ,sum(case when score >= 60 and score <=80 then score else 0 end) as sumScore from 學生成績表
由於項目數據處理部分數據比較多,這樣的sql在代碼中成群結隊,之前沒想到這么多使用innerjoin來寫的,后來一一改成了這種聚合函數的方式,雖說不見得效率提高了,但是代碼確實比較好看了。
上面的sql是求總表的,如果需求是求各個班級的分數分布情況,比如統計每個班的及格人數,所有的班級成績存在一張表里。那么可以這樣寫
select class as 班級 ,count(case when score >= 60 and score <= 80 then 1 else null end) as stuNum ,sum(case when score >= 60 and score <=80 then score else 0 end) as sumScore from 學生成績表 group by class -- 班級
之前做過一個驗證碼的生成接口,需求是這樣的:每一場考試對應一張考試表,考試表中有一個叫驗證碼的字段,用戶添加考試的時候后台自動生成一個考試驗證碼,並存入數據庫。
要求:1、驗證碼由數字和小寫字母組成,長度為6;2、生成的驗證碼為數據庫中不存在的。
就這兩個要求,第一次實現的時候使用一個死循環,生成一個驗證碼然后去后台查詢是否有存在的,若有,則丟棄然后重新生成。如果沒有就break然后返回。
這個解決方案被老大看到了一頓教育,說咱們系統里面一定不能再循環里面寫查詢,更何況你這個還是死循環,回去改。
於是回去換了一個思路,將數據庫里面考試表中所有的驗證碼查詢出來,然后存到一個list里面,然后開始死循環,生成一個驗證碼,然后用contain函數判斷列表里面是否存在,若存在則丟棄,若不存在則break並且返回。
后來數據達到兩千多的時候感覺就有點卡,不知道2000就卡是不是數據庫的原因,那時候用的是sqlserver,於是考慮換思路。換思路的方向改成在數據庫內部吧所有驗證碼拼接成一個字符串,用逗號分隔,然后返回一個超長字符串,然后生成驗證碼去這個String中判斷是否存在。好了,順利完成,恩,那個sql這樣寫的:
目標數據庫是SQL Server,別的數據庫不知道是否支持OUTER APPLY關鍵字。
原理就是最內層的那個select ... for xml auto,這會生成一個字段名=值這種類型的xml格式字符串,然后把其中的數據庫名、字段名和多余的負號去掉就只剩下值了,然后替換的時候保留逗號,一個逗號分隔的超長字符串就出來了。
有一個問題是沒測試這個字符串會不會因為太長而出問題~不過我已經離開那家公司了,回頭有興趣再測一測吧。