亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄 搜索
目錄 前言 1. 一般信息 1.1. 關(guān)于本手冊 1.2. 本手冊采用的慣例 1.3. MySQL AB概述 1.4. MySQL數(shù)據(jù)庫管理系統(tǒng)概述 1.4.1. MySQL的歷史 1.4.2. MySQL的的主要特性 1.4.3. MySQL穩(wěn)定性 1.4.4. MySQL表最大能達到多少 1.4.5. 2000年兼容性 1.5. MaxDB數(shù)據(jù)庫管理系統(tǒng)概述 1.5.1. 什么是MaxDB? 1.5.2. MaxDB的歷史 1.5.3. MaxDB的特性 1.5.4. 許可和支持 1.5.5. MaxDB和MySQL之間的特性差異 1.5.6. MaxDB和MySQL之間的協(xié)同性 1.5.7. 與MaxDB有關(guān)的鏈接 1.6. MySQL發(fā)展大事記 1.6.1. MySQL 5.1的新特性 1.7. MySQL信息源 1.7.1. MySQL郵件列表 1.7.2. IRC(在線聊天系統(tǒng))上的MySQL社區(qū)支持 1.7.3. MySQL論壇上的MySQL社區(qū)支持 1.8. MySQL標準的兼容性 1.8.1. MySQL遵從的標準是什么 1.8.2. 選擇SQL模式 1.8.3. 在ANSI模式下運行MySQL 1.8.4. MySQL對標準SQL的擴展 1.8.5. MySQL與標準SQL的差別 1.8.6. MySQL處理約束的方式 2. 安裝MySQL 2.1. 一般安裝問題 2.1.1. MySQL支持的操作系統(tǒng) 2.1.2. 選擇要安裝的MySQL分發(fā)版 2.1.3. 怎樣獲得MySQL 2.1.4. 通過MD5校驗和或GnuPG驗證軟件包的完整性 2.1.5. 安裝布局 2.2. 使用二進制分發(fā)版的標準MySQL安裝 2.3. 在Windows上安裝MySQL 2.3.1. Windows系統(tǒng)要求 2.3.2. 選擇安裝軟件包 2.3.3. 用自動安裝器安裝MySQL 2.3.4. 使用MySQL安裝向?qū)?/a> 2.3.5. 使用配置向?qū)?/a> 2.3.6. 通過非安裝Zip文件安裝MySQL 2.3.7. 提取安裝檔案文件 2.3.8. 創(chuàng)建選項文件 2.3.9. 選擇MySQL服務器類型 2.3.10. 首次啟動服務器 2.3.11. 從Windows命令行啟動MySQL 2.3.12. 以Windows服務方式啟動MySQL 2.3.13. 測試MySQL安裝 2.3.14. 在Windows環(huán)境下對MySQL安裝的故障診斷與排除 2.3.15. 在Windows下升級MySQL 2.3.16. Windows版MySQL同Unix版MySQL對比 2.4. 在Linux下安裝MySQL 2.5.在Mac OS X中安裝MySQL 2.6. 在NetWare中安裝MySQL 2.7. 在其它類Unix系統(tǒng)中安裝MySQL 2.8. 使用源碼分發(fā)版安裝MySQL 2.8.1. 源碼安裝概述 2.8.2. 典型配置選項 2.8.3. 從開發(fā)源碼樹安裝 2.8.4. 處理MySQL編譯問題 2.8.5. MIT-pthreads注意事項 2.8.6. 在Windows下從源碼安裝MySQL 2.8.7. 在Windows下編譯MySQL客戶端 2.9. 安裝后的設置和測試 2.9.1. Windows下安裝后的過程 2.9.2. Unix下安裝后的過程 2.9.3. 使初始MySQL賬戶安全 2.10. 升級MySQL 2.10.1. 從5.0版升級 2.10.2. 升級授權(quán)表 2.10.3. 將MySQL數(shù)據(jù)庫拷貝到另一臺機器 2.11. 降級MySQL 2.12. 具體操作系統(tǒng)相關(guān)的注意事項 2.12.1. Linux注意事項 2.12.2. Mac OS X注意事項 2.12.3. Solaris注意事項 2.12.4. BSD注意事項 2.12.5. 其它Unix注意事項 2.12.6. OS/2注意事項 2.13. Perl安裝注意事項 2.13.1. 在Unix中安裝Perl 2.13.2. 在Windows下安裝ActiveState Perl 2.13.3. 使用Perl DBI/DBD接口的問題 3. 教程 3.1. 連接與斷開服務器 3.2. 輸入查詢 3.3. 創(chuàng)建并使用數(shù)據(jù)庫 3.3.1. 創(chuàng)建并選擇數(shù)據(jù)庫 3.3.2. 創(chuàng)建表 3.3.3. 將數(shù)據(jù)裝入表中 3.3.4. 從表檢索信息 3.4. 獲得數(shù)據(jù)庫和表的信息 NoName 3.6. 常用查詢的例子 3.6.1. 列的最大值 3.6.2. 擁有某個列的最大值的行 3.6.3. 列的最大值:按組 3.6.4. 擁有某個字段的組間最大值的行 3.6.5. 使用用戶變量 3.6.6. 使用外鍵 3.6.7. 根據(jù)兩個鍵搜索 3.6.8. 根據(jù)天計算訪問量 3.6.9. 使用AUTO_INCREMENT 3.7. 孿生項目的查詢 3.7.1. 查找所有未分發(fā)的孿生項 3.7.2. 顯示孿生對狀態(tài)的表 3.8. 與Apache一起使用MySQL 4. MySQL程序概述 4.1. MySQL程序概述 4.2. 調(diào)用MySQL程序 4.3. 指定程序選項 4.3.1. 在命令行上使用選項 4.3.2. 使用選項文件 4.3.3. 用環(huán)境變量指定選項 4.3.4. 使用選項設置程序變量 5. 數(shù)據(jù)庫管理 5.1. MySQL服務器和服務器啟動腳本 5.1.1. 服務器端腳本和實用工具概述 5.1.2. mysqld-max擴展MySQL服務器 5.1.3. mysqld_safe:MySQL服務器啟動腳本 5.1.4. mysql.server:MySQL服務器啟動腳本 5.1.5. mysqld_multi:管理多個MySQL服務器的程序 5.2. mysqlmanager:MySQL實例管理器 5.2.1. 用MySQL實例管理器啟動MySQL服務器 5.2.2. 連接到MySQL實例管理器并創(chuàng)建用戶賬戶 5.2.3. MySQL實例管理器命令行選項 5.2.4. MySQL實例管理器配置文件 5.2.5. MySQL實例管理器識別的命令 5.3. mysqld:MySQL服務器 5.3.1. mysqld命令行選項 5.3.2. SQL服務器模式 5.3.3. 服務器系統(tǒng)變量 5.3.4. 服務器狀態(tài)變量 5.4. mysql_fix_privilege_tables:升級MySQL系統(tǒng)表 5.5. MySQL服務器關(guān)機進程 5.6. 一般安全問題 5.6.1. 通用安全指南 5.6.2. 使MySQL在攻擊者面前保持安全 5.6.3. Mysqld安全相關(guān)啟動選項 5.6.4. LOAD DATA LOCAL安全問題 5.7. MySQL訪問權(quán)限系統(tǒng) 5.7.1. 權(quán)限系統(tǒng)的作用 5.7.2. 權(quán)限系統(tǒng)工作原理 5.7.3. MySQL提供的權(quán)限 5.7.4. 與MySQL服務器連接 5.7.5. 訪問控制 5.7.6. 訪問控制 5.7.7. 權(quán)限更改何時生效 5.7.8. 拒絕訪問錯誤的原因 5.7.9. MySQL 4.1中的密碼哈希處理 5.8. MySQL用戶賬戶管理 5.8.1. MySQL用戶名和密碼 5.8.2. 向MySQL增加新用戶賬戶 5.8.3. 從MySQL刪除用戶賬戶 5.8.4. 限制賬戶資源 5.8.5. 設置賬戶密碼 5.8.6. 使你的密碼安全 5.8.7. 使用安全連接 5.9. 備份與恢復 5.9.1. 數(shù)據(jù)庫備份 5.9.2. 示例用備份與恢復策略 5.9.3. 自動恢復 5.9.4. 表維護和崩潰恢復 5.9.5. myisamchk:MyISAM表維護實用工具 5.9.6. 建立表維護計劃 5.9.7. 獲取關(guān)于表的信息 5.10. MySQL本地化和國際應用 5.10.1. 數(shù)據(jù)和排序用字符集 5.10.2. 設置錯誤消息語言 5.10.3. 添加新的字符集 5.10.4. 字符定義數(shù)組 5.10.5. 字符串比較支持 5.10.6. 多字節(jié)字符支持 5.10.7. 字符集問題 5.10.8. MySQL服務器時區(qū)支持 5.11. MySQL日志文件 5.11.1. 錯誤日志 5.11.2. 通用查詢?nèi)罩?/a> 5.11.3. 二進制日志 5.11.4. 慢速查詢?nèi)罩?/a> 5.11.5. 日志文件維護 5.12. 在同一臺機器上運行多個MySQL服務器 5.12.1. 在Windows下運行多個服務器 5.12.2. 在Unix中運行多個服務器 5.12.3. 在多服務器環(huán)境中使用客戶端程序 5.13. MySQL查詢高速緩沖 5.13.1. 查詢高速緩沖如何工作 5.13.2. 查詢高速緩沖SELECT選項 5.13.3. 查詢高速緩沖配置 5.13.4. 查詢高速緩沖狀態(tài)和維護 6. MySQL中的復制 6.1. 復制介紹 6.2. 復制實施概述 6.3. 復制實施細節(jié) 6.3.1. 復制主線程狀態(tài) 6.3.2. 復制從I/O線程狀態(tài) 6.3.3. 復制從SQL線程狀態(tài) 6.3.4. 復制傳遞和狀態(tài)文件 6.4. 如何設置復制 6.5. 不同MySQL版本之間的復制兼容性 6.6. 升級復制設置 6.6.1. 將復制升級到5.0版 6.7. 復制特性和已知問題 6.8. 復制啟動選項 6.9. 復制FAQ 6.10. 復制故障診斷與排除 6.11. 通報復制缺陷 6.12. 多服務器復制中的Auto-Increment 7. 優(yōu)化 7.1. 優(yōu)化概述 7.1.1. MySQL設計局限與折衷 7.1.2. 為可移植性設計應用程序 7.1.3. 我們已將MySQL用在何處? 7.1.4. MySQL基準套件 7.1.5. 使用自己的基準 7.2. 優(yōu)化SELECT語句和其它查詢 7.2.1. EXPLAIN語法(獲取SELECT相關(guān)信息) 7.2.2. 估計查詢性能 7.2.3. SELECT查詢的速度 7.2.4. MySQL怎樣優(yōu)化WHERE子句 7.2.5. 范圍優(yōu)化 7.2.6. 索引合并優(yōu)化 7.2.7. MySQL如何優(yōu)化IS NULL 7.2.8. MySQL如何優(yōu)化DISTINCT 7.2.9. MySQL如何優(yōu)化LEFT JOIN和RIGHT JOIN 7.2.10. MySQL如何優(yōu)化嵌套Join 7.2.11. MySQL如何簡化外部聯(lián)合 7.2.12. MySQL如何優(yōu)化ORDER BY 7.2.13. MySQL如何優(yōu)化GROUP BY 7.2.14. MySQL如何優(yōu)化LIMIT 7.2.15. 如何避免表掃描 7.2.16. INSERT語句的速度 7.2.17. UPDATE語句的速度 7.2.18. DELETE語句的速度 7.2.19. 其它優(yōu)化技巧 7.3. 鎖定事宜 7.3.1. 鎖定方法 7.3.2. 表鎖定事宜 7.4. 優(yōu)化數(shù)據(jù)庫結(jié)構(gòu) 7.4.1. 設計選擇 7.4.2. 使你的數(shù)據(jù)盡可能小 7.4.3. 列索引 7.4.4. 多列索引 7.4.5. MySQL如何使用索引 7.4.6. MyISAM鍵高速緩沖 7.4.7. MyISAM索引統(tǒng)計集合 7.4.8. MySQL如何計算打開的表 7.4.9. MySQL如何打開和關(guān)閉表 7.4.10. 在同一個數(shù)據(jù)庫中創(chuàng)建多個表的缺陷 7.5. 優(yōu)化MySQL服務器 7.5.1. 系統(tǒng)因素和啟動參數(shù)的調(diào)節(jié) 7.5.2. 調(diào)節(jié)服務器參數(shù) 7.5.3. 控制查詢優(yōu)化器的性能 7.5.4. 編譯和鏈接怎樣影響MySQL的速度 7.5.5. MySQL如何使用內(nèi)存 7.5.6. MySQL如何使用DNS 7.6. 磁盤事宜 7.6.1. 使用符號鏈接 8. 客戶端和實用工具程序 8.1. 客戶端腳本和實用工具概述 8.2. myisampack:生成壓縮、只讀MyISAM表 8.3. mysql:MySQL命令行工具 8.3.1. 選項 8.3.2. mysql命令 8.3.3. 怎樣從文本文件執(zhí)行SQL語句 8.3.4. mysql技巧 8.4. mysqlaccess:用于檢查訪問權(quán)限的客戶端 8.5. mysqladmin:用于管理MySQL服務器的客戶端 8.6. mysqlbinlog:用于處理二進制日志文件的實用工具 8.7. mysqlcheck:表維護和維修程序 8.8. mysqldump:數(shù)據(jù)庫備份程序 8.9. mysqlhotcopy:數(shù)據(jù)庫備份程序 8.10. mysqlimport:數(shù)據(jù)導入程序 8.11. mysqlshow-顯示數(shù)據(jù)庫、表和列信息 8.12. myisamlog:顯示MyISAM日志文件內(nèi)容 8.13. perror:解釋錯誤代碼 8.14. replace:字符串替換實用工具 8.15. mysql_zap:殺死符合某一模式的進程 9. 語言結(jié)構(gòu) 9.1. 文字值 9.1.1. 字符串 9.1.2. 數(shù)值 9.1.3. 十六進制值 9.1.4. 布爾值 9.1.5. 位字段值 9.1.6. NULL值 9.2. 數(shù)據(jù)庫、表、索引、列和別名 9.2.1. 識別符限制條件 9.2.2. 識別符大小寫敏感性 9.3. 用戶變量 9.4. 系統(tǒng)變量 9.4.1. 結(jié)構(gòu)式系統(tǒng)變量 9.5. 注釋語法 9.6. MySQL中保留字的處理 10. 字符集支持 10.1. 常規(guī)字符集和校對 10.2. MySQL中的字符集和校對 10.3. 確定默認字符集和校對 10.3.1. 服務器字符集和校對 10.3.2. 數(shù)據(jù)庫字符集和校對 10.3.3. 表字符集和校對 10.3.4. 列字符集和校對 10.3.5. 字符集和校對分配示例 10.3.6. 連接字符集和校對 10.3.7. 字符串文字字符集和校對 10.3.8. 在SQL語句中使用COLLATE 10.3.9. COLLATE子句優(yōu)先 10.3.10. BINARY操作符 10.3.11. 校對確定較為復雜的一些特殊情況 10.3.12. 校對必須適合字符集 10.3.13. 校對效果的示例 10.4. 字符集支持影響到的操作 10.4.1. 結(jié)果字符串 10.4.2. CONVERT() 10.4.3. CAST() 10.4.4. SHOW語句 10.5. Unicode支持 10.6. 用于元數(shù)據(jù)的UTF8 10.7. 與其它DBMS的兼容性 10.8. 新字符集配置文件格式 10.9. 國家特有字符集 10.10. MySQL支持的字符集和校對 10.10.1. Unicode字符集 10.10.2. 西歐字符集 10.10.3. 中歐字符集 10.10.4. 南歐與中東字符集 10.10.5. 波羅的海字符集 10.10.6. 西里爾字符集 10.10.7. 亞洲字符集 11. 列類型 11.1. 列類型概述 11.1.1. 數(shù)值類型概述 11.1.2. 日期和時間類型概述 11.1.3. 字符串類型概述 11.2. 數(shù)值類型 11.3. 日期和時間類型 11.3.1. DATETIME、DATE和TIMESTAMP類型 11.3.2. TIME類型 11.3.3. YEAR類型 11.3.4. Y2K事宜和日期類型 11.4. String類型 11.4.1. CHAR和VARCHAR類型 11.4.2. BINARY和VARBINARY類型 11.4.3. BLOB和TEXT類型 11.4.4. ENUM類型 11.4.5. SET類型 11.5. 列類型存儲需求 11.6. 選擇正確的列類型 11.7. 使用來自其他數(shù)據(jù)庫引擎的列類型 12. 函數(shù)和操作符 12.1. 操作符 12.1.1. 操作符優(yōu)先級 12.1.2. 圓括號 12.1.3. 比較函數(shù)和操作符 12.1.4. 邏輯操作符 12.2. 控制流程函數(shù) 12.3. 字符串函數(shù) 12.3.1. 字符串比較函數(shù) 12.4. 數(shù)值函數(shù) 12.4.1. 算術(shù)操作符 12.4.2. 數(shù)學函數(shù) 12.5. 日期和時間函數(shù) 12.6. MySQL使用什么日歷? 12.7. 全文搜索功能 12.7.1. 布爾全文搜索 12.7.2. 全文搜索帶查詢擴展 12.7.3. 全文停止字 12.7.4. 全文限定條件 12.7.5. 微調(diào)MySQL全文搜索 12.8. Cast函數(shù)和操作符 12.9. 其他函數(shù) 12.9.1. 位函數(shù) 12.9.2. 加密函數(shù) 12.9.3. 信息函數(shù) 12.9.4. 其他函數(shù) NoName 12.10.1. GROUP BY(聚合)函數(shù) 12.10.2. GROUP BY修改程序 12.10.3. 具有隱含字段的GROUP BY 13. SQL語句語法 13.1. 數(shù)據(jù)定義語句 13.1.1. ALTER DATABASE語法 13.1.2. ALTER TABLE語法 13.1.3. CREATE DATABASE語法 13.1.4. CREATE INDEX語法 13.1.5. CREATE TABLE語法 13.1.6. DROP DATABASE語法 13.1.7. DROP INDEX語法 13.1.8. DROP TABLE語法 13.1.9. RENAME TABLE語法 13.2. 數(shù)據(jù)操作語句 13.2.1. DELETE語法 13.2.2. DO語法 13.2.3. HANDLER語法 13.2.4. INSERT語法 13.2.5. LOAD DATA INFILE語法 13.2.6. REPLACE語法 13.2.7. SELECT語法 13.2.8. Subquery語法 13.2.9. TRUNCATE語法 13.2.10. UPDATE語法 13.3. MySQL實用工具語句 13.3.1. DESCRIBE語法(獲取有關(guān)列的信息) 13.3.2. USE語法 13.4. MySQL事務處理和鎖定語句 13.4.1. START TRANSACTION 13.4.2. 不能回滾的語句 13.4.3. 會造成隱式提交的語句 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT語法 13.4.5. LOCK TABLES和UNLOCK TABLES語法 13.4.6. SET TRANSACTION語法 13.4.7. XA事務 13.5. 數(shù)據(jù)庫管理語句 13.5.1. 賬戶管理語句 13.5.2. 表維護語句 13.5.3. SET語法 13.5.4. SHOW語法 13.5.5. 其它管理語句 13.6. 復制語句 13.6.1. 用于控制主服務器的SQL語句 13.6.2. 用于控制從服務器的SQL語句 13.7. 用于預處理語句的SQL語法 14. 插件式存儲引擎體系結(jié)構(gòu) 14.1. 前言 14.2. 概述 14.3. 公共MySQL數(shù)據(jù)庫服務器層 14.4. 選擇存儲引擎 14.5. 將存儲引擎指定給表 14.6. 存儲引擎和事務 14.7. 插入存儲引擎 14.8. 拔出存儲引擎 14.9. 插件式存儲器的安全含義 15. 存儲引擎和表類型 15.1. MyISAM存儲引擎 15.1.1. MyISAM啟動選項 15.1.2. 鍵所需的空間 15.1.3. MyISAM表的存儲格式 15.1.4. MyISAM表方面的問題 15.2. InnoDB存儲引擎 15.2.1. InnoDB概述 15.2.2. InnoDB聯(lián)系信息 15.2.3. InnoDB配置 15.2.4. InnoDB啟動選項 15.2.5. 創(chuàng)建InnoDB表空間 15.2.6. 創(chuàng)建InnoDB表 15.2.7. 添加和刪除InnoDB數(shù)據(jù)和日志文件 15.2.8. InnoDB數(shù)據(jù)庫的備份和恢復 15.2.9. 將InnoDB數(shù)據(jù)庫移到另一臺機器上 15.2.10. InnoDB事務模型和鎖定 15.2.11. InnoDB性能調(diào)節(jié)提示 15.2.12. 多版本的實施 15.2.13. 表和索引結(jié)構(gòu) 15.2.14. 文件空間管理和磁盤I/O 15.2.15. InnoDB錯誤處理 15.2.16. 對InnoDB表的限制 15.2.17. InnoDB故障診斷與排除 15.3. MERGE存儲引擎 15.3.1. MERGE表方面的問題 15.4. MEMORY (HEAP)存儲引擎 15.5. BDB (BerkeleyDB)存儲引擎 15.5.1. BDB支持的操作系統(tǒng) 15.5.2. 安裝BDB 15.5.3. BDB啟動選項 15.5.4. BDB表的特性 15.5.5. 修改BDB所需的事宜 15.5.6. 對BDB表的限制 15.5.7. 使用BDB表時可能出現(xiàn)的錯誤 15.6. EXAMPLE存儲引擎 15.7. FEDERATED存儲引擎 15.7.1. 安裝FEDERATED存儲引擎 15.7.2. FEDERATED存儲引擎介紹 15.7.3. 如何使用FEDERATED表 15.7.4. FEDERATED存儲引擎的局限性 15.8. ARCHIVE存儲引擎 15.9. CSV存儲引擎 15.10. BLACKHOLE存儲引擎 16. 編寫自定義存儲引擎 16.1. 前言 16.2. 概述 16.3. 創(chuàng)建存儲引擎源文件 NoName 16.5. 對處理程序進行實例化處理 16.6. 定義表擴展 16.7. 創(chuàng)建表 16.8. 打開表 16.9. 實施基本的表掃描功能 16.9.1. 實施store_lock()函數(shù) 16.9.2. 實施external_lock()函數(shù) 16.9.3. 實施rnd_init()函數(shù) 16.9.4. 實施info()函數(shù) 16.9.5. 實施extra()函數(shù) 16.9.6. 實施rnd_next()函數(shù) 16.10. 關(guān)閉表 NoName NoName NoName 16.14. API引用 16.14.1. bas_ext 16.14.2. close 16.14.3. create 16.14.4. delete_row 16.14.5. delete_table 16.14.6. external_lock 16.14.7. extra 16.14.8. info 16.14.9. open 16.14.10. rnd_init 16.14.11. rnd_next 16.14.12. store_lock 16.14.13. update_row 16.14.14. write_row 17. MySQL簇 17.1. MySQL簇概述 17.2. MySQL簇的基本概念 17.3. 多計算機的簡單基礎(chǔ)知識 17.3.1. 硬件、軟件和聯(lián)網(wǎng) 17.3.2. 安裝 17.3.3. 配置 17.3.4. 首次啟動 17.3.5. 加載示例數(shù)據(jù)并執(zhí)行查詢 17.3.6. 安全關(guān)閉和重啟 17.4. MySQL簇的配置 17.4.1. 從源碼創(chuàng)建MySQL簇 17.4.2. 安裝軟件 17.4.3. MySQL簇的快速測試設置 17.4.4. 配置文件 17.5. MySQL簇中的進程管理 17.5.1. 用于MySQL簇的MySQL服務器進程使用 17.5.2. ndbd,存儲引擎節(jié)點進程 17.5.3. ndb_mgmd,“管理服務器”進程 17.5.4. ndb_mgm,“管理客戶端”進程 17.5.5. 用于MySQL簇進程的命令選項 17.6. MySQL簇的管理 17.6.1. MySQL簇的啟動階段 17.6.2. “管理客戶端”中的命令 17.6.3. MySQL簇中生成的事件報告 17.6.4. 單用戶模式 17.6.5. MySQL簇的聯(lián)機備份 17.7. 使用與MySQL簇的高速互連 17.7.1. 配置MySQL簇以使用SCI套接字 17.7.2. 理解簇互連的影響 17.8. MySQL簇的已知限制 17.9. MySQL簇發(fā)展的重要歷程 17.9.1. MySQL 5.0中的MySQL簇變化 17.9.2. 關(guān)于MySQL簇的MySQL 5.1發(fā)展歷程 17.10. MySQL簇常見問題解答 17.11. MySQL簇術(shù)語表 18. 分區(qū) 18.1. MySQL中的分區(qū)概述 18.2. 分區(qū)類型 18.2.1. RANGE分區(qū) 18.2.2. LIST分區(qū) 18.2.3. HASH分區(qū) 18.2.4. KEY分區(qū) 18.2.5. 子分區(qū) 18.2.6. MySQL分區(qū)處理NULL值的方式 18.3. 分區(qū)管理 18.3.1. RANGE和LIST分區(qū)的管理 18.3.2. HASH和KEY分區(qū)的管理 18.3.3. 分區(qū)維護 18.3.4. 獲取關(guān)于分區(qū)的信息 19. MySQL中的空間擴展 19.1. 前言 19.2. OpenGIS幾何模型 19.2.1. Geometry類的層次 19.2.2. 類Geometry 19.2.3. 類Point 19.2.4. 類Curve 19.2.5. 類LineString 19.2.6. 類Surface 19.2.7. 類Polygon 19.2.8. 類GeometryCollection 19.2.9. 類MultiPoint 19.2.10. 類MultiCurve 19.2.11. 類MultiLineString 19.2.12. 類MultiSurface 19.2.13. 類MultiPolygon 19.3. 支持的空間數(shù)據(jù)格式 19.3.1. 著名的文本(WKT)格式 19.3.2. 著名的二進制(WKB)格式 19.4. 創(chuàng)建具備空間功能的MySQL數(shù)據(jù)庫 19.4.1. MySQL空間數(shù)據(jù)類型 19.4.2. 創(chuàng)建空間值 19.4.3. 創(chuàng)建空間列 19.4.4. 填充空間列 19.4.5. 獲取空間數(shù)據(jù) 19.5. 分析空間信息 19.5.1. Geometry格式轉(zhuǎn)換函數(shù) 19.5.2. Geometry函數(shù) 19.5.3. 從已有Geometry創(chuàng)建新Geometry的函數(shù) 19.5.4. 測試幾何對象間空間關(guān)系的函數(shù) 19.5.5. 關(guān)于幾何最小邊界矩形(MBR)的關(guān)系 19.5.6. 測試幾何類之間空間關(guān)系的函數(shù) 19.6. 優(yōu)化空間分析 19.6.1. 創(chuàng)建空間索引 19.6.2. 使用空間索引 19.7. MySQL的一致性和兼容性 19.7.1. 尚未實施的GIS特性 20. 存儲程序和函數(shù) 20.1. 存儲程序和授權(quán)表 20.2. 存儲程序的語法 20.2.1. CREATE PROCEDURE和CREATE FUNCTION 20.2.2. ALTER PROCEDURE和ALTER FUNCTION 20.2.3. DROP PROCEDURE和DROP FUNCTION 20.2.4.SHOW CREATE PROCEDURE和SHOW CREATE FUNCTION 20.2.5.SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS 20.2.6. CALL語句 20.2.7. BEGIN ... END復合語句 20.2.8. DECLARE語句 20.2.9. 存儲程序中的變量 20.2.10. 條件和處理程序 20.2.11. 光標 20.2.12. 流程控制構(gòu)造 20.3. 存儲程序、函數(shù)、觸發(fā)程序和復制:常見問題 20.4. 存儲子程序和觸發(fā)程序的二進制日志功能 21. 觸發(fā)程序 21.1. CREATE TRIGGER語法 21.2. DROP TRIGGER語法 21.3. 使用觸發(fā)程序 22. 視圖 22.1. ALTER VIEW語法 22.2. CREATE VIEW語法 22.3. DROP VIEW語法 22.4. SHOW CREATE VIEW語法 23. INFORMATION_SCHEMA信息數(shù)據(jù)庫 23.1. INFORMATION_SCHEMA表 23.1.1. INFORMATION_SCHEMA SCHEMATA表 23.1.2. INFORMATION_SCHEMA TABLES表 23.1.3. INFORMATION_SCHEMA COLUMNS表 23.1.4. INFORMATION_SCHEMA STATISTICS表 23.1.5. INFORMATION_SCHEMA USER_PRIVILEGES表 23.1.6. INFORMATION_SCHEMA SCHEMA_PRIVILEGES表 23.1.7. INFORMATION_SCHEMA TABLE_PRIVILEGES表 23.1.8. INFORMATION_SCHEMA COLUMN_PRIVILEGES表 23.1.9. INFORMATION_SCHEMA CHARACTER_SETS表 23.1.10. INFORMATION_SCHEMA COLLATIONS表 23.1.11. INFORMATION_SCHEMA COLLATION_CHARACTER_SET_APPLICABILITY表 23.1.12. INFORMATION_SCHEMA TABLE_CONSTRAINTS表 23.1.13. INFORMATION_SCHEMA KEY_COLUMN_USAGE表 23.1.14. INFORMATION_SCHEMA ROUTINES表 23.1.15. INFORMATION_SCHEMA VIEWS表 23.1.16. INFORMATION_SCHEMA TRIGGERS表 23.1.17. 其他INFORMATION_SCHEMA表 NoName 24. 精度數(shù)學 24.1. 數(shù)值的類型 24.2. DECIMAL數(shù)據(jù)類型更改 24.3. 表達式處理 24.4. 四舍五入 24.5. 精度數(shù)學示例 25. API和庫 25.1. libmysqld,嵌入式MySQL服務器庫 25.1.1. 嵌入式MySQL服務器庫概述 25.1.2. 使用libmysqld編譯程序 25.1.3. 使用嵌入式MySQL服務器時的限制 25.1.4. 與嵌入式服務器一起使用的選項 25.1.5. 嵌入式服務器中尚需完成的事項(TODO) 25.1.6. 嵌入式服務器示例 25.1.7. 嵌入式服務器的許可 25.2. MySQL C API 25.2.1. C API數(shù)據(jù)類型 25.2.2. C API函數(shù)概述 25.2.3. C API函數(shù)描述 25.2.4. C API預處理語句 25.2.5. C API預處理語句的數(shù)據(jù)類型 25.2.6. C API預處理語句函數(shù)概述 25.2.7. C API預處理語句函數(shù)描述 25.2.8. C API預處理語句方面的問題 25.2.9. 多查詢執(zhí)行的C API處理 25.2.10. 日期和時間值的C API處理 25.2.11. C API線程函數(shù)介紹 25.2.12. C API嵌入式服務器函數(shù)介紹 25.2.13. 使用C API時的常見問題 25.2.14. 創(chuàng)建客戶端程序 25.2.15. 如何生成線程式客戶端 25.3. MySQL PHP API 25.3.1. 使用MySQL和PHP的常見問題 25.4. MySQL Perl API 25.5. MySQL C++ API 25.5.1. Borland C++ 25.6. MySQL Python API 25.7. MySQL Tcl API 25.8. MySQL Eiffel Wrapper 25.9. MySQL程序開發(fā)實用工具 25.9.1. msql2mysql:轉(zhuǎn)換mSQL程序以用于MySQL 25.9.2. mysql_config:獲取編譯客戶端的編譯選項 26. 連接器 26.1. MySQL Connector/ODBC 26.1.1. MyODBC介紹 26.1.2. 關(guān)于ODBC和MyODBC的一般信息 26.1.3. 如何安裝MyODBC 26.1.4. 在Windows平臺上從二進制版本安裝MyODBC 26.1.5. I在Unix平臺上從二進制版本安裝MyODBC 26.1.6. 在Windows平臺上從源碼版本安裝MyODBC 26.1.7. 在Unix平臺上從源碼版本安裝MyODBC 26.1.8. 從BitKeeper開發(fā)源碼樹安裝MyODBC 26.1.9. MyODBC配置 26.1.10. 與MyODBC連接相關(guān)的事宜 26.1.11. MyODBC和Microsoft Access 26.1.12. MyODBC和Microsoft VBA及ASP 26.1.13. MyODBC和第三方ODBC工具 26.1.14. MyODBC通用功能 26.1.15. 基本的MyODBC應用步驟 26.1.16. MyODBC API引用 26.1.17. MyODBC數(shù)據(jù)類型 26.1.18. MyODBC錯誤代碼 26.1.19. MyODBC與VB:ADO、DAO和RDO 26.1.20. MyODBC與Microsoft.NET 26.1.21. 感謝 26.2. MySQL Connector/NET 26.2.1. 前言 26.2.2. 下載并安裝MySQL Connector/NET 26.2.3. Connector/NET體系結(jié)構(gòu) 26.2.4. 使用MySQL Connector/NET 26.2.5. MySQL Connector/NET變更史 26.3. MySQL Connector/J 26.3.1. 基本的JDBC概念 26.3.2. 安裝 Connector/J 26.3.3. JDBC引用 26.3.4. 與J2EE和其他Java框架一起使用 Connector/J 26.3.5. 診斷 Connector/J方面的問題 26.3.6. Changelog 26.4. MySQL Connector/MXJ 26.4.1. 前言 26.4.2. 支持平臺: 26.4.3. Junit測試要求 26.4.4. 運行Junit測試 26.4.5. 作為JDBC驅(qū)動程序的一部分運行 26.4.6. 在Java對象中運行 26.4.7. MysqldResource API 26.4.8. 在JMX代理(custom)中運行 26.4.9. 部署在標準的JMX代理環(huán)境下 (JBoss) 26.4.10. 安裝 27. 擴展MySQL 27.1. MySQL內(nèi)部控件 27.1.1. MySQL線程 27.1.2. MySQL測試套件 27.2. 為MySQL添加新函數(shù) 27.2.1. 自定義函數(shù)接口的特性 27.2.2. CREATE FUNCTION/DROP FUNCTION語法 27.2.3. 添加新的自定義函數(shù) 27.2.4. 添加新的固有函數(shù) 27.3. 為MySQL添加新步驟 27.3.1. 步驟分析 27.3.2. 編寫步驟 A. 問題和常見錯誤 A.1. 如何確定導致問題的原因 A.2. 使用MySQL程序時的常見錯誤 A.2.1. 拒絕訪問 A.2.2. 無法連接到[local] MySQL服務器 A.2.3. 客戶端不支持鑒定協(xié)議 A.2.4. 輸入密碼時出現(xiàn)密碼錯誤 NoName A.2.6. 連接數(shù)過多 A.2.7. 內(nèi)存溢出 A.2.8. MySQL服務器不可用 A.2.9. 信息包過大 A.2.10. 通信錯誤和失效連接 A.2.11. 表已滿 A.2.12. 無法創(chuàng)建文件/寫入文件 A.2.13. 命令不同步 A.2.14. 忽略用戶 A.2.15. 表tbl_name不存在 A.2.16. 無法初始化字符集 A.2.17. 文件未找到 A.3. 與安裝有關(guān)的事宜 A.3.1. 與MySQL客戶端庫的鏈接問題 A.3.2. 如何以普通用戶身份運行MySQL A.3.3. 與文件許可有關(guān)的問題 A.4. 與管理有關(guān)的事宜 A.4.1. 如何復位根用戶密碼 A.4.2. 如果MySQL依然崩潰,應作些什么 A.4.3. MySQL處理磁盤滿的方式 A.4.4. MySQL將臨時文件儲存在哪里 A.4.5. 如何保護或更改MySQL套接字文件/tmp/mysql.sock A.4.6. 時區(qū)問題 A.5. 與查詢有關(guān)的事宜 A.5.1. 搜索中的大小寫敏感性 A.5.2. 使用DATE列方面的問題 A.5.3. 與NULL值有關(guān)的問題 A.5.4. 與列別名有關(guān)的問題 A.5.5. 非事務表回滾失敗 A.5.6. 從相關(guān)表刪除行 A.5.7. 解決與不匹配行有關(guān)的問題 A.5.8. 與浮點比較有關(guān)的問題 A.6. 與優(yōu)化器有關(guān)的事宜 A.7. 與表定義有關(guān)的事宜 A.7.1. 與ALTER TABLE有關(guān)的問題 A.7.2. 如何更改表中的列順序 A.7.3. TEMPORARY TABLE問題 A.8. MySQL中的已知事宜 A.8.1. MySQL中的打開事宜 B. 錯誤代碼和消息 B.1. 服務器錯誤代碼和消息 B.2. 客戶端錯誤代碼和消息 C. 感謝 C.1. MySQL AB處的開發(fā)人 C.2. MySQL貢獻人 C.3. 資料員和譯員 C.4. MySQL使用和包含的庫 C.5. 支持MySQL的軟件包 C.6. 用于創(chuàng)建MySQL的工具 C.7. MySQL支持人員 D. MySQL變更史 D.1. 5.1.x版中的變更情況(開發(fā)) D.1.1. 5.1.2版中的變更情況(尚未發(fā)布) D.1.2. 5.1.1版中的變更情況(尚未發(fā)布) D.2. MyODBC的變更情況 D.2.1. MyODBC 3.51.12的變更情況 D.2.2. MyODBC 3.51.11的變更情況 E. 移植到其他系統(tǒng) E.1. 調(diào)試MySQL服務器 E.1.1. 針對調(diào)試編譯MySQL E.1.2. 創(chuàng)建跟蹤文件 E.1.3. 在gdb環(huán)境下調(diào)試mysqld E.1.4. 使用堆棧跟蹤 E.1.5. 使用日志文件找出mysqld中的錯誤原因 E.1.6. 如果出現(xiàn)表崩潰,請生成測試案例 E.2. 調(diào)試MySQL客戶端 E.3. DBUG軟件包 E.4. 關(guān)于RTS線程的注釋 E.5. 線程軟件包之間的差異 F. 環(huán)境變量 G. MySQL正則表達式 H. MySQL中的限制 H.1. 聯(lián)合的限制 I. 特性限制 I.1. 對存儲子程序和觸發(fā)程序的限制 I.2. 對服務器端光標的限制 I.3. 對子查詢的限制 I.4. 對視圖的限制 I.5. 對XA事務的限制 J. GNU通用公共許可 K. MySQL FLOSS許可例外 索引
文字

第18章:分區(qū)

目錄

18.1. MySQL中的分區(qū)概述
18.2. 分區(qū)類型
18.2.1. RANGE分區(qū)
18.2.2. LIST分區(qū)
18.2.3. HASH分區(qū)
18.2.4. KEY分區(qū)
18.2.5. 子分區(qū)
18.2.6. MySQL分區(qū)處理NULL值的方式
18.3. 分區(qū)管理
18.3.1. RANGE和LIST分區(qū)的管理
18.3.2. HASH和KEY分區(qū)的管理
18.3.3. 分區(qū)維護
18.3.4. 獲取關(guān)于分區(qū)的信息

本章討論MySQL 5.1.中實現(xiàn)的分區(qū)。關(guān)于分區(qū)和分區(qū)概念的介紹可以在18.1節(jié),“MySQL中的分區(qū)概述”中找到。MySQL 5.1 支持哪幾種類型的分區(qū),在18.2節(jié),“分區(qū)類型” 中討論。關(guān)于子分區(qū)在18.2.5節(jié),“子分區(qū)” 中討論。現(xiàn)有分區(qū)表中分區(qū)的增加、刪除和修改的方法在18.3節(jié),“分區(qū)管理” 中介紹。 和分區(qū)表一同使用的表維護命令在18.3.3節(jié),“分區(qū)維護” 中介紹。

請注意MySQL 5.1中的分區(qū)實現(xiàn)仍然很新(pre-alpha品質(zhì)),此時還不是可生產(chǎn)的(not production-ready)。 同樣,許多也適用于本章:在這里描述的一些功能還沒有實際上實現(xiàn)(分區(qū)維護和重新分區(qū)命令),其他的可能還沒有完全如所描述的那樣實現(xiàn)(例如, 用于分區(qū)的數(shù)據(jù)目錄(DATA DIRECTORY)和索引目錄(INDEX DIRECTORY)選項受到Bug #13520) 不利的影響). 我們已經(jīng)設法在本章中標出這些差異。在提出缺陷報告前,我們鼓勵參考下面的一些資源:

  • MySQL 分區(qū)論壇

    這是一個為對MySQL分區(qū)技術(shù)感興趣或用MySQL分區(qū)技術(shù)做試驗提供的官方討論論壇。來自MySQL 的開發(fā)者和其他的人,會在上面發(fā)表和更新有關(guān)的材料。它由分區(qū)開發(fā)和文獻團隊的成員負責監(jiān)控。

  • 分區(qū)缺陷報告

    已經(jīng)歸檔在缺陷系統(tǒng)中的、所有分區(qū)缺陷的一個列表,而無論這些缺陷的年限、嚴重性或當前的狀態(tài)如何。根據(jù)許多規(guī)則可以對這些缺陷進行篩選,或者可以從MySQL缺陷系統(tǒng)主頁 開始,然后查找你特別感興趣的缺陷。

  • Mikael Ronstr?m's Blog

    MySQL分區(qū)體系結(jié)構(gòu)和領(lǐng)先的開發(fā)者Mikael Ronstr?m 經(jīng)常在這里貼關(guān)于他研究MySQL 分區(qū)和MySQL簇的文章。

  • PlanetMySQL

    一個MySQL 新聞網(wǎng)站,它以匯集MySQL相關(guān)的網(wǎng)誌為特點,那些使用我的MySQL的人應該對此有興趣。我們鼓勵查看那些研究MySQL分區(qū)的人的網(wǎng)誌鏈接,或者把你自己的網(wǎng)誌加到這些新聞報道中。

MySQL 5.1的二進制版本目前還不可用;但是,可以從BitKeeper知識庫中獲得源碼。要激活分區(qū),需要使用--with-分區(qū)選項編譯服務器。關(guān)于建立MySQL 的更多信息,請參見2.8節(jié),“使用源碼分發(fā)版安裝MySQL”。如果在編譯一個激活分區(qū)的MySQL 5.1創(chuàng)建中碰到問題,可以在MySQL分區(qū)論壇中查找解決辦法,如果在論壇中已經(jīng)貼出的文章中沒有找到問題的解決辦法,可以在上面尋找?guī)椭?/p>

18.1.?MySQL中的分區(qū)概述

本節(jié)提供了關(guān)于MySQL 5.1.分區(qū)在概念上的概述。

SQL標準在數(shù)據(jù)存儲的物理方面沒有提供太多的指南。SQL語言的使用獨立于它所使用的任何數(shù)據(jù)結(jié)構(gòu)或圖表、表、行或列下的介質(zhì)。但是,大部分高級數(shù)據(jù)庫管理系統(tǒng)已經(jīng)開發(fā)了一些根據(jù)文件系統(tǒng)、硬件或者這兩者來確定將要用于存儲特定數(shù)據(jù)塊物理位置的方法。在MySQL,InnoDB存儲引擎長期支持表空間的概念,并且MySQL服務器甚至在分區(qū)引入之前,就能配置為存儲不同的數(shù)據(jù)庫使用不同的物理路徑(關(guān)于如何配置的解釋,請參見7.6.1節(jié),“使用符號鏈接”)。

分區(qū)又把這個概念推進了一步,它允許根據(jù)可以設置為任意大小的規(guī)則,跨文件系統(tǒng)分配單個表的多個部分。實際上,表的不同部分在不同的位置被存儲為單獨的表。用戶所選擇的、實現(xiàn)數(shù)據(jù)分割的規(guī)則被稱為分區(qū)函數(shù),這在MySQL中它可以是模數(shù),或者是簡單的匹配一個連續(xù)的數(shù)值區(qū)間或數(shù)值列表,或者是一個內(nèi)部HASH函數(shù),或一個線性HASH函數(shù)。函數(shù)根據(jù)用戶指定的分區(qū)類型來選擇,把用戶提供的表達式的值作為參數(shù)。該表達式可以是一個整數(shù)列值,或一個作用在一個或多個列值上并返回一個整數(shù)的函數(shù)。這個表達式的值傳遞給分區(qū)函數(shù),分區(qū)函數(shù)返回一個表示那個特定記錄應該保存在哪個分區(qū)的序號。這個函數(shù)不能是常數(shù),也不能是任意數(shù)。它不能包含任何查詢,但是實際上可以使用MySQL 中任何可用的SQL表達式,只要該表達式返回一個小于MAXVALUE(最大可能的正整數(shù))的正數(shù)值。分區(qū)函數(shù)的例子可以在本章后面關(guān)于分區(qū)類型的討論中找到 (請參見18.2節(jié),“分區(qū)類型” ),也可在13.1.5節(jié),“CREATE TABLE語法”的分區(qū)語法描述中找到。

當二進制碼變成可用時(也就是說,5.1 -max 二進制碼將通過--with-partition 建立),分區(qū)支持就將包含在MySQL 5.1-max 版本中。如果MySQL二進制碼是使用分區(qū)支持建立的,那么激活它不需要任何其他的東西 (例如,在my.cnf 文件中,不需要特殊的條目)。可以通過使用SHOW VARIABLES命令來確定MySQL是否支持分區(qū),例如:

mysql> SHOW VARIABLES LIKE '%partition%';
?
+-----------------------+-------+
| Variable_name???????? | Value |
+-----------------------+-------+
| have_partition_engine | YES?? |
+-----------------------+-------+
1 row in set (0.00 sec)

在如上列出的一個正確的SHOW VARIABLES 命令所產(chǎn)生的輸出中,如果沒有看到變量have_partition_engine的值為YES,那么MySQL的版本就不支持分區(qū)。(注意:在顯示任何有關(guān)分區(qū)支持信息的命令SHOW ENGINES的輸出中,不會給出任何信息;必須使用SHOW VARIABLES命令來做出這個判斷)

對于創(chuàng)建了分區(qū)的表,可以使用你的MySQL 服務器所支持的任何存儲引擎;MySQL 分區(qū)引擎在一個單獨的層中運行,并且可以和任何這樣的層進行相互作用。在MySQL 5.1版中,同一個分區(qū)表的所有分區(qū)必須使用同一個存儲引擎;例如,不能對一個分區(qū)使用MyISAM,而對另一個使用InnoDB。但是,這并不妨礙在同一個 MySQL 服務器中,甚至在同一個數(shù)據(jù)庫中,對于不同的分區(qū)表使用不同的存儲引擎。

要為某個分區(qū)表配置一個專門的存儲引擎,必須且只能使用[STORAGE] ENGINE 選項,這如同為非分區(qū)表配置存儲引擎一樣。但是,必須記住[STORAGE] ENGINE(和其他的表選項)必須列在用CREATE TABLE語句中的其他任何分區(qū)選項之前。下面的例子給出了怎樣創(chuàng)建一個通過HASH分成6個分區(qū)、使用InnoDB存儲引擎的表:

CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE)
??? ENGINE=INNODB
??? PARTITION BY HASH(MONTH(tr_date))
??? PARTITIONS 6;

(注釋:每個PARTITION 子句可以包含一個 [STORAGE] ENGINE 選項,但是在MySQL 5.1版本中,這沒有作用)。

創(chuàng)建分區(qū)的臨時表也是可能的;但是,這種表的生命周期只有當前MySQL 的會話的時間那么長。對于非分區(qū)的臨時表,這也是一樣的。

注釋分區(qū)適用于一個表的所有數(shù)據(jù)和索引;不能只對數(shù)據(jù)分區(qū)而不對索引分區(qū),反之亦然,同時也不能只對表的一部分進行分區(qū)。

可以通過使用用來創(chuàng)建分區(qū)表的CREATE TABLE語句的PARTITION子句的DATA DIRECTORY(數(shù)據(jù)路徑)INDEX DIRECTORY(索引路徑)選項,為每個分區(qū)的數(shù)據(jù)和索引指定特定的路徑。此外,MAX_ROWSMIN_ROWS選項可以用來設定最大和最小的行數(shù),它們可以各自保存在每個分區(qū)里。關(guān)于這些選項的更多信息,請參見18.3節(jié),“分區(qū)管理”。注釋這個特殊的功能由于Bug #13250的原因,目前還不能實用。在第一個5.1二進制版本投入使用時,我們應該已經(jīng)把這個問題解決了。

分區(qū)的一些優(yōu)點包括:

·???????? 與單個磁盤或文件系統(tǒng)分區(qū)相比,可以存儲更多的數(shù)據(jù)。

·???????? 對于那些已經(jīng)失去保存意義的數(shù)據(jù),通??梢酝ㄟ^刪除與那些數(shù)據(jù)有關(guān)的分區(qū),很容易地刪除那些數(shù)據(jù)。相反地,在某些情況下,添加新數(shù)據(jù)的過程又可以通過為那些新數(shù)據(jù)專門增加一個新的分區(qū),來很方便地實現(xiàn)。

通常和分區(qū)有關(guān)的其他優(yōu)點包括下面列出的這些。MySQL 分區(qū)中的這些功能目前還沒有實現(xiàn),但是在我們的優(yōu)先級列表中,具有高的優(yōu)先級;我們希望在5.1的生產(chǎn)版本中,能包括這些功能。

·???????? 一些查詢可以得到極大的優(yōu)化,這主要是借助于滿足一個給定WHERE 語句的數(shù)據(jù)可以只保存在一個或多個分區(qū)內(nèi),這樣在查找時就不用查找其他剩余的分區(qū)。因為分區(qū)可以在創(chuàng)建了分區(qū)表后進行修改,所以在第一次配置分區(qū)方案時還不曾這么做時,可以重新組織數(shù)據(jù),來提高那些常用查詢的效率。

·???????? 涉及到例如SUM() COUNT()這樣聚合函數(shù)的查詢,可以很容易地進行并行處理。這種查詢的一個簡單例子如 “SELECT salesperson_id, COUNT(orders) as order_total FROM sales GROUP BY salesperson_id。通過并行, 這意味著該查詢可以在每個分區(qū)上同時進行,最終結(jié)果只需通過總計所有分區(qū)得到的結(jié)果。

·???????? 通過跨多個磁盤來分散數(shù)據(jù)查詢,來獲得更大的查詢吞吐量。

要經(jīng)常檢查本頁和本章,因為它將隨MySQL 5.1后續(xù)的分區(qū)進展而更新。

18.2.?分區(qū)類型

18.2.1. RANGE分區(qū)
18.2.2. LIST分區(qū)
18.2.3. HASH分區(qū)
18.2.4. KEY分區(qū)
18.2.5. 子分區(qū)
18.2.6. MySQL分區(qū)處理NULL值的方式

本節(jié)討論在MySQL 5.1中可用的分區(qū)類型。這些類型包括:

·???????? RANGE 分區(qū)基于屬于一個給定連續(xù)區(qū)間的列值,把多行分配給分區(qū)。參見18.2.1節(jié),“RANGE分區(qū)”。

·???????? LIST 分區(qū)類似于按RANGE分區(qū),區(qū)別在于LIST分區(qū)是基于列值匹配一個離散值集合中的某個值來進行選擇。參見18.2.2節(jié),“LIST分區(qū)”。

·???????? HASH分區(qū)基于用戶定義的表達式的返回值來進行選擇的分區(qū),該表達式使用將要插入到表中的這些行的列值進行計算。這個函數(shù)可以包含MySQL 中有效的、產(chǎn)生非負整數(shù)值的任何表達式。參見18.2.3節(jié),“HASH分區(qū)”。

·???????? KEY 分區(qū):類似于按HASH分區(qū),區(qū)別在于KEY分區(qū)只支持計算一列或多列,且MySQL 服務器提供其自身的哈希函數(shù)。必須有一列或多列包含整數(shù)值。參見18.2.4節(jié),“KEY分區(qū)”。

無論使用何種類型的分區(qū),分區(qū)總是在創(chuàng)建時就自動的順序編號,且從0開始記錄,記住這一點非常重要。當有一新行插入到一個分區(qū)表中時,就是使用這些分區(qū)編號來識別正確的分區(qū)。例如,如果你的表使用4個分區(qū),那么這些分區(qū)就編號為0, 1, 2, 3。對于RANGELIST分區(qū)類型,確認每個分區(qū)編號都定義了一個分區(qū),很有必要。對HASH分區(qū),使用的用戶函數(shù)必須返回一個大于0的整數(shù)值。對于KEY分區(qū),這個問題通過MySQL服務器內(nèi)部使用的 哈希函數(shù)自動進行處理。

分區(qū)的名字基本上遵循其他MySQL 標識符應當遵循的原則,例如用于表和數(shù)據(jù)庫名字的標識符。但是應當注意,分區(qū)的名字是不區(qū)分大小寫的。例如,下面的CREATE TABLE語句將會產(chǎn)生如下的錯誤:

mysql> CREATE TABLE t2 (val INT)
??? -> PARTITION BY LIST(val)(
??? ->???? PARTITION mypart VALUES IN (1,3,5),
??? ->???? PARTITION MyPart VALUES IN (2,4,6)
??? -> );
錯誤1488 (HY000): 表的所有分區(qū)必須有唯一的名字。

這是因為MySQL認為分區(qū)名字mypartMyPart沒有區(qū)別。

注釋在下面的章節(jié)中,我們沒有必要提供可以用來創(chuàng)建每種分區(qū)類型語法的所有可能形式,這些信息可以在13.1.5節(jié),“CREATE TABLE語法” 中找到。

18.2.1.?RANGE分區(qū)

按照RANGE分區(qū)的表是通過如下一種方式進行分區(qū)的,每個分區(qū)包含那些分區(qū)表達式的值位于一個給定的連續(xù)區(qū)間內(nèi)的行。這些區(qū)間要連續(xù)且不能相互重疊,使用VALUES LESS THAN操作符來進行定義。在下面的幾個例子中,假定你創(chuàng)建了一個如下的一個表,該表保存有20家音像店的職員記錄,這20家音像店的編號從120

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT NOT NULL,
??? store_id INT NOT NULL
);

根據(jù)你的需要,這個表可以有多種方式來按照區(qū)間進行分區(qū)。一種方式是使用store_id 列。例如,你可能決定通過添加一個PARTITION BY RANGE子句把這個表分割成4個區(qū)間,如下所示:

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT NOT NULL,
??? store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
??? PARTITION p0 VALUES LESS THAN (6),
??? PARTITION p1 VALUES LESS THAN (11),
??? PARTITION p2 VALUES LESS THAN (16),
??? PARTITION p3 VALUES LESS THAN (21)
);

按照這種分區(qū)方案,在商店15工作的雇員相對應的所有行被保存在分區(qū)P0中,商店610的雇員保存在P1中,依次類推。注意,每個分區(qū)都是按順序進行定義,從最低到最高。這是PARTITION BY RANGE 語法的要求;在這點上,它類似于CJava中的“switch ... case”語句。

對于包含數(shù)據(jù)(72, 'Michael', 'Widenius', '1998-06-25', NULL, 13)的一個新行,可以很容易地確定它將插入到p2分區(qū)中,但是如果增加了一個編號為第21的商店,將會發(fā)生什么呢?在這種方案下,由于沒有規(guī)則把store_id大于20的商店包含在內(nèi),服務器將不知道把該行保存在何處,將會導致錯誤。 要避免這種錯誤,可以通過在CREATE TABLE語句中使用一個“catchallVALUES LESS THAN句,該子句提供給所有大于明確指定的最高值的值:

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT NOT NULL,
??? store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
??? PARTITION p0 VALUES LESS THAN (6),
??? PARTITION p1 VALUES LESS THAN (11),
??? PARTITION p2 VALUES LESS THAN (16),
??? PARTITION p3 VALUES LESS THAN MAXVALUE
);

MAXVALUE 表示最大的可能的整數(shù)值。現(xiàn)在,store_id 列值大于或等于16(定義了的最高值)的所有行都將保存在分區(qū)p3中。在將來的某個時候,當商店數(shù)已經(jīng)增長到25, 30, 或更多 ,可以使用ALTER TABLE語句為商店21-25, 26-30,等等增加新的分區(qū) (關(guān)于如何實現(xiàn)的詳細信息參見18.3節(jié),“分區(qū)管理” )

在幾乎一樣的結(jié)構(gòu)中,你還可以基于雇員的工作代碼來分割表,也就是說,基于job_code 列值的連續(xù)區(qū)間。例如——假定2位數(shù)字的工作代碼用來表示普通(店內(nèi)的)工人,三個數(shù)字代碼表示辦公室和支持人員,四個數(shù)字代碼表示管理層,你可以使用下面的語句創(chuàng)建該分區(qū)表:

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT NOT NULL,
??? store_id INT NOT NULL
)
PARTITION BY RANGE (job_code) (
??? PARTITION p0 VALUES LESS THAN (100),
??? PARTITION p1 VALUES LESS THAN (1000),
??? PARTITION p2 VALUES LESS THAN (10000)
);

在這個例子中, 店內(nèi)工人相關(guān)的所有行將保存在分區(qū)p0中,辦公室和支持人員相關(guān)的所有行保存在分區(qū)p1中,管理層相關(guān)的所有行保存在分區(qū)p2中。

VALUES LESS THAN 子句中使用一個表達式也是可能的。這里最值得注意的限制是MySQL 必須能夠計算表達式的返回值作為LESS THAN (<)比較的一部分;因此,表達式的值不能為NULL 。由于這個原因,雇員表的hired, separated, job_code,store_id列已經(jīng)被定義為非空(NOT NULL)。

除了可以根據(jù)商店編號分割表數(shù)據(jù)外,你還可以使用一個基于兩個DATE (日期)中的一個的表達式來分割表數(shù)據(jù)。例如,假定你想基于每個雇員離開公司的年份來分割表,也就是說,YEAR(separated)的值。實現(xiàn)這種分區(qū)模式的CREATE TABLE 語句的一個例子如下所示:

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT,
??? store_id INT
)
PARTITION BY RANGE (YEAR(separated)) (
??? PARTITION p0 VALUES LESS THAN (1991),
??? PARTITION p1 VALUES LESS THAN (1996),
??? PARTITION p2 VALUES LESS THAN (2001),
??? PARTITION p3 VALUES LESS THAN MAXVALUE
);

在這個方案中,在1991年前雇傭的所有雇員的記錄保存在分區(qū)p0中,1991年到1995年期間雇傭的所有雇員的記錄保存在分區(qū)p1中, 1996年到2000年期間雇傭的所有雇員的記錄保存在分區(qū)p2中,2000年后雇傭的所有工人的信息保存在p3中。

RANGE分區(qū)在如下場合特別有用:

·???????? 當需要刪除“舊的”數(shù)據(jù)時。如果你使用上面最近的那個例子給出的分區(qū)方案,你只需簡單地使用 “ALTER TABLE employees DROP PARTITION p0來刪除所有在1991年前就已經(jīng)停止工作的雇員相對應的所有行。(更多信息請參見13.1.2節(jié),“ALTER TABLE語法” 和 18.3節(jié),“分區(qū)管理”)。對于有大量行的表,這比運行一個如“DELETE FROM employees WHERE YEAR(separated) <= 1990”這樣的一個DELETE查詢要有效得多。

·???????? 想要使用一個包含有日期或時間值,或包含有從一些其他級數(shù)開始增長的值的列。

·???????? 經(jīng)常運行直接依賴于用于分割表的列的查詢。例如,當執(zhí)行一個如“SELECT COUNT(*) FROM employees WHERE YEAR(separated) = 2000 GROUP BY store_id;”這樣的查詢時,MySQL可以很迅速地確定只有分區(qū)p2需要掃描,這是因為余下的分區(qū)不可能包含有符合該WHERE子句的任何記錄。注釋:這種優(yōu)化還沒有在MySQL 5.1源程序中啟用,但是,有關(guān)工作正在進行中。

18.2.2.?LIST分區(qū)

MySQL中的LIST分區(qū)在很多方面類似于RANGE分區(qū)。和按照RANGE分區(qū)一樣,每個分區(qū)必須明確定義。它們的主要區(qū)別在于,LIST分區(qū)中每個分區(qū)的定義和選擇是基于某列的值從屬于一個值列表集中的一個值,而RANGE分區(qū)是從屬于一個連續(xù)區(qū)間值的集合。LIST分區(qū)通過使用“PARTITION BY LIST(expr)”來實現(xiàn),其中expr” 是某列值或一個基于某個列值、并返回一個整數(shù)值的表達式,然后通過“VALUES IN (value_list)”的方式來定義每個分區(qū),其中“value_list”是一個通過逗號分隔的整數(shù)列表。

注釋MySQL 5.1中,當使用LIST分區(qū)時,有可能只能匹配整數(shù)列表。

不像按照RANGE定義分區(qū)的情形,LIST分區(qū)不必聲明任何特定的順序。關(guān)于LIST分區(qū)更詳細的語法信息,請參考13.1.5節(jié),“CREATE TABLE語法” 。

對于下面給出的例子,我們假定將要被分區(qū)的表的基本定義是通過下面的“CREATE TABLE”語句提供的:

CREATE TABLE employees (
??? id INT NOT NULL,
?? ?fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT,
??? store_id INT
)

(這和18.2.1節(jié),“RANGE分區(qū)” 中的例子中使用的是同一個表)。?

假定有20個音像店,分布在4個有經(jīng)銷權(quán)的地區(qū),如下表所示:

地區(qū)

商店ID

北區(qū)

3, 5, 6, 9, 17

東區(qū)

1, 2, 10, 11, 19, 20

西區(qū)

4, 12, 13, 14, 18

中心區(qū)

7, 8, 15, 16

要按照屬于同一個地區(qū)商店的行保存在同一個分區(qū)中的方式來分割表,可以使用下面的“CREATE TABLE”語句:

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT,
??? store_id INT
)
PARTITION BY LIST(store_id)
??? PARTITION pNorth VALUES IN (3,5,6,9,17),
??? PARTITION pEast VALUES IN (1,2,10,11,19,20),
??? PARTITION pWest VALUES IN (4,12,13,14,18),
??? PARTITION pCentral VALUES IN (7,8,15,16)
);

這使得在表中增加或刪除指定地區(qū)的雇員記錄變得容易起來。例如,假定西區(qū)的所有音像店都賣給了其他公司。那么與在西區(qū)音像店工作雇員相關(guān)的所有記錄(行)可以使用查詢“ALTER TABLE employees DROP PARTITION pWest;”來進行刪除,它與具有同樣作用的DELETE (刪除)查詢“DELETE query DELETE FROM employees WHERE store_id IN (4,12,13,14,18);”比起來,要有效得多。

要點:如果試圖插入列值(或分區(qū)表達式的返回值)不在分區(qū)值列表中的一行時,那么“INSERT”查詢將失敗并報錯。例如,假定LIST分區(qū)的采用上面的方案,下面的查詢將失敗:

INSERT INTO employees VALUES 
????(224, 'Linus', 'Torvalds', '2002-05-01', '2004-10-12', 42, 21);

這是因為“store_id”列值21不能在用于定義分區(qū)pNorth, pEast, pWest,pCentral的值列表中找到。要重點注意的是,LIST分區(qū)沒有類似如“VALUES LESS THAN MAXVALUE”這樣的包含其他值在內(nèi)的定義。將要匹配的任何值都必須在值列表中找到。

LIST分區(qū)除了能和RANGE分區(qū)結(jié)合起來生成一個復合的子分區(qū),與HASHKEY分區(qū)結(jié)合起來生成復合的子分區(qū)也是可能的。 關(guān)于這方面的討論,請參考18.2.5節(jié),“子分區(qū)”。

18.2.3.?HASH分區(qū)

18.2.3.1. LINEAR HASH分區(qū)

HASH分區(qū)主要用來確保數(shù)據(jù)在預先確定數(shù)目的分區(qū)中平均分布。在RANGELIST分區(qū)中,必須明確指定一個給定的列值或列值集合應該保存在哪個分區(qū)中;而在HASH分區(qū)中,MySQL 自動完成這些工作,你所要做的只是基于將要被哈希的列值指定一個列值或表達式,以及指定被分區(qū)的表將要被分割成的分區(qū)數(shù)量。

要使用HASH分區(qū)來分割一個表,要在CREATE TABLE 語句上添加一個“PARTITION BY HASH (expr)”子句,其中“expr”是一個返回一個整數(shù)的表達式。它可以僅僅是字段類型為MySQL 整型的一列的名字。此外,你很可能需要在后面再添加一個“PARTITIONS num”子句,其中num 是一個非負的整數(shù),它表示表將要被分割成分區(qū)的數(shù)量。

例如,下面的語句創(chuàng)建了一個使用基于“store_id”列進行 哈希處理的表,該表被分成了4個分區(qū):

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT,
?? ?store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

如果沒有包括一個PARTITIONS子句,那么分區(qū)的數(shù)量將默認為1。 例外: 對于NDB Cluster(簇)表,默認的分區(qū)數(shù)量將與簇數(shù)據(jù)節(jié)點的數(shù)量相同,這種修正可能是考慮任何MAX_ROWS 設置,以便確保所有的行都能合適地插入到分區(qū)中。(參見第17章:MySQL簇。

如果在關(guān)鍵字“PARTITIONS”后面沒有加上分區(qū)的數(shù)量,將會出現(xiàn)語法錯誤。

expr”還可以是一個返回一個整數(shù)的SQL表達式。例如,也許你想基于雇用雇員的年份來進行分區(qū)。這可以通過下面的語句來實現(xiàn):

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT,
??? store_id INT
)
PARTITION BY HASH(YEAR(hired))
PARTITIONS 4

expr”還可以是MySQL 中有效的任何函數(shù)或其他表達式,只要它們返回一個既非常數(shù)、也非隨機數(shù)的整數(shù)。(換句話說,它既是變化的但又是確定的)。但是應當記住,每當插入或更新(或者可能刪除)一行,這個表達式都要計算一次;這意味著非常復雜的表達式可能會引起性能問題,尤其是在執(zhí)行同時影響大量行的運算(例如批量插入)的時候。

最有效率的哈希函數(shù)是只對單個表列進行計算,并且它的值隨列值進行一致地增大或減小,因為這考慮了在分區(qū)范圍上的“修剪”。也就是說,表達式值和它所基于的列的值變化越接近,MySQL就可以越有效地使用該表達式來進行HASH分區(qū)。

例如,“date_col” 是一個DATE(日期)類型的列,那么表達式TO_DAYS(date_col)就可以說是隨列“date_col”值的變化而發(fā)生直接的變化,因為列“date_col”值的每個變化,表達式的值也將發(fā)生與之一致的變化。而表達式Y(jié)EAR(date_col)的變化就沒有表達式TO_DAYS(date_col)那么直接,因為不是列“date_col”每次可能的改變都能使表達式Y(jié)EAR(date_col)發(fā)生同等的改變。即便如此,表達式Y(jié)EAR(date_col)也還是一個用于 哈希函數(shù)的、好的候選表達式,因為它隨列date_col的一部分發(fā)生直接變化,并且列date_col的變化不可能引起表達式Y(jié)EAR(date_col)不成比例的變化。

作為對照,假定有一個類型為整型(INT)的、列名為“int_col”的列。現(xiàn)在考慮表達式“POW(5-int_col,3) + 6”。這對于哈希函數(shù)就是一個不好的選擇,因為“int_col”值的變化并不能保證表達式產(chǎn)生成比例的變化。列 “int_col”的值發(fā)生一個給定數(shù)目的變化,可能會引起表達式的值產(chǎn)生一個很大不同的變化。例如,把列“int_col”的值從5變?yōu)?,表達式的值將產(chǎn)生“-1”的改變,但是把列“int_col”的值從6變?yōu)?時,表達式的值將產(chǎn)生“-7”的變化。

換句話說,如果列值與表達式值之比的曲線圖越接近由等式“y=nx(其中n為非零的常數(shù))描繪出的直線,則該表達式越適合于 哈希。這是因為,表達式的非線性越嚴重,分區(qū)中數(shù)據(jù)產(chǎn)生非均衡分布的趨勢也將越嚴重。

理論上講,對于涉及到多列的表達式,“修剪(pruning)”也是可能的,但是要確定哪些適于 哈希是非常困難和耗時的?;谶@個原因,實際上不推薦使用涉及到多列的哈希表達式。

當使用了“PARTITION BY HASH”時,MySQL將基于用戶函數(shù)結(jié)果的模數(shù)來確定使用哪個編號的分區(qū)。換句話,對于一個表達式“expr”,將要保存記錄的分區(qū)編號為N ,其中“N = MOD(expr, num)”。例如,假定表t1 定義如下,它有4個分區(qū):

CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE)
??? PARTITION BY HASH( YEAR(col3) )
??? PARTITIONS 4;

如果插入一個col3值為'2005-09-15'的記錄到表t1中,那么保存該條記錄的分區(qū)確定如下:

MOD(YEAR('2005-09-01'),4)
=? MOD(2005,4)
=? 1

MySQL 5.1 還支持一個被稱為“linear hashing(線性哈希功能)”的變量,它使用一個更加復雜的算法來確定新行插入到已經(jīng)分區(qū)了的表中的位置。關(guān)于這種算法的描述,請參見18.2.3.1節(jié),“LINEAR HASH分區(qū)” 。

每當插入或更新一條記錄,用戶函數(shù)都要計算一次。當刪除記錄時,用戶函數(shù)也可能要進行計算,這取決于所處的環(huán)境。

注釋如果將要分區(qū)的表有一個唯一的鍵,那么用來作為HASH用戶函數(shù)的自變數(shù)或者主鍵的column_list的自變數(shù)的任意列都必須是那個鍵的一部分。

18.2.3.1.?LINEAR HASH分區(qū)

MySQL還支持線性哈希功能,它與常規(guī)哈希的區(qū)別在于,線性哈希功能使用的一個線性的2的冪(powers-of-two)運算法則,而常規(guī) 哈希使用的是求哈希函數(shù)值的模數(shù)。

線性哈希分區(qū)和常規(guī)哈希分區(qū)在語法上的唯一區(qū)別在于,在“PARTITION BY” 子句中添加“LINEAR”關(guān)鍵字,如下面所示:

CREATE TABLE employees (
??? id INT NOT NULL,
??? fname VARCHAR(30),
??? lname VARCHAR(30),
??? hired DATE NOT NULL DEFAULT '1970-01-01',
??? separated DATE NOT NULL DEFAULT '9999-12-31',
??? job_code INT,
??? store_id INT
)
PARTITION BY LINEAR HASH(YEAR(hired))
PARTITIONS 4

假設一個表達式expr, 當使用線性哈希功能時,記錄將要保存到的分區(qū)是num 個分區(qū)中的分區(qū)N,其中N是根據(jù)下面的算法得到:

1.??? 找到下一個大于num.的、2的冪,我們把這個值稱為V ,它可以通過下面的公式得到:

2.?????????? V = POWER(2, CEILING(LOG(2, num)))

(例如,假定num13。那么LOG(2,13)就是3.7004397181411。 CEILING(3.7004397181411)就是4,則V = POWER(2,4), 即等于16。

3.??? 設置 N = F(column_list) & (V - 1).

4.??? N >= num:

·???????? 設置 V = CEIL(V / 2)

·???????? 設置 N = N & (V - 1)

例如,假設表t1,使用線性哈希分區(qū)且有4個分區(qū),是通過下面的語句創(chuàng)建的:

CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE)
??? PARTITION BY LINEAR HASH( YEAR(col3) )
??? PARTITIONS 6;

現(xiàn)在假設要插入兩行記錄到表t1中,其中一條記錄col3列值為'2003-04-14',另一條記錄col3列值為'1998-10-19'。第一條記錄將要保存到的分區(qū)確定如下:

V = POWER(2, CEILING(LOG(2,7))) = 8
N = YEAR('2003-04-14') & (8 - 1)
?? = 2003 & 7
?? = 3
?
(3 >= 6 為假(FALSE: 記錄將被保存到#3號分區(qū)中)

第二條記錄將要保存到的分區(qū)序號計算如下:

V = 8
N = YEAR('1998-10-19') & (8-1)
? = 1998 & 7
? = 6
?
(6 >= 4 為真(TRUE: 還需要附加的步驟)
?
N = 6 & CEILING(5 / 2)
? = 6 & 3
? = 2
?
(2 >= 4 為假(FALSE: 記錄將被保存到#2分區(qū)中)

按照線性哈希分區(qū)的優(yōu)點在于增加、刪除、合并和拆分分區(qū)將變得更加快捷,有利于處理含有極其大量(1000吉)數(shù)據(jù)的表。它的缺點在于,與使用常規(guī)HASH分區(qū)得到的數(shù)據(jù)分布相比,各個分區(qū)間數(shù)據(jù)的分布不大可能均衡。

18.2.4.?KEY分區(qū)

按照KEY進行分區(qū)類似于按照HASH分區(qū),除了HASH分區(qū)使用的用戶定義的表達式,而KEY分區(qū)的 哈希函數(shù)是由MySQL 服務器提供。MySQL 簇(Cluster)使用函數(shù)MD5()來實現(xiàn)KEY分區(qū);對于使用其他存儲引擎的表,服務器使用其自己內(nèi)部的 哈希函數(shù),這些函數(shù)是基于與PASSWORD()一樣的運算法則。

CREATE TABLE ... PARTITION BY KEY”的語法規(guī)則類似于創(chuàng)建一個通過HASH分區(qū)的表的規(guī)則。它們唯一的區(qū)別在于使用的關(guān)鍵字是KEY而不是HASH,并且KEY分區(qū)只采用一個或多個列名的一個列表。

通過線性KEY分割一個表也是可能的。下面是一個簡單的例子:

CREATE TABLE tk (
??? col1 INT NOT NULL,
??? col2 CHAR(5),
??? col3 DATE
) 
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;

KEY分區(qū)中使用關(guān)鍵字LINEAR和在HASH分區(qū)中使用具有同樣的作用,分區(qū)的編號是通過2的冪(powers-of-two)算法得到,而不是通過模數(shù)算法。關(guān)于該算法及其蘊涵式的描述請參考 18.2.3.1節(jié),“LINEAR HASH分區(qū)”

18.2.5.?子分區(qū)

子分區(qū)是分區(qū)表中每個分區(qū)的再次分割。例如,考慮下面的CREATE TABLE 語句:

CREATE TABLE ts (id INT, purchased DATE)
??? PARTITION BY RANGE(YEAR(purchased))
??? SUBPARTITION BY HASH(TO_DAYS(purchased))
??? SUBPARTITIONS 2
??? (
??????? PARTITION p0 VALUES LESS THAN (1990),
??????? PARTITION p1 VALUES LESS THAN (2000),
??????? PARTITION p2 VALUES LESS THAN MAXVALUE
??? );

ts 3RANGE分區(qū)。這3個分區(qū)中的每一個分區(qū)——p0, p1, p2 ——又被進一步分成了2個子分區(qū)。實際上,整個表被分成了3 * 2 = 6個分區(qū)。但是,由于PARTITION BY RANGE子句的作用,這些分區(qū)的頭2個只保存“purchased”列中值小于1990的那些記錄。

MySQL 5.1中,對于已經(jīng)通過RANGELIST分區(qū)了的表再進行子分區(qū)是可能的。子分區(qū)既可以使用HASH希分區(qū),也可以使用KEY分區(qū)。這也被稱為復合分區(qū)(composite partitioning)。

為了對個別的子分區(qū)指定選項,使用SUBPARTITION 子句來明確定義子分區(qū)也是可能的。例如,創(chuàng)建在前面例子中給出的同一個表的、一個更加詳細的方式如下:

CREATE TABLE ts (id INT, purchased DATE)
??? PARTITION BY RANGE(YEAR(purchased))
??? SUBPARTITION BY HASH(TO_DAYS(purchased))
??? (
??????? PARTITION p0 VALUES LESS THAN (1990)
??????? (
??????????? SUBPARTITION s0,
??????????? SUBPARTITION s1
??????? ),
??????? PARTITION p1 VALUES LESS THAN (2000)
??????? (
??????????? SUBPARTITION s2,
? ??????????SUBPARTITION s3
??????? ),
??????? PARTITION p2 VALUES LESS THAN MAXVALUE
??????? (
??????????? SUBPARTITION s4,
??????????? SUBPARTITION s5
??????? )
??? );

幾點要注意的語法項:

·???????? 每個分區(qū)必須有相同數(shù)量的子分區(qū)。

·???????? 如果在一個分區(qū)表上的任何分區(qū)上使用SUBPARTITION 來明確定義任何子分區(qū),那么就必須定義所有的子分區(qū)。換句話說,下面的語句將執(zhí)行失?。?

·??????????????? CREATE TABLE ts (id INT, purchased DATE)
·??????????????? ????PARTITION BY RANGE(YEAR(purchased))
·??????????????? ????SUBPARTITION BY HASH(TO_DAYS(purchased))
·??????????????? ????(
·??????????????? ????????PARTITION p0 VALUES LESS THAN (1990)
·??????????????? ????????(
·??????????????? ????????????SUBPARTITION s0,
·??????????????? ????????????SUBPARTITION s1
·??????????????? ????????),
·??????????????? ????????PARTITION p1 VALUES LESS THAN (2000),
·??????????????? ????????PARTITION p2 VALUES LESS THAN MAXVALUE
·??????????????? ????????(
·??????????????? ????????????SUBPARTITION s2,
·??????????????? ????????????SUBPARTITION s3
·??????????????? ????????)
·??????????????? ????);

即便這個語句包含了一個SUBPARTITIONS 2子句,但是它仍然會執(zhí)行失敗。

·???????? 每個SUBPARTITION 子句必須包括 (至少)子分區(qū)的一個名字。否則,你可能要對該子分區(qū)設置任何你所需要的選項,或者允許該子分區(qū)對那些選項采用其默認的設置。

·???????? 在每個分區(qū)內(nèi),子分區(qū)的名字必須是唯一的,但是在整個表中,沒有必要保持唯一。例如,下面的CREATE TABLE 語句是有效的:

·??????????????? CREATE TABLE ts (id INT, purchased DATE)
·??????????????? ????PARTITION BY RANGE(YEAR(purchased))
·??????????????? ????SUBPARTITION BY HASH(TO_DAYS(purchased))
·??????????????? ????(
·??????????????? ????????PARTITION p0 VALUES LESS THAN (1990)
·??????????????? ????????(
·??????????????? ????????????SUBPARTITION s0,
·??????????????? ????????????SUBPARTITION s1
·??????????????? ????????),
·??????????????? ????????PARTITION p1 VALUES LESS THAN (2000)
·??????????????? ????????(
·??????????????? ????????????SUBPARTITION s0,
·??????????????? ????????????SUBPARTITION s1
·??????????????? ????????),
·??????????????? ????????PARTITION p2 VALUES LESS THAN MAXVALUE
·??????????????? ????????(
·??????????????? ????????????SUBPARTITION s0,
·??????????????? ????????????SUBPARTITION s1
·??????????????? ????????)
·??????????????? ????);

子分區(qū)可以用于特別大的表,在多個磁盤間分配數(shù)據(jù)和索引。假設有6個磁盤,分別為/disk0, /disk1, /disk2等。現(xiàn)在考慮下面的例子:

CREATE TABLE ts (id INT, purchased DATE)
??? PARTITION BY RANGE(YEAR(purchased))
??? SUBPARTITION BY HASH(TO_DAYS(purchased))
??? (
??????? PARTITION p0 VALUES LESS THAN (1990)
??????? (
??????????? SUBPARTITION s0 
????????????????DATA DIRECTORY = '/disk0/data' 
????????????????INDEX DIRECTORY = '/disk0/idx',
??????????? SUBPARTITION s1 
????????????????DATA DIRECTORY = '/disk1/data' 
????????????????INDEX DIRECTORY = '/disk1/idx'
??????? ),
??????? PARTITION p1 VALUES LESS THAN (2000)
??????? (
??????????? SUBPARTITION s0 
????????????????DATA DIRECTORY = '/disk2/data' 
????????????????INDEX DIRECTORY = '/disk2/idx',
??????????? SUBPARTITION s1 
????????????????DATA DIRECTORY = '/disk3/data' 
????????????????INDEX DIRECTORY = '/disk3/idx'
??????? ),
??????? PARTITION p2 VALUES LESS THAN MAXVALUE
??????? (
??????????? SUBPARTITION s0 
????????????????DATA DIRECTORY = '/disk4/data' 
????????????????INDEX DIRECTORY = '/disk4/idx',
??????????? SUBPARTITION s1 
????????????????DATA DIRECTORY = '/disk5/data' 
????????????????INDEX DIRECTORY = '/disk5/idx'
??????? )
??? );

在這個例子中,每個RANGE分區(qū)的數(shù)據(jù)和索引都使用一個單獨的磁盤。還可能有許多其他的變化;下面是另外一個可能的例子:

CREATE TABLE ts (id INT, purchased DATE)
??? PARTITION BY RANGE(YEAR(purchased))
??? SUBPARTITION BY HASH(TO_DAYS(purchased))
??? (
??????? PARTITION p0 VALUES LESS THAN (1990)
??????? (
??????????? SUBPARTITION s0a 
????????????????DATA DIRECTORY = '/disk0' 
????????????????INDEX DIRECTORY = '/disk1',
??????????? SUBPARTITION s0b 
????????????????DATA DIRECTORY = '/disk2' 
????????????????INDEX DIRECTORY = '/disk3'
??????? ),
??????? PARTITION p1 VALUES LESS THAN (2000)
??????? (
??????????? SUBPARTITION s1a 
????????????????DATA DIRECTORY = '/disk4/data' 
????????????????INDEX DIRECTORY = '/disk4/idx',
??????????? SUBPARTITION s1b 
????????????????DATA DIRECTORY = '/disk5/data' 
????????????????INDEX DIRECTORY = '/disk5/idx'
??????? ),
??????? PARTITION p2 VALUES LESS THAN MAXVALUE
??????? (
??????????? SUBPARTITION s2a,
??????????? SUBPARTITION s2b
??????? )
??? )

在這個例子中,存儲的分配如下:

·???????? 購買日期在1990年前的記錄占了大量的存儲空間,所以把它分為了四個部分進行存儲,組成p0分區(qū)的兩個子分區(qū)(s0a s0b)的數(shù)據(jù)和索引都分別用一個單獨的磁盤進行存儲。換句話說:

o??????? 子分區(qū)s0a 的數(shù)據(jù)保存在磁盤/disk0中。

o??????? 子分區(qū)s0a 的索引保存在磁盤/disk1中。

o??????? 子分區(qū)s0b 的數(shù)據(jù)保存在磁盤/disk2中。

o??????? 子分區(qū)s0b 的索引保存在磁盤/disk3中。

·???????? 保存購買日期從1990年到1999年間的記錄(分區(qū)p1)不需要保存購買日期在1990年之前的記錄那么大的存儲空間。這些記錄分在2個磁盤(/disk4/disk5)上保存,而不是4個磁盤:

o??????? 屬于分區(qū)p1的第一個子分區(qū)(s1a)的數(shù)據(jù)和索引保存在磁盤/disk4 — 其中數(shù)據(jù)保存在路徑/disk4/data下,索引保存在/disk4/idx下。

o??????? 屬于分區(qū)p1的第二個子分區(qū)(s1b)的數(shù)據(jù)和索引保存在磁盤/disk5 — 其中數(shù)據(jù)保存在路徑/disk5/data下,索引保存在/disk5/idx下。

·???????? 保存購買日期從2000年到現(xiàn)在的記錄(分區(qū)p2)不需要前面兩個RANGE分區(qū)那么大的空間。當前,在默認的位置能夠足夠保存所有這些記錄。

將來,如果從2000年開始后十年購買的數(shù)量已經(jīng)達到了默認的位置不能夠提供足夠的保存空間時,相應的記錄(行)可以通過使用“ALTER TABLE ... REORGANIZE PARTITION”語句移動到其他的位置。關(guān)于如何實現(xiàn)的說明,請參見18.3節(jié),“分區(qū)管理” 。

18.2.6.?MySQL分區(qū)處理NULL值的方式

MySQL 中的分區(qū)在禁止空值(NULL)上沒有進行處理,無論它是一個列值還是一個用戶定義表達式的值。一般而言,在這種情況下MySQL NULL視為0。如果你希望回避這種做法,你應該在設計表時不允許空值;最可能的方法是,通過聲明列“NOT NULL”來實現(xiàn)這一點。

在本節(jié)中,我們提供了一些例子,來說明當決定一個行應該保存到哪個分區(qū)時,MySQL 是如何處理NULL值的。

如果插入一行到按照RANGELIST分區(qū)的表,該行用來確定分區(qū)的列值為NULL,分區(qū)將把該NULL值視為0。例如,考慮下面的兩個表,表的創(chuàng)建和插入記錄如下:

mysql> CREATE TABLE tnlist (
??? ->???? id INT,
??? ->???? name VARCHAR(5)
??? -> )
??? -> PARTITION BY LIST(id) (
??? ->???? PARTITION p1 VALUES IN (0),
??? ->???? PARTITION p2 VALUES IN (1)
??? -> );
Query OK, 0 rows affected (0.09 sec)
?
mysql> CREATE TABLE tnrange (
??? ->???? id INT,
??? ->???? name VARCHAR(5)
??? -> )
??? -> PARTITION BY RANGE(id) (
??? ->???? PARTITION p1 VALUES LESS THAN (1),
??? ->???? PARTITION p2 VALUES LESS THAN MAXVALUE
??? -> );
Query OK, 0 rows affected (0.09 sec)
?
mysql> INSERT INTO tnlist VALUES (NULL, 'bob');
Query OK, 1 row affected (0.00 sec)
?
mysql> INSERT INTO tnrange VALUES (NULL, 'jim');
Query OK, 1 row affected (0.00 sec)
?
mysql> SELECT * FROM tnlist;
+------+------+
| id?? | name |
+------+------+
| NULL | bob? |
+------+------+
1 row in set (0.00 sec)
?
mysql> SELECT * FROM tnrange;
+------+------+
| id?? | name |
+------+------+
| NULL | jim? |
+------+------+
1 row in set (0.00 sec)

在兩個表中,id列沒有聲明為“NOT NULL”,這意味著它們允許Null值。可以通過刪除這些分區(qū),然后重新運行SELECT 語句,來驗證這些行被保存在每個表的p1分區(qū)中:

mysql> ALTER TABLE tnlist DROP PARTITION p1;
Query OK, 0 rows affected (0.16 sec)
?
mysql> ALTER TABLE tnrange DROP PARTITION p1;
Query OK, 0 rows affected (0.16 sec)
?
mysql> SELECT * FROM tnlist;
Empty set (0.00 sec)
?
mysql> SELECT * FROM tnrange;
Empty set (0.00 sec)

在按HASHKEY分區(qū)的情況下,任何產(chǎn)生NULL值的表達式都視同好像它的返回值為0。我們可以通過先創(chuàng)建一個按HASH分區(qū)的表,然后插入一個包含有適當值的記錄,再檢查對文件系統(tǒng)的作用,來驗證這一點。假定有使用下面的語句在測試數(shù)據(jù)庫中創(chuàng)建了一個表tnhash

CREATE TABLE tnhash (
??? id INT,
??? name VARCHAR(5)
)
PARTITION BY HASH(id)
PARTITIONS 2;

假如Linux 上的MySQL 的一個RPM安裝,這個語句在目錄/var/lib/mysql/test創(chuàng)建了兩個.MYD文件,這兩個文件可以在bash shell中查看,結(jié)果如下:

/var/lib/mysql/test> ls *.MYD -l
-rw-rw----? 1 mysql mysql 0 2005-11-04 18:41 tnhash_p0.MYD
-rw-rw----? 1 mysql mysql 0 2005-11-04 18:41 tnhash_p1.MYD

注意:每個文件的大小為0字節(jié)?,F(xiàn)在在表tnhash 中插入一行id列值為NULL的行,然后驗證該行已經(jīng)被插入:

mysql> INSERT INTO tnhash VALUES (NULL, 'sam');
Query OK, 1 row affected (0.00 sec)
?
mysql> SELECT * FROM tnhash;
+------+------+
| id?? | name |
+------+------+
| NULL | sam? |
+------+------+
1 row in set (0.01 sec)

回想一下,對于任意的整數(shù)N,NULL MOD N 的值總是等于NULL。這個結(jié)果在確定正確的分區(qū)方面被認為是0?;氐较到y(tǒng)shell(仍然假定bash用于這個目的) ,通過再次列出數(shù)據(jù)文件,可以看出值被成功地插入到第一個分區(qū)(默認名稱為p0)中:

var/lib/mysql/test> ls *.MYD -l
-rw-rw----? 1 mysql mysql 20 2005-11-04 18:44 tnhash_p0.MYD
-rw-rw----? 1 mysql mysql? 0 2005-11-04 18:41 tnhash_p1.MYD

可以看出INSERT語句只修改了文件tnhash_p0.MYD,它在磁盤上的尺寸增加了,而沒有影響其他的文件。

假定有下面的一個表:

CREATE TABLE tndate (
??? id INT,
??? dt DATE
)
PARTITION BY RANGE( YEAR(dt) ) (
??? PARTITION p0 VALUES LESS THAN (1990),
??? PARTITION p1 VALUES LESS THAN (2000),
??? PARTITION p2 VALUES LESS THAN MAXVALUE
);

像其他的MySQL函數(shù)一樣,YEAR(NULL)返回NULL值。一個dt列值為NULL的行,其分區(qū)表達式的計算結(jié)果被視為0,該行被插入到分區(qū)p0中。

18.3.?分區(qū)管理

18.3.1. RANGE和LIST分區(qū)的管理
18.3.2. HASH和KEY分區(qū)的管理
18.3.3. 分區(qū)維護
18.3.4. 獲取關(guān)于分區(qū)的信息

MySQL 5.1 提供了許多修改分區(qū)表的方式。添加、刪除、重新定義、合并或拆分已經(jīng)存在的分區(qū)是可能的。所有這些操作都可以通過使用ALTER TABLE 命令的分區(qū)擴展來實現(xiàn)(關(guān)于語法的定義,請參見13.1.2節(jié),“ALTER TABLE語法” )。也有獲得分區(qū)表和分區(qū)信息的方式。在本節(jié),我們討論下面這些主題:

·???????? RANGELIST分區(qū)的表的分區(qū)管理的有關(guān)信息,請參見18.3.1節(jié),“RANGE和LIST分區(qū)的管理”。

·???????? 關(guān)于HASHKEY分區(qū)管理的討論,請參見18.3.2節(jié),“HASH和KEY分區(qū)的管理”。

·???????? MySQL 5.1中提供的、獲得關(guān)于分區(qū)表和分區(qū)信息的機制的討論,請參見18.3.4節(jié),“獲取關(guān)于分區(qū)的信息”

·???????? 關(guān)于執(zhí)行分區(qū)維護操作的討論,請參見18.3.3節(jié),“分區(qū)維護”。

注釋:在MySQL 5.1中,一個分區(qū)表的所有分區(qū)都必須有子分區(qū)同樣的名字,并且一旦表已經(jīng)創(chuàng)建,再改變子分區(qū)是不可能的。

要點:當前,從5.1系列起建立的MySQL 服務器就把“ALTER TABLE ... PARTITION BY ...”作為有效的語法,但是這個語句目前還不起作用。我們期望MySQL 5.1達到生產(chǎn)狀態(tài)時,能夠按照下面的描述實現(xiàn)該語句的功能。

要改變一個表的分區(qū)模式,只需要使用帶有一個“partition_options”子句的ALTER TABLE 的命令。這個子句和與創(chuàng)建一個分區(qū)表的CREATE TABLE命令一同使用的子句有相同的語法,并且總是以關(guān)鍵字PARTITION BY 開頭。例如,假設有一個使用下面CREATE TABLE語句建立的按照RANGE分區(qū)的表:

CREATE TABLE trb3 (id INT, name VARCHAR(50), purchased DATE)
??? PARTITION BY RANGE(YEAR(purchased))
??? (
??????? PARTITION p0 VALUES LESS THAN (1990),
??????? PARTITION p1 VALUES LESS THAN (1995),
????? ??PARTITION p2 VALUES LESS THAN (2000),
??????? PARTITION p3 VALUES LESS THAN (2005)
??? );

現(xiàn)在,要把這個表按照使用id列值作為鍵的基礎(chǔ),通過KEY分區(qū)把它重新分成兩個分區(qū),可以使用下面的語句:

ALTER TABLE trb3 PARTITION BY KEY(id) PARTITIONS 2;

這和先刪除這個表、然后使用“CREATE TABLE trb3 PARTITION BY KEY(id) PARTITIONS 2”重新創(chuàng)建這個表具有同樣的效果。

18.3.1.?RANGE和LIST分區(qū)的管理

關(guān)于如何添加和刪除分區(qū)的處理,RANGELIST分區(qū)非常相似?;谶@個原因,我們在本節(jié)討論這兩種分區(qū)的管理。關(guān)于HASHKEY分區(qū)管理的信息,請參見18.3.2節(jié),“HASH和KEY分區(qū)的管理”。刪除一個RANGELIST分區(qū)比增加一個分區(qū)要更加簡單易懂,所以我們先討論前者。

從一個按照RANGELIST分區(qū)的表中刪除一個分區(qū),可以使用帶一個DROP PARTITION子句的ALTER TABLE命令來實現(xiàn)。這里有一個非?;镜睦?,假設已經(jīng)使用下面的CREATE TABLEINSERT語句創(chuàng)建了一個按照RANGE分區(qū)的表,并且已經(jīng)插入了10條記錄:

mysql> CREATE TABLE tr (id INT, name VARCHAR(50), purchased DATE)
??? ->???? PARTITION BY RANGE(YEAR(purchased))
??? ->???? (
??? ->???????? PARTITION p0 VALUES LESS THAN (1990),
??? ->???????? PARTITION p1 VALUES LESS THAN (1995),
??? ->???????? PARTITION p2 VALUES LESS THAN (2000),
??? ->???????? PARTITION p3 VALUES LESS THAN (2005)
??? ->???? );
Query OK, 0 rows affected (0.01 sec)
?
mysql> INSERT INTO tr VALUES
??? ->???? (1, 'desk organiser', '2003-10-15'),
??? ->???? (2, 'CD player', '1993-11-05'),
??? ->???? (3, 'TV set', '1996-03-10'),
??? ->???? (4, 'bookcase', '1982-01-10'),
??? ->???? (5, 'exercise bike', '2004-05-09'),
??? ->???? (6, 'sofa', '1987-06-05'),
??? ->???? (7, 'popcorn maker', '2001-11-22'),
??? ->???? (8, 'aquarium', '1992-08-04'),
??? ->???? (9, 'study desk', '1984-09-16'),
??? ->???? (10, 'lava lamp', '1998-12-25');
Query OK, 10 rows affected (0.01 sec)????????????????? 

可以通過使用下面的命令查看那些記錄已經(jīng)插入到了分區(qū)p2中:

mysql> SELECT * FROM tr
??? -> WHERE purchased BETWEEN '1995-01-01' AND '1999-12-31';
+------+-----------+------------+
| id?? | name????? | purchased? |
+------+-----------+------------+
|??? 3 | TV set??? | 1996-03-10 |
|?? 10 | lava lamp | 1998-12-25 |
+------+-----------+------------+
2 rows in set (0.00 sec)

要刪除名字為p2的分區(qū),執(zhí)行下面的命令:

mysql> ALTER TABLE tr DROP PARTITION p2;
Query OK, 0 rows affected (0.03 sec)

記住下面一點非常重要:當刪除了一個分區(qū),也同時刪除了該分區(qū)中所有的數(shù)據(jù)。可以通過重新運行前面的SELECT查詢來驗證這一點:

mysql> SELECT * FROM tr WHERE purchased 
????-> BETWEEN '1995-01-01' AND '1999-12-31';
Empty set (0.00 sec)

如果希望從所有分區(qū)刪除所有的數(shù)據(jù),但是又保留表的定義和表的分區(qū)模式,使用TRUNCATE TABLE命令。請參見13.2.9節(jié),“TRUNCATE語法”)。

如果希望改變表的分區(qū)而又不丟失數(shù)據(jù),使用“ALTER TABLE ... REORGANIZE PARTITION”語句。參見下面的內(nèi)容,或者在13.1.2節(jié),“ALTER TABLE語法” 中參考關(guān)于REORGANIZE PARTITION的信息。

如果現(xiàn)在執(zhí)行一個SHOW CREATE TABLE命令,可以觀察到表的分區(qū)結(jié)構(gòu)是如何被改變的:

mysql> SHOW CREATE TABLE tr\G
*************************** 1. row ***************************
?????? Table: tr
Create Table: CREATE TABLE `tr` (
? `id` int(11) default NULL,
? `name` varchar(50) default NULL,
? `purchased` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 
PARTITION BY RANGE (YEAR(purchased)) (
? PARTITION p0 VALUES LESS THAN (1990) ENGINE = MyISAM, 
??PARTITION p1 VALUES LESS THAN (1995) ENGINE = MyISAM, 
??PARTITION p3 VALUES LESS THAN (2005) ENGINE = MyISAM
)
1 row in set (0.01 sec)

如果插入購買日期列的值在'1995-01-01''2004-12-31'之間(含)的新行到已經(jīng)修改后的表中時,這些行將被保存在分區(qū)p3中??梢酝ㄟ^下面的方式來驗證這一點:

mysql> INSERT INTO tr VALUES (11, 'pencil holder', '1995-07-12');
Query OK, 1 row affected (0.00 sec)
?
mysql> SELECT * FROM tr WHERE purchased 
????-> BETWEEN '1995-01-01' AND '2004-12-31';
+------+----------------+------------+
| id?? | name?????????? | purchased? |
+------+----------------+------------+
|?? 11 | pencil holder? | 1995-07-12 |
|??? 1 | desk organiser | 2003-10-15 |
|??? 5 | exercise bike? | 2004-05-09 |
|??? 7 | popcorn maker? | 2001-11-22 |
+------+----------------+------------+
4 rows in set (0.00 sec)
?
mysql> ALTER TABLE tr DROP PARTITION p3;
Query OK, 0 rows affected (0.03 sec)
?
mysql> SELECT * FROM tr WHERE purchased 
????-> BETWEEN '1995-01-01' AND '2004-12-31';
Empty set (0.00 sec)

注意:由“ALTER TABLE ... DROP PARTITION”語句引起的、從表中刪除的行數(shù)并沒有被服務器報告出來,就好像通過同等的DELETE查詢操作一樣。

刪除LIST分區(qū)使用和刪除RANGE分區(qū)完全相同的“ALTER TABLE ... DROP PARTITION”語法。但是,在對其后使用這個表的影響方面,還是有重大的區(qū)別:在這個表中,再也不能插入這么一些行,這些行的列值包含在定義已經(jīng)刪除了的分區(qū)的值列表中 (有關(guān)示例,請參見18.2.2節(jié),“LIST分區(qū)”

要增加一個新的RANGELIST分區(qū)到一個前面已經(jīng)分區(qū)了的表,使用“ALTER TABLE ... ADD PARTITION”語句。對于使用RANGE分區(qū)的表,可以用這個語句添加新的區(qū)間到已有分區(qū)的序列的前面或后面。例如,假設有一個包含你所在組織的全體成員數(shù)據(jù)的分區(qū)表,該表的定義如下:

CREATE TABLE members (
??? id INT, 
????fname VARCHAR(25),
??? lname VARCHAR(25), 
????dob DATE
)
PARTITION BY RANGE(YEAR(dob)) (
??? PARTITION p0 VALUES LESS THAN (1970),
??? PARTITION p1 VALUES LESS THAN (1980),
??? PARTITION p2 VALUES LESS THAN (1990)
);

進一步假設成員的最小年紀是16歲。隨著日歷接近2005年年底,你會認識到不久將要接納1990年(以及以后年份)出生的成員??梢园凑障旅娴姆绞剑薷某蓡T表來容納出生在19901999年之間的成員:

ALTER TABLE ADD PARTITION (PARTITION p3 VALUES LESS THAN (2000));

要點:對于通過RANGE分區(qū)的表,只可以使用ADD PARTITION添加新的分區(qū)到分區(qū)列表的高端。設法通過這種方式在現(xiàn)有分區(qū)的前面或之間增加一個新的分區(qū),將會導致下面的一個錯誤:

mysql> ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (1960));
錯誤1463 (HY000): 對每個分區(qū),VALUES LESS THAN 值必須嚴格增長

采用一個類似的方式,可以增加新的分區(qū)到已經(jīng)通過LIST分區(qū)的表。例如,假定有如下定義的一個表:

CREATE TABLE tt (
??? id INT, 
????data INT
)
PARTITION BY LIST(data) (
??? PARTITION p0 VALUES IN (5, 10, 15),
??? PARTITION p1 VALUES IN (6, 12, 18)
);

可以通過下面的方法添加一個新的分區(qū),用來保存擁有數(shù)據(jù)列值71421的行:

ALTER TABLE tt ADD PARTITION (PARTITION p2 VALUES IN (7, 14, 21));

注意:不能添加這樣一個新的LIST分區(qū),該分區(qū)包含有已經(jīng)包含在現(xiàn)有分區(qū)值列表中的任意值。如果試圖這樣做,將會導致錯誤:

mysql> ALTER TABLE tt ADD PARTITION (PARTITION np VALUES IN (4, 8, 12));
錯誤1465 (HY000): LIST分區(qū)中,同一個常數(shù)的多次定義

因為帶有數(shù)據(jù)列值12的任何行都已經(jīng)分配給了分區(qū)p1,所以不能在表tt上再創(chuàng)建一個其值列表包括12的新分區(qū)。為了實現(xiàn)這一點,可以先刪除分區(qū)p1,添加分區(qū)np,然后使用修正后的定義添加一個新的分區(qū)p1。但是,正如我們前面討論過的,這將導致保存在分區(qū)p1中的所有數(shù)據(jù)丟失——而這往往并不是你所真正想要做的。另外一種解決方法可能是,建立一個帶有新分區(qū)的表的副本,然后使用“CREATE TABLE ... SELECT ...”把數(shù)據(jù)拷貝到該新表中,然后刪除舊表,重新命名新表,但是,當需要處理大量的數(shù)據(jù)時,這可能是非常耗時的。在需要高可用性的場合,這也可能是不可行的。

幸運地是,MySQL 的分區(qū)實現(xiàn)提供了在不丟失數(shù)據(jù)的條件下重新定義分區(qū)的方式。讓我們首先看兩個涉及到RANGE分區(qū)的簡單例子?;叵胍幌卢F(xiàn)在定義如下的成員表:

mysql> SHOW CREATE TABLE members\G
*************************** 1. row ***************************
?????? Table: members
Create Table: CREATE TABLE `members` (
? `id` int(11) default NULL,
? `fname` varchar(25) default NULL,
? `lname` varchar(25) default NULL,
? `dob` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 
PARTITION BY RANGE (YEAR(dob)) (
? PARTITION p0 VALUES LESS THAN (1970) ENGINE = MyISAM, 
??PARTITION p1 VALUES LESS THAN (1980) ENGINE = MyISAM, 
??PARTITION p2 VALUES LESS THAN (1990) ENGINE = MyISAM.
? PARTITION p3 VALUES LESS THAN (2000) ENGINE = MyISAM
)

假定想要把表示出生在1960年前成員的所有行移入到一個分開的分區(qū)中。正如我們前面看到的,不能通過使用“ALTER TABLE ... ADD PARTITION”來實現(xiàn)這一點。但是,要實現(xiàn)這一點,可以使用ALTER TABLE上的另外一個與分區(qū)有關(guān)的擴展,具體實現(xiàn)如下:

ALTER TABLE members REORGANIZE PARTITION p0 INTO (
??? PARTITION s0 VALUES LESS THAN (1960),
??? PARTITION s1 VALUES LESS THAN (1970)
);

實際上,這個命令把分區(qū)p0分成了兩個新的分區(qū)s0s1。同時,它還根據(jù)包含在兩個“PARTITION ... VALUES ...”子句中的規(guī)則,把保存在分區(qū)p0中的數(shù)據(jù)移入到兩個新的分區(qū)中,所以分區(qū)s0中只包含YEAR(dob)小于1960的那些行,s1中包含那些YEAR(dob)大于或等于1960但是小于1970的行。

一個REORGANIZE PARTITION語句也可以用來合并相鄰的分區(qū)??梢允褂萌缦碌恼Z句恢復成員表到它以前的分區(qū):

ALTER TABLE members REORGANIZE PARTITION s0,s1 INTO (
??? PARTITION p0 VALUES LESS THAN (1970)
)

使用“REORGANIZE PARTITION”拆分或合并分區(qū),沒有數(shù)據(jù)丟失。在執(zhí)行上面的語句中,MySQL 把保存在分區(qū)s0s1中的所有數(shù)據(jù)都移到分區(qū)p0中。

“REORGANIZE PARTITION”的基本語法是:

ALTER TABLE tbl_name REORGANIZE PARTITION partition_list INTO (partition_definitions)

其中,tbl_name 是分區(qū)表的名稱,partition_list 是通過逗號分開的、一個或多個將要被改變的現(xiàn)有分區(qū)的列表。partition_definitions 是一個是通過逗號分開的、新分區(qū)定義的列表,它遵循與用在“CREATE TABLE”中的partition_definitions 相同的規(guī)則 (請參見13.1.5節(jié),“CREATE TABLE語法”)。應當注意到,在把多少個分區(qū)合并到一個分區(qū)或把一個分區(qū)拆分成多少個分區(qū)方面,沒有限制。例如,可以重新組織成員表的四個分區(qū)成兩個分區(qū),具體實現(xiàn)如下:

ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
??? PARTITION m0 VALUES LESS THAN (1980),
??? PARTITION m1 VALUES LESS THAN (2000)
)

同樣,對于按LIST分區(qū)的表,也可以使用REORGANIZE PARTITION。讓我們回到那個問題,即增加一個新的分區(qū)到已經(jīng)按照LIST分區(qū)的表tt中,但是因為該新分區(qū)有一個值已經(jīng)存在于現(xiàn)有分區(qū)的值列表中,添加新的分區(qū)失敗。我們可以通過先添加只包含非沖突值的分區(qū),然后重新組織該新分區(qū)和現(xiàn)有的那個分區(qū),以便保存在現(xiàn)有的那個分區(qū)中的值現(xiàn)在移到了新的分區(qū)中,來處理這個問題:

ALTER TABLE tt ADD PARTITION (PARTITION np VALUES IN (4, 8));
ALTER TABLE tt REORGANIZE PARTITION p1,np INTO (
??? PARTITION p1 VALUES IN (6, 18),
??? PARTITION np VALUES in (4, 8, 12)
);

當使用“ALTER TABLE ... REORGANIZE PARTITION”來對已經(jīng)按照RANGELIST分區(qū)表進行重新分區(qū)時,下面是一些要記住的關(guān)鍵點:

·???????? 用來確定新分區(qū)模式的PARTITION子句使用與用在CREATE TABLE中確定分區(qū)模式的PARTITION子句相同的規(guī)則。

最重要的是,應該記?。盒路謪^(qū)模式不能有任何重疊的區(qū)間(適用于按照RANGE分區(qū)的表)或值集合(適用于重新組織按照LIST分區(qū)的表)。

·???????? partition_definitions 列表中分區(qū)的合集應該與在partition_list 中命名分區(qū)的合集占有相同的區(qū)間或值集合。

例如,在本節(jié)中用作例子的成員表中,分區(qū)p1p2總共覆蓋了19801999的這些年。因此,對這兩個分區(qū)的重新組織都應該覆蓋相同范圍的年份。

·???????? 對于按照RANGE分區(qū)的表,只能重新組織相鄰的分區(qū);不能跳過RANGE分區(qū)。

例如,不能使用以“ALTER TABLE members REORGANIZE PARTITION p0,p2 INTO ...”開頭的語句,來重新組織本節(jié)中用作例子的成員表。因為,p0覆蓋了1970年以前的年份,而p2覆蓋了從19901999(包括19901999)之間的年份,因而這兩個分區(qū)不是相鄰的分區(qū)。

·???????? 不能使用REORGANIZE PARTITION來改變表的分區(qū)類型;也就是說,例如,不能把RANGE分區(qū)變?yōu)?span>HASH分區(qū),反之亦然。也不能使用該命令來改變分區(qū)表達式或列。如果想在不刪除和重建表的條件下實現(xiàn)這兩個任務,可以使用“ALTER TABLE ... PARTITION BY ....”,例如:

·??????????????? ALTER TABLE members 
·??????????????? ????PARTITION BY HASH(YEAR(dob))
·??????????????? ????PARTITIONS 8

注釋MySQL 5.1發(fā)布前的版本中,“ALTER TABLE ... PARTITION BY ...”還沒有實現(xiàn)。作為替代,要么使用先刪除表,然后使用想要的分區(qū)重建表,或者——如果需要保留已經(jīng)存儲在表中的數(shù)據(jù)——可以使用“CREATE TABLE ... SELECT ...”來創(chuàng)建新的表,然后從舊表中把數(shù)據(jù)拷貝到新表中,再刪除舊表,如有必要,最后重新命名新表。

18.3.2.?HASH和KEY分區(qū)的管理

在改變分區(qū)設置方面,按照HASH分區(qū)或KEY分區(qū)的表彼此非常相似,但是它們又與按照RANGELIST分區(qū)的表在很多方面有差別。所以,本節(jié)只討論按照HASHKEY分區(qū)表的修改。關(guān)于添加和刪除按照RANGELIST進行分區(qū)的表的分區(qū)的討論,參見18.3.1節(jié),“RANGE和LIST分區(qū)的管理”。

不能使用與從按照RANGELIST分區(qū)的表中刪除分區(qū)相同的方式,來從HASHKEY分區(qū)的表中刪除分區(qū)。但是,可以使用“ALTER TABLE ... COALESCE PARTITION”命令來合并HASHKEY分區(qū)。例如,假定有一個包含顧客信息數(shù)據(jù)的表,它被分成了12個分區(qū)。該顧客表的定義如下:

CREATE TABLE clients (
??? id INT,
??? fname VARCHAR(30),
? ??lname VARCHAR(30),
??? signed DATE
)
PARTITION BY HASH( MONTH(signed) )
PARTITIONS 12;

要減少分區(qū)的數(shù)量從126,執(zhí)行下面的ALTER TABLE命令:

mysql> ALTER TABLE clients COALESCE PARTITION 6
Query OK, 0 rows affected (0.02 sec)

對于按照HASH,KEYLINEAR HASH,或LINEAR KEY分區(qū)的表, COALESCE能起到同樣的作用。下面是一個類似于前面例子的另外一個例子,它們的區(qū)別只是在于表是按照LINEAR KEY 進行分區(qū):

mysql> CREATE TABLE clients_lk (
??? ->???? id INT,
??? ->???? fname VARCHAR(30),
??? ->???? lname VARCHAR(30),
??? ->???? signed DATE
??? -> )
??? -> PARTITION BY LINEAR KEY(signed)
??? -> PARTITIONS 12;
Query OK, 0 rows affected (0.03 sec)
?
mysql> ALTER TABLE clients_lk COALESCE PARTITION 6;
Query OK, 0 rows affected (0.06 sec)
Records: 0? Duplicates: 0? Warnings: 0

COALESCE不能用來增加分區(qū)的數(shù)量,如果你嘗試這么做,結(jié)果會出現(xiàn)類似于下面的錯誤:

mysql> ALTER TABLE clients COALESCE PARTITION 18;
錯誤1478 (HY000): 不能移動所有分區(qū),使用DROP TABLE代替

要增加顧客表的分區(qū)數(shù)量從1218,使用“ALTER TABLE ... ADD PARTITION”,具體如下:

ALTER TABLE clients ADD PARTITION PARTITIONS 18;

注釋ALTER TABLE ... REORGANIZE PARTITION”不能用于按照HASHHASH分區(qū)的表。

18.3.3.?分區(qū)維護

注釋實際上,本節(jié)討論的命令還沒有在MySQL 5.1中實現(xiàn), 在這里提出的目的,是為了在5.1版投產(chǎn)前的開發(fā)周期期間,引出來自用戶測試該軟件的反饋意見。(換句話說,就是“請不要反饋這樣的缺陷,說這些命令不起作用”)。隨著MySQL5.1版開發(fā)的繼續(xù),這些信息很有可能發(fā)生變化。隨著分區(qū)功能的實現(xiàn)和提高,我們將更新本節(jié)的內(nèi)容。

MySQL 5.1中可以執(zhí)行許多分區(qū)維護的任務。對于分區(qū)表,MySQL不支持命令CHECK TABLE,OPTIMIZE TABLEANALYZE TABLE,或REPAIR TABLE。作為替代,可以使用ALTER TABLE 的許多擴展來在一個或多個分區(qū)上直接地執(zhí)行這些操作,如下面列出的那樣:

·???????? 重建分區(qū): 這和先刪除保存在分區(qū)中的所有記錄,然后重新插入它們,具有同樣的效果。它可用于整理分區(qū)碎片。

示例:

ALTER TABLE t1 REBUILD PARTITION (p0, p1);

·???????? 優(yōu)化分區(qū):如果從分區(qū)中刪除了大量的行,或者對一個帶有可變長度的行(也就是說,有VARCHARBLOB,或TEXT類型的列)作了許多修改,可以使用“ALTER TABLE ... OPTIMIZE PARTITION”來收回沒有使用的空間,并整理分區(qū)數(shù)據(jù)文件的碎片。

示例:

ALTER TABLE t1 OPTIMIZE PARTITION (p0, p1);

在一個給定的分區(qū)表上使用“OPTIMIZE PARTITION”等同于在那個分區(qū)上運行CHECK PARTITIONANALYZE PARTITION,和REPAIR PARTITION。

·???????? 分析分區(qū):讀取并保存分區(qū)的鍵分布。

示例:

ALTER TABLE t1 ANALYZE PARTITION (p3);

·???????? 修補分區(qū): 修補被破壞的分區(qū)。

示例:

ALTER TABLE t1 REPAIR PARTITION (p0,p1);

·???????? 檢查分區(qū): 可以使用幾乎與對非分區(qū)表使用CHECK TABLE 相同的方式檢查分區(qū)。

示例:

ALTER TABLE trb3 CHECK PARTITION (p1);

這個命令可以告訴你表t1的分區(qū)p1中的數(shù)據(jù)或索引是否已經(jīng)被破壞。如果發(fā)生了這種情況,使用“ALTER TABLE ... REPAIR PARTITION”來修補該分區(qū)。

還可以使用mysqlcheckmyisamchk 應用程序,在對表進行分區(qū)時所產(chǎn)生的、單獨的MYI文件上進行操作,來完成這些任務。請參見8.7節(jié),“mysqlcheck:表維護和維修程序”。(在pre-alpha編碼中,這個功能已經(jīng)可以使用)。

18.3.4.?獲取關(guān)于分區(qū)的信息

本節(jié)討論獲取關(guān)于現(xiàn)有分區(qū)的信息。這個功能仍然處于計劃階段,所以現(xiàn)階段在這里描述的,實際上是我們想要在MySQL 5.1中實現(xiàn)的一個概觀。

如在本章中別處討論的一樣,在SHOW CREATE TABLE的輸出中包含了用于創(chuàng)建分區(qū)表的PARTITION BY子句。例如:

mysql> SHOW CREATE TABLE trb3\G
*************************** 1. row ***************************
??? ???Table: trb3
Create Table: CREATE TABLE `trb3` (
? `id` int(11) default NULL,
? `name` varchar(50) default NULL,
? `purchased` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 
PARTITION BY RANGE (YEAR(purchased)) (
? PARTITION p0 VALUES LESS THAN (1990) ENGINE = MyISAM, 
??PARTITION p1 VALUES LESS THAN (1995) ENGINE = MyISAM, 
??PARTITION p2 VALUES LESS THAN (2000) ENGINE = MyISAM, 
??PARTITION p3 VALUES LESS THAN (2005) ENGINE = MyISAM
)
1 row in set (0.00 sec)

注釋:當前,對于按HASHKEY分區(qū)的表,PARTITIONS子句并不顯示。 (Bug #14327)

SHOW TABLE STATUS用于分區(qū)表,它的輸出與用于非分區(qū)表的輸出相同,除了引擎(Engine)列總是包含'PARTITION'值。(關(guān)于這個命令的更多信息,參見13.5.4.18節(jié),“SHOW TABLE STATUS語法”)。要獲取單個分區(qū)的狀態(tài)信息,我們計劃實現(xiàn)一個SHOW PARTITION STATUS命令請參見下面)。

計劃用于分區(qū)表的、兩個附加的SHOW命令是:

·???????? SHOW PARTITIONS

這個命令預期其功能類似于SHOW TABLESSHOW DATABASES,除了該命令將列出的是分區(qū)而不是表或數(shù)據(jù)庫。這個命令的輸出可能包含單個稱為Partitions_in_tbl_name 的列,其中tbl_name 是分區(qū)表的名字。對于SHOW TABLES命令而言,如果一旦選擇了一個數(shù)據(jù)庫,隨后該數(shù)據(jù)庫將作為SHOW TABLES命令的默認數(shù)據(jù)庫。但是由于SHOW PARTITIONS命令不可能用這樣的方式來選擇一個表,它很可能需要使用FROM子句,以便MySQL知道要顯示的是哪個表的分區(qū)信息。

·???????? SHOW PARTITION STATUS

這個命令將提供關(guān)于一個或多個分區(qū)的詳細狀態(tài)信息。它的輸出很可能包含有與SHOW TABLE STATUS 的輸出相同或類似的列,此外,還包括顯示用于分區(qū)的數(shù)據(jù)和索引路徑的附加列。這個命令可能支持LIKEFROM子句,這樣使得通過名字獲得關(guān)于一個給定分區(qū)的信息,或者獲得關(guān)于屬于指定表或數(shù)據(jù)庫的分區(qū)的信息,成為可能。

擴展INFORMATION_SCHEMA 數(shù)據(jù)庫的計劃也在進行中,以便提供關(guān)于分區(qū)表和分區(qū)的信息。這個計劃當前還處一個在非常早的階段;隨著補充的信息變得可用,以及任何新的、與分區(qū)有關(guān)的INFORMATION_SCHEMA擴展得以實現(xiàn),我們將更新手冊相關(guān)部分的內(nèi)容。


這是MySQL參考手冊的翻譯版本,關(guān)于MySQL參考手冊,請訪問dev.mysql.com。原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。

上一篇: 下一篇: