MySQL分區表使用方法

来源:https://www.cnblogs.com/huchong/archive/2019/01/07/10231719.html
-Advertisement-
Play Games

1. 確認MySQL伺服器是否支持分區表 命令: show plugins; 2. MySQL分區表的特點 在邏輯上為一個表,在物理上存儲在多個文件中 HASH分區(HASH) HASH分區的特點 根據MOD(分區鍵,分區數)的值把數據行存儲到表的不同分區中 數據可以平均的分佈在各個分區中 HASH ...


1. 確認MySQL伺服器是否支持分區表

命令:

show plugins;

2. MySQL分區表的特點

  • 在邏輯上為一個表,在物理上存儲在多個文件中

HASH分區(HASH)

HASH分區的特點

  • 根據MOD(分區鍵,分區數)的值把數據行存儲到表的不同分區中
  • 數據可以平均的分佈在各個分區中
  • HASH分區的鍵值必須是一個INT類型的值,或是通過函數可以轉為INT類型

如何建立HASH分區表

以INT類型欄位 customer_id為分區鍵

CREATE TABLE `customer_login_log` (
  `customer_id` int(10) unsigned NOT NULL COMMENT '登錄用戶ID',
  `login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '用戶登錄時間',
  `login_ip` int(10) unsigned NOT NULL COMMENT '登錄IP',
  `login_type` tinyint(4) NOT NULL COMMENT '登錄類型:0未成功 1成功'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶登錄日誌表'

PARTITION BY HASH(customer_id)  PARTITIONS 4;

以非INT類型欄位 login_time 為分區鍵(需要先轉換成INT類型)

CREATE TABLE `customer_login_log` (
  `customer_id` int(10) unsigned NOT NULL COMMENT '登錄用戶ID',
  `login_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '用戶登錄時間',
  `login_ip` int(10) unsigned NOT NULL COMMENT '登錄IP',
  `login_type` tinyint(4) NOT NULL COMMENT '登錄類型:0未成功 1成功'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶登錄日誌表'

PARTITION BY HASH(UNIX_TIMESTAMP(login_time))  PARTITIONS 4;

customer_login_log 表如果不分區,在物理磁碟上文件為

customer_login_log.frm    # 存儲表原數據信息
customer_login_log.ibd    # Innodb數據文件

如果按上面的建HASH分區表,則有五個文件

customer_login_log.frm    
customer_login_log#P#p0.ibd
customer_login_log#P#p1.ibd
customer_login_log#P#p2.ibd
customer_login_log#P#p3.ibd

演示

使用起來和不分區是一樣的,看起來只有一個資料庫,其實有多個分區文件,比如我們要插入一條數據,不需要指定分區,MySQL會自動幫我們處理

查詢

範圍分區(RANGE)

RANGE分區特點

  • 根據分區鍵值的範圍把數據行存儲到表的不同分區中
  • 多個分區的範圍要連續,但是不能重疊
  • 預設情況下使用VALUES LESS THAN屬性,即每個分區不包括指定的那個值

如何建立RANGE分區

如果沒有定義p3分區,當插入的customer_id大於29999時會報錯,定義了則超過的數據都存入p3中

RANGE分區的適用場景

  • 分區鍵為日期或是時間類型 (可以使得各個分區表的數據比較均衡,如果按上面的例子中以整型id為分區鍵,假如活躍用戶集中在10000-19999之間,則p1中的數據量就會比其他分區的數據量大很多,這就失去了分區的意義;而且按時間類型分區,如果要按時間順序進行數據的歸檔,則只需要對某一個分區進行歸檔就可以了)
  • 所有查詢中都包括分區鍵(避免跨分區查詢)
  • 定期按分區範圍清理歷史數據

LIST分區

LIST分區的特點

  • 按分區鍵取值的列表進行分區
  • 同範圍分區一樣,各分區的列表值不能重覆
  • 每一行數據必須能找到對應的分區列表,否則數據插入失敗

如何建立LIST分區

如果插入一條login_type為10的數據行,則會報錯

3. 如何為登錄日誌表(customer_login_log)分區

業務場景

  • 用戶每次登錄都會記錄customer_login_log日誌
  • 用戶登錄日誌保存一年,1年後可以刪除或者歸檔

登錄日誌表的分區類型及分區鍵

  • 使用RANGE分區
  • 以login_time為分區鍵

分區後的用戶登錄日誌表

按年份分區存儲,所以用YEAR函數進行了轉化

CREATE TABLE `customer_login_log` (
  `customer_id` int(10) unsigned NOT NULL COMMENT '登錄用戶ID',
  `login_time` DATETIME NOT NULL COMMENT '用戶登錄時間',
  `login_ip` int(10) unsigned NOT NULL COMMENT '登錄IP',
  `login_type` tinyint(4) NOT NULL COMMENT '登錄類型:0未成功 1成功'
) ENGINE=InnoDB 
PARTITION BY RANGE (YEAR(login_time))(
PARTITION p0 VALUES LESS THAN (2017),
PARTITION p1 VALUES LESS THAN (2018),
PARTITION p2 VALUES LESS THAN (2019)
) 

插入並查詢數據

查詢指定表中的分區數據情況

SELECT table_name,partition_name,partition_description,table_rows FROM
information_schema.`PARTITIONS`  WHERE table_name = 'customer_login_log';

再插入2條18年的日誌,會存入p2表中

之前說過建立分區表時,最好建立一個MAXVALUE的分區,這裡之所以沒有建立,是為了數據維護的方便,如果我們建立了MAXVALUE分區,很容易忽視一個問題,當我們2019年有的數據插入時,會自動存入那個MAXVALUE分區中,之後在做數據維護時會不方便,所以沒有建立MAXVALUE分區
而是通過計劃任務的方式,在每年年底的時候增加這個分區,比如我們現在在2018年年底,我們需要在日誌表中為2019年建立日誌分區,否則2019年的日誌都會插入失敗

我們可以通過下麵語句

增加分區

ALTER TABLE customer_login_log ADD PARTITION (PARTITION p3 VALUES LESS THAN(2020))

增加分區,並插入數據

刪除分區

假如我們現在要刪除2016年到2017年間一年的數據,因為我們已經做了分區,所以只需要通過一條語句,刪除p0分區即可

ALTER TABLE customer_login_log DROP PARTITION p0;

可以發現p0分區已被刪除,且2016年的日誌全部被清除了

歸檔分區歷史數據

我們可能有另一種需求對數據進行歸檔

Mysql版本>=5.7,歸檔分區歷史數據非常方便,提供了一個交換分區的方法

分區數據歸檔遷移條件:

  1. MySQL>=5.7
  2. 結構相同
  3. 歸檔到的數據表一定要是非分區表
  4. 非臨時表;不能有外鍵約束
  5. 歸檔引擎要是:archive

建表並交換分區

CREATE TABLE `arch_customer_login_log` (
  `customer_id` INT unsigned NOT NULL COMMENT '登錄用戶ID',
  `login_time` DATETIME NOT NULL COMMENT '用戶登錄時間',
  `login_ip` INT unsigned NOT NULL COMMENT '登錄IP',
  `login_type` TINYINT NOT NULL COMMENT '登錄類型:0未成功 1成功'
) ENGINE=InnoDB ;

ALTER TABLE customer_login_log 
    exchange  PARTITION p1 WITH TABLE arch_customer_login_log;

可以發現,原customer_login_log表中的2017年的數據(p1分區中的數據)已轉移到了arch_customer_login_log表中,但是p1分區未刪除,只是數據轉移了,所以我們還需要執行DROP命令刪除分區,以免有數據插入其中

將歸檔數據的存儲引擎改為歸檔引擎

最後我們將歸檔數據的存儲引擎改為歸檔引擎,命令為

ALTER TABLE customer_login_log  ENGINE=ARCHIVE;

使用歸檔引擎的好處是:它比Innodb所占用的空間更少,但是歸檔引擎只能進行查詢操作,不能進行寫操作

4. 使用分區表的主要事項

  • 結合業務場景選擇分區鍵,避免跨分區查詢
  • 對分區表進行查詢最好在WHERE從句中包含分區鍵
  • 具有主鍵或唯一索引的表,主鍵或唯一索引必須是分區鍵的一部分(這也是為什麼我們上面分區時去掉了主鍵登錄日誌id(login_id)的原因,不然就無法按照上面的按年份進行分區,所以分區表其實更適合在MyISAM引擎中)

關於MyISAM和Innodb的索引區別

1.關於自動增長

myisam引擎的自動增長列必須是索引,如果是組合索引,自動增長可以不是第一列,他可以根據前面幾列進行排序後遞增。

innodb引擎的自動增長咧必須是索引,如果是組合索引也必須是組合索引的第一列。

2.關於主鍵

myisam允許沒有任何索引和主鍵的表存在,

myisam的索引都是保存行的地址。

innodb引擎如果沒有設定主鍵或者非空唯一索引,就會自動生成一個6位元組的主鍵(用戶不可見)

innodb的數據是主索引的一部分,附加索引保存的是主索引的值。

3.關於count()函數

myisam保存有表的總行數,如果select count(*) from table;會直接取出出該值

innodb沒有保存表的總行數,如果使用select count(*) from table;就會遍歷整個表,消耗相當大,但是在加了wehre 條件後,myisam和innodb處理的方式都一樣。

4.全文索引

myisam支持 FULLTEXT類型的全文索引

innodb不支持FULLTEXT類型的全文索引,但是innodb可以使用sphinx插件支持全文索引,並且效果更好。(sphinx 是一個開源軟體,提供多種語言的API介面,可以優化mysql的各種查詢)

5.delete from table

使用這條命令時,innodb不會從新建立表,而是一條一條的刪除數據,在innodb上如果要清空保存有大量數據的表,最 好不要使用這個命令。(推薦使用truncate table,不過需要用戶有drop此表的許可權)

6.索引保存位置

myisam的索引以表名+.MYI文件分別保存。

innodb的索引和數據一起保存在表空間里。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 繼續上節的索引,這次主要總結oracle資料庫的許可權和角色問題! ...
  • 在優化有問題的查詢時,目標應該是找到一個更優的方法獲得實際需要的結果,而不是一定總是要求從MySQL獲取一模一樣的結果集 ...
  • 修改用戶自定義資料庫用戶註意事項 預設架構將是伺服器為此資料庫用戶解析對象名時將搜索的第一個架構。 除非另外指定,否則預設架構將是此資料庫用戶創建的對象所屬的架構。 如果用戶具有預設架構,則將使用預設架構。 如果用戶不具有預設架構,但該用戶是具有預設架構的組的成員,則將使用該組的預設架構。 如果用戶 ...
  • 新增多個表時,如果有同名錶會報錯,導致其中一個表不能正確創建,此時可以用以下語句進行判斷 ...
  • 最近測試服務端的時候,接觸到了redis,之前也看過,但不系統,藉著這次實踐,記錄一下。 一、寫在前面 Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支持網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。 它通常被稱為數據結構伺服器,因為值(va ...
  • 一 安裝準備 1.首先從官網下載PostgreSQL壓縮包(也可以使用yum安裝),我們這裡使用的是10.1的版本 2.將文件上傳到linux服務區目錄(我們這裡放在/root 中) 3.解壓縮 tar -vxf postgresql-10.1.tar 壓縮包格式不同請註意替換命令 4.由於我們這裡 ...
  • 問題描述: 當我們在linux系統上裝載mysql後操作資料庫的時候,會出現中文亂碼問題,比如做插入操作,發現添加到資料庫的數據中文出現亂碼,遠程連接資料庫數據顯示中文亂碼等。 下麵就將解決linux下mysql中文亂碼問題。 環境CentOS-6.5 1.打開Linux視窗,啟動mysql: my ...
  • 正文 The mysqldump client utility performs logical backups, producing a set of SQL statements that can be executed to reproduce the original database ob ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...