# 訪問數據庫
程序運行的時候,數據都是在內存中的。當程序終止的時候,通常都需要將數據保存到磁盤上,無論是保存到本地磁盤,還是通過網絡保存到服務器上,最終都會將數據寫入磁盤文件。
而如何定義數據的存儲格式就是一個大問題。如果我們自己來定義存儲格式,比如保存一個班級所有學生的成績單:
| 名字 | 成績 |
| --- | --- |
| Michael | 99 |
| Bob | 85 |
| Bart | 59 |
| Lisa | 87 |
你可以用一個文本文件保存,一行保存一個學生,用`,`隔開:
```
Michael,99
Bob,85
Bart,59
Lisa,87
```
你還可以用JSON格式保存,也是文本文件:
```
[
{"name":"Michael","score":99},
{"name":"Bob","score":85},
{"name":"Bart","score":59},
{"name":"Lisa","score":87}
]
```
你還可以定義各種保存格式,但是問題來了:
存儲和讀取需要自己實現,JSON還是標準,自己定義的格式就各式各樣了;
不能做快速查詢,只有把數據全部讀到內存中才能自己遍歷,但有時候數據的大小遠遠超過了內存(比如藍光電影,40GB的數據),根本無法全部讀入內存。
為了便于程序保存和讀取數據,而且,能直接通過條件快速查詢到指定的數據,就出現了數據庫(Database)這種專門用于集中存儲和查詢的軟件。
數據庫軟件誕生的歷史非常久遠,早在1950年數據庫就誕生了。經歷了網狀數據庫,層次數據庫,我們現在廣泛使用的關系數據庫是20世紀70年代基于關系模型的基礎上誕生的。
關系模型有一套復雜的數學理論,但是從概念上是十分容易理解的。舉個學校的例子:
假設某個XX省YY市ZZ縣第一實驗小學有3個年級,要表示出這3個年級,可以在Excel中用一個表格畫出來:

每個年級又有若干個班級,要把所有班級表示出來,可以在Excel中再畫一個表格:

這兩個表格有個映射關系,就是根據Grade_ID可以在班級表中查找到對應的所有班級:

也就是Grade表的每一行對應Class表的多行,在關系數據庫中,這種基于表(Table)的一對多的關系就是關系數據庫的基礎。
根據某個年級的ID就可以查找所有班級的行,這種查詢語句在關系數據庫中稱為SQL語句,可以寫成:
```
SELECT * FROM classes WHERE grade_id = '1';
```
結果也是一個表:
```
---------+----------+----------
grade_id | class_id | name
---------+----------+----------
1 | 11 | 一年級一班
---------+----------+----------
1 | 12 | 一年級二班
---------+----------+----------
1 | 13 | 一年級三班
---------+----------+----------
```
類似的,Class表的一行記錄又可以關聯到Student表的多行記錄:

由于本教程不涉及到關系數據庫的詳細內容,如果你想從零學習關系數據庫和基本的SQL語句,推薦Coursera課程:
英文:[https://www.coursera.org/course/db](https://www.coursera.org/course/db)
中文:[http://c.open.163.com/coursera/courseIntro.htm?cid=12](http://c.open.163.com/coursera/courseIntro.htm?cid=12)
## NoSQL
你也許還聽說過NoSQL數據庫,很多NoSQL宣傳其速度和規模遠遠超過關系數據庫,所以很多同學覺得有了NoSQL是否就不需要SQL了呢?千萬不要被他們忽悠了,連SQL都不明白怎么可能搞明白NoSQL呢?
## 數據庫類別
既然我們要使用關系數據庫,就必須選擇一個關系數據庫。目前廣泛使用的關系數據庫也就這么幾種:
付費的商用數據庫:
* Oracle,典型的高富帥;
* SQL Server,微軟自家產品,Windows定制專款;
* DB2,IBM的產品,聽起來挺高端;
* Sybase,曾經跟微軟是好基友,后來關系破裂,現在家境慘淡。
這些數據庫都是不開源而且付費的,最大的好處是花了錢出了問題可以找廠家解決,不過在Web的世界里,常常需要部署成千上萬的數據庫服務器,當然不能把大把大把的銀子扔給廠家,所以,無論是Google、Facebook,還是國內的BAT,無一例外都選擇了免費的開源數據庫:
* MySQL,大家都在用,一般錯不了;
* PostgreSQL,學術氣息有點重,其實挺不錯,但知名度沒有MySQL高;
* sqlite,嵌入式數據庫,適合桌面和移動應用。
作為Python開發工程師,選擇哪個免費數據庫呢?當然是MySQL。因為MySQL普及率最高,出了錯,可以很容易找到解決方法。而且,圍繞MySQL有一大堆監控和運維的工具,安裝和使用很方便。
為了能繼續后面的學習,你需要從MySQL官方網站下載并安裝[MySQL Community Server 5.6](http://dev.mysql.com/downloads/mysql/),這個版本是免費的,其他高級版本是要收錢的(請放心,收錢的功能我們用不上)。
- JavaScript教程
- JavaScript簡介
- 快速入門
- 基本語法
- 數據類型和變量
- 字符串
- 數組
- 對象
- 條件判斷
- 循環
- Map和Set
- iterable
- 函數
- 函數定義和調用
- 變量作用域
- 方法
- 高階函數
- map/reduce
- filter
- sort
- 閉包
- 箭頭函數
- generator
- 標準對象
- Date
- RegExp
- JSON
- 面向對象編程
- 創建對象
- 原型繼承
- 瀏覽器
- 瀏覽器對象
- 操作DOM
- 更新DOM
- 插入DOM
- 刪除DOM
- 操作表單
- 操作文件
- AJAX
- Promise
- Canvas
- jQuery
- 選擇器
- 層級選擇器
- 查找和過濾
- 操作DOM
- 修改DOM結構
- 事件
- 動畫
- 擴展
- underscore
- Collections
- Arrays
- Functions
- Objects
- Chaining
- Node.js
- 安裝Node.js和npm
- 第一個Node程序
- 模塊
- 基本模塊
- fs
- stream
- http
- buffer
- Web開發
- koa
- mysql
- swig
- 自動化工具
- 期末總結
- Python 2.7教程
- Python簡介
- 安裝Python
- Python解釋器
- 第一個Python程序
- 使用文本編輯器
- 輸入和輸出
- Python基礎
- 數據類型和變量
- 字符串和編碼
- 使用list和tuple
- 條件判斷和循環
- 使用dict和set
- 函數
- 調用函數
- 定義函數
- 函數的參數
- 遞歸函數
- 高級特性
- 切片
- 迭代
- 列表生成式
- 生成器
- 函數式編程
- 高階函數
- map/reduce
- filter
- sorted
- 返回函數
- 匿名函數
- 裝飾器
- 偏函數
- 模塊
- 使用模塊
- 安裝第三方模塊
- 使用__future__
- 面向對象編程
- 類和實例
- 訪問限制
- 繼承和多態
- 獲取對象信息
- 面向對象高級編程
- 使用__slots__
- 使用@property
- 多重繼承
- 定制類
- 使用元類
- 錯誤、調試和測試
- 錯誤處理
- 調試
- 單元測試
- 文檔測試
- IO編程
- 文件讀寫
- 操作文件和目錄
- 序列化
- 進程和線程
- 多進程
- 多線程
- ThreadLocal
- 進程 vs. 線程
- 分布式進程
- 正則表達式
- 常用內建模塊
- collections
- base64
- struct
- hashlib
- itertools
- XML
- HTMLParser
- 常用第三方模塊
- PIL
- 圖形界面
- 網絡編程
- TCP/IP簡介
- TCP編程
- UDP編程
- 電子郵件
- SMTP發送郵件
- POP3收取郵件
- 訪問數據庫
- 使用SQLite
- 使用MySQL
- 使用SQLAlchemy
- Web開發
- HTTP協議簡介
- HTML簡介
- WSGI接口
- 使用Web框架
- 使用模板
- 協程
- gevent
- 實戰
- Day 1 - 搭建開發環境
- Day 2 - 編寫數據庫模塊
- Day 3 - 編寫ORM
- Day 4 - 編寫Model
- Day 5 - 編寫Web框架
- Day 6 - 添加配置文件
- Day 7 - 編寫MVC
- Day 8 - 構建前端
- Day 9 - 編寫API
- Day 10 - 用戶注冊和登錄
- Day 11 - 編寫日志創建頁
- Day 12 - 編寫日志列表頁
- Day 13 - 提升開發效率
- Day 14 - 完成Web App
- Day 15 - 部署Web App
- Day 16 - 編寫移動App
- 期末總結
- Python3教程
- Python簡介
- 安裝Python
- Python解釋器
- 第一個Python程序
- 使用文本編輯器
- Python代碼運行助手
- 輸入和輸出
- Python基礎
- 數據類型和變量
- 字符串和編碼
- 使用list和tuple
- 條件判斷
- 循環
- 使用dict和set
- 函數
- 調用函數
- 定義函數
- 函數的參數
- 遞歸函數
- 高級特性
- 切片
- 迭代
- 列表生成式
- 生成器
- 迭代器
- 函數式編程
- 高階函數
- map/reduce
- filter
- sorted
- 返回函數
- 匿名函數
- 裝飾器
- 偏函數
- 模塊
- 使用模塊
- 安裝第三方模塊
- 面向對象編程
- 類和實例
- 訪問限制
- 繼承和多態
- 獲取對象信息
- 實例屬性和類屬性
- 面向對象高級編程
- 使用__slots__
- 使用@property
- 多重繼承
- 定制類
- 使用枚舉類
- 使用元類
- 錯誤、調試和測試
- 錯誤處理
- 調試
- 單元測試
- 文檔測試
- IO編程
- 文件讀寫
- StringIO和BytesIO
- 操作文件和目錄
- 序列化
- 進程和線程
- 多進程
- 多線程
- ThreadLocal
- 進程 vs. 線程
- 分布式進程
- 正則表達式
- 常用內建模塊
- datetime
- collections
- base64
- struct
- hashlib
- itertools
- XML
- HTMLParser
- urllib
- 常用第三方模塊
- PIL
- virtualenv
- 圖形界面
- 網絡編程
- TCP/IP簡介
- TCP編程
- UDP編程
- 電子郵件
- SMTP發送郵件
- POP3收取郵件
- 訪問數據庫
- 使用SQLite
- 使用MySQL
- 使用SQLAlchemy
- Web開發
- HTTP協議簡介
- HTML簡介
- WSGI接口
- 使用Web框架
- 使用模板
- 異步IO
- 協程
- asyncio
- async/await
- aiohttp
- 實戰
- Day 1 - 搭建開發環境
- Day 2 - 編寫Web App骨架
- Day 3 - 編寫ORM
- Day 4 - 編寫Model
- Day 5 - 編寫Web框架
- Day 6 - 編寫配置文件
- Day 7 - 編寫MVC
- Day 8 - 構建前端
- Day 9 - 編寫API
- Day 10 - 用戶注冊和登錄
- Day 11 - 編寫日志創建頁
- Day 12 - 編寫日志列表頁
- Day 13 - 提升開發效率
- Day 14 - 完成Web App
- Day 15 - 部署Web App
- Day 16 - 編寫移動App
- FAQ
- 期末總結
- Git教程
- Git簡介
- Git的誕生
- 集中式vs分布式
- 安裝Git
- 創建版本庫
- 時光機穿梭
- 版本回退
- 工作區和暫存區
- 管理修改
- 撤銷修改
- 刪除文件
- 遠程倉庫
- 添加遠程庫
- 從遠程庫克隆
- 分支管理
- 創建與合并分支
- 解決沖突
- 分支管理策略
- Bug分支
- Feature分支
- 多人協作
- 標簽管理
- 創建標簽
- 操作標簽
- 使用GitHub
- 自定義Git
- 忽略特殊文件
- 配置別名
- 搭建Git服務器
- 期末總結