# 信息系統
現在需要開發一套信息系統, 記錄系里的學生、課程、 還有選課信息。比如
- 學生信息:[學號,姓名,性別,身份證號,入學日期,班級]
- 課程信息:[課程號,課程名,授課老師]
- 選課:[學號,課程號,成績]
可以使用三個獨立的文本文件來存儲這些信息,比如學生信息:

然后`程序`只需要讀寫這三個文件就可以了。
# 中間層的引入
到了期末,各個老師希望能進行一些統計的工作,比如哪些人不及格,某學科的平均分等等。實際上就是對文件進行`查詢`而已。如果每次都使用程序來進行操作,非常麻煩,而且不利于普及。
所以我們可以提供一個`中間層`,把文件層屏蔽掉,讓每個人都可以在這個中間層用簡單的方法進行查詢。我們把數據存放的結構叫`表`,每一列叫`列、字段、屬性`。
可以使用簡單的`SQL語句`就能查詢
```
SELECT 學號,姓名
FROM 學生信息
WHERE 入學日期='1991-9-1'
```
然后需要一個`解析器`,可以把`語句`轉換為內部對**文件的操作**。這樣還可以使用程序來調用`抽象層`來編程啊, 也不用直接操作文件了
使用這樣的`SQL語句`最大的好處是**用戶完全不用考慮物理層的那些文件的結構,只需要關注邏輯層的“表”就可以了。**

中間的邏輯層的另外的好處是可以**對物理層的文件存儲進行優化了**, 為了加快訪問速度, 可以**增加了索引、B+樹,緩存等手段。**
總結起來,中間層的好處在于:
- 對用戶屏蔽了底層邏輯,只需要通過SQL語句就可以進行操作了。
- 還可以對物理層的文件存儲進行優化,加快訪問速度。
# 并發訪問
之前的訪問都是單機版的,但是如果有若干的客戶端連入呢?可能會存在
- 兩個客戶端同時對一個文件進行修改,所以后修改的會完全覆蓋前人的修改。
- 兩個客戶端同時對一行數據進行修改,會出現數據不一致。
那么怎么辦呢?
- 基于文件的操作改變成基于行的操作, **每個人的修改只影響這一行**。 這樣縱然兩個人同時修改一個文件,只要不在同一行都沒毛病。
- 修改某行數據的時候,要先給這一行加`鎖`。也就是一個人修改的時候,不允許另一個人修改。
# 原子性問題
現在我們已經解決了`并發`寫的帶來的數據`不一致`的問題,那么還有沒有其他的風險點呢?`系統故障`。
比如電子系有1000元, 數學系有2000元
電子系給數學系轉賬200元, 系統先扣除了電子系的錢,現在余額只有800 ,此時系統崩潰了。
重啟以后,就發現電子系的余額是對的, 可是數學系還是2000元, 那200元丟了
所以轉賬的操作必須是`原子`的: **要么全部發生, 要么根本不發生。 **
可以把類似`轉賬`這樣的操作叫做“事務”, 但是怎么實現呢?`記錄日志 `
在做真正的操作之前,
- 先記錄日志:要修改哪一項,原來的值是什么,現在的值是什么
- 然后再修改
- 只有所有的操作都正確無誤寫入了`磁盤`,才會提交。否則就`回滾`
# 權限管理
一個沒有權限控制的系統是非常危險的, 尤其是隨意刪除。
先定義三大類權限:
1. 對**數據**操作的, 例如SELECT, UPDATE, INSERT等
2. 對**結構**操作的, 例如創建表,修改表,等
3. 做**管理**的, 例如備份數據, 創建用戶等
然后就可以把這些權限授予某個用戶了
```
GRANT SELECT on 財務表 to 系主任 #只能查詢。
GRANT CREATE_TABLE to 張老師:#可以創建表格
```
這個系統的中間層完全可以剝離出來,形成一個完整的軟件了,也就是`數據庫`

# 參考
- [小李的數據庫之旅(上)](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513312&idx=1&sn=f0c3e5623cc1042fa486c91c5d0ec6d4&scene=21#wechat_redirect)
- [小李的數據庫之旅(下)](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513315&idx=1&sn=768b9bc4a5dff80008eec5ca1f80d426&scene=21#wechat_redirect)