傳統數據庫
上篇文章:聊聊數據庫~開篇 https://www.cnblogs.com/dotnetcrazy/p/9690466.html
本來准備直接開講NoSQL的(當時開篇就是說的NoSQL)考慮到有些同志可能連MySQL系都沒接觸過,所以我們2019說數據系的時候預計從MySQL
(穿插MSSQL
)開始,這篇文章就當試水篇,效果好就繼續往下寫~(這篇偏理論和運維)
1.1.MariaDB and MySQL
官方文檔:https://mariadb.com/kb/zh-cn/mariadb
目前主流:MySQL 5.7
or MariaDB 5.5.x
(推薦)
多一句嘴,MySQL
當年被Oracle
收購后,MySQL之父
覺得靠Oracle
維護MySQL
很不靠譜,然后就跳槽弄了個MariaDB
(很多Oracle
競爭對手扶持着),目前MariaDB
是發展最快的MySQL
分支版本(PS:MySQL
現在是雙協議了,大部分公司用的版本都是<=5.7
)
然后得說下遷移問題:MySQL 5.x
到 MariaDB 5.x
基本上是無縫的,MariaDB最新穩定版為:MariaDB 5.5
PS:MariaDB有兩個分支,而10.x分支是不兼容MySQL的
MariaDB
與MySQL
兼容性可以查看:
https://mariadb.com/kb/zh-cn/mariadb-vs-mysql-compatibility/
PS:國內比較火的還有阿里的MySQL分支
:https://github.com/alibaba/AliSQL
不談其他的,咱們看看它們開發的積極程度就知道為什么MariaDB
是主流了
使用概括(推薦)
如果想要使用MariaDB10.x
的同志可以考慮MySQL8.x
(社區完善)
如果想要使用MySQL5.x
的同志可以考慮MariaDB5.5.x
(高性能且兼容)
1.2.MariaDB部署
網絡配置如果不會可以看我以前寫的文章:https://www.cnblogs.com/dunitian/p/6658578.html
1.環境配置和初始化
安裝很簡單,以CentOS
為例:
systemctl start mariadb.service # 啟動MariaDB
systemctl enable mariadb.service # 設置開機啟動
systemctl stop mariadb.service # 停止MariaDB
systemctl restart mariadb.service # 重啟MariaDB
PS:Win安裝注意這一步:
執行文件簡單說明:有時候我們 ps aux | grep mysql
的時候,發現運行的並不是/usr/bin/
下的mysqld
而是mysqld_safe
,那這個mysqld_safe
是啥呢?==> 線程安全的實例
MariaDB
的程序組成:ls /usr/bin | grep mysql
- Client:
mysql
命令行客戶端mysqldump
數據庫備份用mysqladmin
遠程管理工具mysqlbinlog
二進制日志管理工具- ...
- Server:
mysqld_safe
線程安全的實例mysqld_multi
多實例mysqld
mysql_secure_installation
安全初始化工具(記得先啟動數據庫哦)- ...
mysql
的賬號由兩部分組成:username
@host
,MySQL客戶端連接參數:
-u用戶名
:--user
,默認為root
-h服務器主機
:--host
,默認為localhost
host
用於限制用戶可以通過哪些主機連接- 支持通配符:
%
匹配任意長度的任意字符:172.16.0.0/16 ==> 172.16.%.%_
匹配任意單個字符
-p密碼
:--password
,默認為空
- 安裝完成后運行
mysql_secure_installation
來設置密碼並初始化
- 安裝完成后運行
- other:
-P
:--port
,指定端口-D
:--database
,指定數據庫-C
:--compress
,連接數據庫的時候對傳輸的數據壓縮-S
:--socket
,指定socket文件
- MySQL專用:-e "SQL語句",直接執行SQL語句
- mysql -e "show databases"(腳本直接運行)
很多人安裝完成后是這樣設置密碼的:(不推薦)
正確打開方式:mysql_secure_installation
如果允許root遠程登錄:Disallow root login remotely? [Y/n] n
安全初始化后登錄圖示:
2.配置文件
以MariaDB 5.5.60
為例:
- Linux:配置文件查找順序(找不到就往下繼續)
/etc/my.cnf
-->/etc/mysql/conf.d/*.cnf
-->~/.my.cnf
- Windows:
MariaDB安裝目錄/data/my.ini
PS:一般配置文件都會設置這3個
[mysqld]
# 獨立表空間: 每一個表都有一個.frm表描述文件,還有一個.ibd文件
innodb_file_per_table=on
# 不對連接進行DNS解析(省時)
skip_name_resolve=on
# 配置sql_mode
sql_mode='strict_trans_tables'
# 指定數據庫文件存放路徑
# datadir=/mysql/data
# socket=/mysql/data/mysql.sock # 與之對應
其他配置MariaDB
提供了樣本:
[dnt@localhost ~] ls /usr/share/mysql/ | grep .cnf
my-huge.cnf # 超大內存配置參考
my-innodb-heavy-4G.cnf # 4G內存配置參考
my-large.cnf # 大內存配置
my-medium.cnf # 中等內存配置
my-small.cnf # 小內存配置
PS:thread_concurrency
=CPU數*2
最佳,修改配置后記得重啟數據庫
3.遠程訪問
1.之前安全初始化的時候把root
禁止遠程登錄了,現在我們創建一個其他用戶
2.給用戶權限
3.防火牆放行指定端口
4.遠程客戶端測試一下
Code如下:
# root賬戶登錄
mysql -uroot -p
# 新增用戶
insert into mysql.user(user,host,password) values("用戶名","%",password("密碼"));
# 刷新設置
flush privileges;
# 分配權限
grant all privileges on 數據庫.* to 用戶名@"%" identified by "密碼";
# 刷新設置
flush privileges;
# 顯示服務狀態
systemctl status firewalld
# 添加 --permanent永久生效(沒有此參數重啟后失效)
firewall-cmd --zone=public --add-port=3306/tcp --permanent
# 重新載入
firewall-cmd --reload
# 查看
firewall-cmd --zone= public --query-port=3306/tcp
# 刪除
firewall-cmd --zone= public --remove-port=3306/tcp --permanent
SQLServer遠程連接:https://www.cnblogs.com/dunitian/p/5474501.html
擴展:為用戶添加新數據庫的權限
PS:先使用root創建數據庫,然后再授權grant all privileges on 數據庫.* to 用戶名@"%" identified by "密碼";
並刷新flush privileges;
查看權限:show grants for dnt;
效果:
1.3.MySQL部署
之前有園友說,為啥不順便說說UbuntuServer
的部署呢?呃。。。一般來說公司服務器都是CentOS
的占大多數,然后UbuntuServer
更多的是個人雲服務比較多(推薦初創公司使用),畢竟它們兩個系統追求的不太一樣,一個是追求穩(部署麻煩),一個是追求軟件盡量新的情況下穩定(更新太快)
那么長話短說,步入正軌:
1.Ubuntu最常見的包問題
Ubuntu不得不說的就是這個apt
出問題的處理 :(換源就不說了/etc/apt/sources.list
)
# 一般刪除這幾個鎖文件,然后再重新配置下就可以了
sudo rm /var/lib/dpkg/lock
sudo rm /var/lib/dpkg/lock-frontend
sudo rm /var/lib/apt/lists/lock
sudo rm /var/cache/apt/archives/lock
# 簡寫(千萬注意空格,不然你就是rm -rf / + 跑路了)
# sudo rm /var/lib/apt/lists/lock /var/cache/apt/archives/lock /var/lib/dpkg/lock /var/lib/dpkg/lock-frontend
# 重新配置下
sudo dpkg --configure -a
2.安裝注意(Ubuntu的特點就是使用起來簡單)
Ubuntu
推薦使用MySQL
(畢竟同是5.x
用起來基本上差不多,安裝過程和之前說的CentOS 下 MariaDB
差不多,所有命令前加個sudo
)
1.安裝比較簡單:sudo apt install mysql-server -y
2.允許遠程連接:注釋掉 bind-address=127.0.0.1
(/etc/mysql/mysql.conf.d/mysqld.cnf
)
PS:常用配置(/etc/mysql/mysql.conf.d/mysqld.cnf
)
3.關於為什么是這個路徑的說明:sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
4.所有配置修改都需要重新啟動下:sudo systemctl restart mysql
5.第一次初始化和MariaDB不太一樣:sudo mysql_secure_installation
(其他一路y
即可)
需要選下你設置root密碼的復雜度:(一般1就可以了,就算設置再復雜,入了系統也是虛的)
PS:可以看看拓展文章:Ubuntu16安裝mysql5.7未提示輸入密碼,安裝后修改mysql默認密碼 和 【不推薦】修改mysql密碼策略
6.然后輸入密碼你就可以登錄了sudo mysql -uroot -p
(PS:你直接sudo mysql
也可以直接登錄)
這邊我就不像上節課一步步演示了,直接授權和創建一步走了grant all privileges on 數據庫.* to "用戶名"@"%" identified by "復雜密碼";
7.記得flush privileges;
刷新一下系統表
課后拓展:
MySQL5.7.26 忘記Root密碼小計:https://www.cnblogs.com/dotnetcrazy/p/11027732.html
淺析MySQL 8忘記密碼處理方式
https://www.cnblogs.com/wangjiming/p/10363357.html
MySQL5.6更改datadir數據存儲目錄
https://www.cnblogs.com/ding2016/p/7644675.html
擴展:CentOS7安裝MySQL8
CentOS7安裝MySQL8.0安裝小計:https://mp.weixin.qq.com/s/Su3Ivuy5IMeAwYBXaka0ag
MySQL軍規(58)
文章結尾貼一節58
的MySQL
軍規:(適用於並發量大,數據量大的典型互聯網業務)
1.基礎規范
- 表存儲引擎必須使用
InnoDB
- 表字符集默認使用
utf8
,必要時候使用utf8mb4
utf8
通用,無亂碼風險,漢字3字節,英文1字節utf8mb4
是utf8的超集
,存儲4字節時使用(eg:表情符號)
- 禁止使用存儲過程,視圖,觸發器,Event
- 調試,排錯,遷移都比較困難,擴展性較差
- 對數據庫性能影響較大,互聯網業務,能讓站點層和服務層干的事情,不要交到數據庫層
- 禁止在數據庫中存儲大文件(eg:照片)
- 可以將大文件存儲在對象存儲系統,數據庫中存儲路徑
- 禁止在線上環境做數據庫壓力測試
- 測試,開發,線上數據庫環境必須隔離
2.命名規范
- 庫名,表名,列名必須用小寫,采用下划線分隔
- abc,Abc,ABC都是給自己埋坑
- 庫名,表名,列名必須見名知義,長度不要超過32字符
- tmp,wushan誰TM知道這些庫是干嘛的
- 庫備份必須以bak為前綴,以日期為后綴
- 從庫必須以-s為后綴
- 備庫必須以-ss為后綴
3.表設計規范
- 單實例表個數必須控制在
2000
個以內 - 單表分表個數必須控制在
1024
個以內 - 表必須有主鍵,推薦使用
unsigned
整數為主鍵- 潛在坑:刪除無主鍵的表,如果是row模式的主從架構,從庫會掛住
- 禁止使用外鍵,如果要保證完整性,應由應用程式實現
- 外鍵使得表之間相互耦合,影響
update/delete
等SQL性能 - 有可能造成死鎖,高並發情況下容易成為數據庫瓶頸
- 外鍵使得表之間相互耦合,影響
- 建議將大字段,訪問頻度低的字段拆分到單獨的表中存儲,分離冷熱數據
- 垂直拆分的依據,盡量把長度較短,訪問頻率較高的屬性放在主表里
- 流量大數據量大時,數據訪問要有
service
層,並且service
層不要通過join
來獲取主表和擴展表的屬性 - 具體可以參考沈劍大牛寫的《如何實施數據庫垂直拆分》
4.列設計規范
- 根據業務區分使用
tinyint
/int
/bigint
,分別會占用1
/4
/8
字節 - 根據業務區分使用
char
/varchar
(PS:沒有MSSQL里的nvarchar
)- 字段長度固定,或者長度近似的業務場景,適合使用
char
,能夠減少碎片,查詢性能高 - 字段長度相差較大,或者更新較少的業務場景,適合使用
varchar
,能夠減少空間
- 字段長度固定,或者長度近似的業務場景,適合使用
- 根據業務區分使用
datetime
/timestamp
datetime
占用5個字節,timestamp
占用4個字節- 存儲年使用
year
,存儲日期使用date
,存儲時間使用datetime
- 必須把字段定義為
NOT NULL
並設默認值- NULL需要更多的存儲空間
- NULL的列使用索引,索引統計,值都更加復雜,MySQL更難優化
- NULL只能采用IS NULL或者IS NOT NULL,而在=/!=/in/not in時有大坑
- 使用
int unsigned
存儲IPv4
,不要用char(15)
- 使用
varchar(20)
存儲手機號,不要使用整數- 手機號不會用來做數學運算
varchar
可以模糊查詢(eg:like ‘138%’)- 牽扯到國家代號,可能出現
+、-、()
等字符,eg:+86
- 使用
tinyint
來代替enum
enum
增加新值要進行DDL
操作
5.索引規范(常用)
- 唯一索引使用
uniq_字段名
來命名(uq_表名_字段名
) - 非唯一索引使用
idx_字段名
來命名(ix_表名_字段名
) - 單張表索引數量建議控制在5個以內
- 互聯網高並發業務,太多索引會影響寫性能
- 異常復雜的查詢需求,可以選擇
ES
等更為適合的方式存儲 生成執行計划時,如果索引太多,會降低性能,並可能導致MySQL選擇不到最優索引
- 組合索引字段數不建議超過5個
- 如果5個字段還不能極大縮小row范圍,八成是設計有問題
- 不建議在頻繁更新的字段上建立索引
- 盡量不要
join
查詢,如果要進行join
查詢,被join
的字段必須類型相同,並建立索引join
字段類型不一致容易導致全表掃描
- 理解組合索引最左前綴原則,避免重復建設索引
- 如果建立了
(a,b,c)
,相當於建立了(a)
,(a,b)
,(a,b,c)
- 如果建立了
6.SQL規范(常用)
- 禁止使用
select *
,只獲取必要字段- 指定字段能有效利用索引覆蓋
select *
會增加cpu/io/內存/帶寬
的消耗指定字段查詢,在表結構變更時,能保證對應用程序無影響
insert
必須指定字段,禁止使用insert into T values()
- 指定字段插入,在表結構變更時,能保證對應用程序無影響
- 隱式類型轉換會使索引失效,導致全表掃描(很重要)
- 禁止在
where
條件列使用函數或者表達式- 導致不能命中索引,全表掃描
- 禁止負向查詢以及
%
開頭的模糊查詢- 導致不能命中索引,全表掃描
- 禁止大表
join
和子查詢
- 同一個字段上的
or
必須改寫為in
,in
的值必須少於50個 - 應用程序必須捕獲SQL異常(方便定位線上問題)
課后思考:為什么select uid from user where phone=13811223344
不能命中phone索引?
課后拓展:
MyISAM與InnoDB兩者之間區別與選擇
https://www.cnblogs.com/y-rong/p/5309392.html
https://www.cnblogs.com/y-rong/p/8110596.html
了解下Mysql的間隙鎖及產生的原因
https://www.cnblogs.com/wt645631686/p/8324671.html
grant授權和revoke回收權限
https://www.cnblogs.com/kevingrace/p/5719536.html
centos7自帶數據庫MariaDB重啟和修改密碼
https://blog.csdn.net/shachao888/article/details/50341857
MySQL添加用戶、刪除用戶與授權
https://www.cnblogs.com/wanghetao/p/3806888.html
深度認識 Sharding-JDBC:做最輕量級的數據庫中間層
https://my.oschina.net/editorial-story/blog/888650