layout: post
title: "MySQL體系結構與數據類型"
date: 2018-02-26
categories: MySQL
tags: MySQL
---html
數據庫
--->表--->字段/索引
--->存儲過程
--->觸發器
--->事件
--->...前端
-- 登陸數據庫 mysql -S /tmp/mysql3376.sock -- 查看當前有哪些數據庫 show databases; information_schema 字典庫 performance_schema 性能相關的字典庫 -- 建立數據庫 create database wubx; -- 建立的數據庫對應datadir下的一個目錄 /data/mysql/mysql3376/data/wubx -- mysql裏把view當成Tb對待了 -- MySQL是一個面向存儲引擎解決方案的DB -- 查看mysql的引擎 show engines; -- 還有其餘引擎 inforbright/InfiniDB/Spider/dblink:connect -- OLTP環境:推薦使用InnoDB -- Memory引擎的一個坑 -- 對於內存表,數據庫重啓時,系統會自動發起一個truncate table mem_tb -- 對於內存表,最好的方法是:在複製中最好忽略 -- 調用關係 mysql.server->mysqld_safe->mysqld
drop database test; truncate table mysql.db;
http://www.javashuo.com/article/p-wzbyjghd-gk.htmlmysql
從速度上來講:drop > truncate > deletegit
怎麼用:github
可以把這個圖歸納性的說一遍sql
http://blog.csdn.net/happylee6688/article/details/47150515shell
1)Connectors:不一樣語言中與SQL的交互數據庫
下圖是mysql的默認鏈接數後端
2)Management Services & Utilities:系統管理和控制工具緩存
3)Connection Pool:鏈接池
管理緩衝用戶鏈接、線程處理等須要緩存的需求
4)SQL Interface:SQL接口
接受用戶的SQL命令,而且返回用戶須要查詢的結果
5)Parser:解析器
驗證和解析SQL
6)Optimizer:查詢優化器
查詢前對SQL進行優化
接入層:負責認證,每一個鏈接都是一個線程,分配PGA Serv 包括:SQL接口,解析,優化,Cache/buffer 存儲引擎 文件系統 推薦文件系統 xfs MySQL裏,每一個鏈接都是一個線程 一個系統的併發度是有限的 線程數太多,反而系統的處理能力降低 隨着鏈接數上長,反而性能降低 版本對應的最大鏈接數 5.1 < 64 5.5 < 128 5.6 < 200 5.7 < 200,300 一個問題: 前端:LVS掛了5臺WEB 後端:1組Cache,3組DB 單組DB鏈接數達6千多 解決方案: 1.引入中間件kingshard 2.thread-pool 在percona,mariadb屬於自帶的免費的
error log 錯誤日誌
看[ERROR]和[WARNING]
general log
默認沒有打開
打開以後有什麼用呢?
分析mysqldump的原理
分析mydumper的原理
分析innbackupex的原理
# 全局 set global general_log=on; # session set general_log=on; # 查看日誌輸出到哪? show global variables like "%general%"; # 默認輸出路徑在 datadir/`hostname`.log
binary log
全部寫操做都會在binary log中記錄
數據庫的複製也是使用的binary log
slow log
long_query_time = 10s
建議改爲1s
DML語句(INSERT,UPDATE,DELETE)在處理中鎖等待的時間不記錄
SELECT語句中鎖等待的時間會記錄
execute_time > long_query_time
execute_time不包含DML中的鎖等待時間
沒有目的的看源碼沒有產出
拿錯誤日誌搜源碼,不必定看源碼,看附近的註釋
Linux的bug社區:https://bugs.mysql.com
https://dev.mysql.com/doc/refman/5.6/en/storage-requirements.html
數據類型
爲了數據庫跑的更快,選擇一個合適的數據類型
實質是:節省IO
全部的SQL調優99%都是節省IO
IOPS (Input/Output Operations Per Second),即每秒進行讀寫(I/O)操做的次數
15000轉/分的硬盤,每秒250次+換道延遲--->每秒150
pic卡 10-45w IOPS
一個InnoDB的Page16K
文件系統裏一個block4k
機械硬盤一個扇區512byte
iops很高,緣由是raid卡緩存在工做
若是raid卡有緩存的話,必定要爲raid卡裝電池
每一個類型佔用多少字節
作容量規劃要用,若是未來須要咱們計算行長,就須要了
Integer Types
age int(3)/age int(1)/age int(20)
int(n)
n表示顯示寬度
zerofill
int作自增主鍵是否是過小了
int作主鍵?只增不刪
bigint作主鍵?(單表能支撐42億數據?)大量寫大量刪
注意:類型的溢出
Fixed-Point Types
固定小數點類型
decimal(M,N)
M表示最大長度,也指字節
N表示小數點後的位數
金額所有以分爲單位存儲
浮點數建索引不能進行等於操做
用區間的形式查詢
decimal(10,0)的替代方案int(10)
Floating-Point Types
浮點數類型
浮點數不能進行等號比較
浮點數的運算比別人多幾步
1.1二進制怎麼表示呢
1.1+1.1呢
下圖僅供參考
timestamp,推薦datetime替換timestamp
https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-6.html
https://dev.mysql.com/doc/refman/5.6/en/datetime.html
text
存儲空間:2^16 select pow(2,16)
char&varchar與text區別
全文索引
text不能有default值
varchar>255byte和text處理同樣
group by和order by都不會用text類型的索引
blob
select pow(2,32)/1024/1024/1024
定長,變長
char定長,varchar變長
存儲長度
char 255
varchar 65533+2長度標記(單位bytes)
測試最大長度是65532
額外開銷
char沒有額外開銷,varchar有額外開銷
char,容量規劃
實際分配的長度是:M字符編碼的長度 等於存儲空間
char(M):M表示字符數
latin1 一個字符就佔1個字節
utf8 一個字符佔3個字節
中文漢字在utf8佔3個字節
2553=765byte
varchar
小於255字節,須要1個字節開銷
大於255字節,須要2個字節的開銷
varchar(200)utf8編碼,實際佔用存儲空間爲 200*3+2(200*3=600>255)
varchar(64)utf8編碼,實際佔用存儲空間爲64*3+1(64*3=192<255)
char和varchar對空格的處理
選用char仍是varchar
通常使用InnoDB
InnoDB自己就是一個變長存儲
trx_id,row-id,rollback,filed_pointer,null-flag,field1,...
數據庫調優:節省IO
InnoDB 推薦varchar
MyISAM這種堆表,char定長分配會更快一點
能不用浮點型就不要用
不是科研場景,基本用不到float
百分比
用decimal
能夠轉成int
座標
有替代方案
轉成地圖位圖信息
金額
不建議用
轉化成分保存成整數
推薦datetime來替換timestamp
數據庫別去存圖片
fastdfs 5.0
ceph
tfs
facebook heystack
emoji 可存,utf8mb4
not null default ''
要有東西落地,先作出東西來
最小最合適原則,減小IO
原則 :快,反3nf
保持表的行寬儘量的小
表的字段數小
大的字段拆分,用主鍵作關聯
避免select *
用啥字段select啥字段
text類型的字段在查詢時會先存儲前20個字節到當前行,後面20字節另外存儲
致使一個問題:訪問一行數據,順序IO讀取-->隨機IO讀取
overflow page,
not null default ''
少一個字節,null佔一個字節,''不佔字節
innodb對NULL列須要下個額外標識
NULL影響索引
推薦 整數自增列作PK
select count(*),count(1),count(col) from tb; 有啥區別
count(*)=count(1)
count(col)會忽略NULL值
推薦count(*) 走主鍵和second index
爲何索引會對SQL有優化呢
B+tree
索引定義:一組有序的數據結構
排序實現:代碼實現???
建索引過程->就是排序
彙集索引:
ICT index cluster table 索引彙集表
數據以彙集索引排序存儲
彙集索引和數據一塊存儲
InnoDB哪一個索引算是彙集索引?
主鍵 pk
第一個惟一索引
內部生成一個 rowid 6type
B+tree是面向行仍是page
InnoDB的b+tree面向page
InnoDB是面向行存儲的
Page最少要有兩行記錄
什麼樣的字段適合作索引
區別度高,主鍵區別度100%
變化少的
區別度大於多少才適合作索引?
計算方法:select distinct(col)/count(col) from tab; >30%
變化少的
索引列儘量少更新
給索引下個定義
一組有序的數據結構
業務梳理不清楚
業務變化
屬性不可分割
行的惟一性,每行一個主鍵
列不重複,在主鍵的基礎下引入關係表,外鍵,空間換時間
master/slave
mha
pxc
group_id,group_name,port,admin_user,admin_password,last_update
線上環境推薦,每一組數據的端口號都是同樣的,同一組數據庫使用一個端口號
結論:自增主鍵溢出報Dumplicate entry(主鍵重複)錯誤
create table t1(id int not null auto_increment, name varchar(32), primary key(id)); insert into t1(id,name) values(pow(2,31)-1,'wubx'); -- 2147483647 mysql> insert into t1(name) values ('test overflow'); ERROR 1062 (23000): Duplicate entry '2147483647' for key 'PRIMARY'
結論:
drop table if exists t1; -- 不指定精度 create table t1(f float(2)); insert into t1 values(1.234); insert into t1 values(5.678); select f from t1 where f=5.68; select f from t1; -- 指定精度 3,2 表示最大存儲範圍爲[-9.99,9.99] create table t1(f float(3.2));
結論見上述總結
drop table if exists t1; create table t1(name varchar(65533)) charset=latin1 engine=innodb; -- result ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs create table t1(name varchar(65533)) charset=latin1 engine=innodb; -- result Query OK, 0 rows affected (0.01 sec) drop table if exists t2; create table t2(name char(255)) charset=latin1 engine=innodb; -- result Query OK, 0 rows affected (0.00 sec) insert into t2 values(repeat('a', 255)); insert into t2 values(repeat('漢', 255)); drop table if exists t3; create table t3(name char(255)) charset=utf8 engine=innodb; insert into t3 values(repeat('a', 255)); insert into t3 values(repeat('漢', 255));
結論見上述總結
create table t1(v varchar(4), c char(4)); insert into t1 values('',''); insert into t1 values('ab','ab'); insert into t1 values('abcd','abcd'); insert into t1 values('abcdefg','abcdefg'); SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM t1;
mysql workbench ER圖 icaba愛詞霸