聊聊數據庫~2.SQL環境篇

傳統數據庫

上篇文章:聊聊數據庫~開篇 http://www.javashuo.com/article/p-kmvgjgda-eh.htmlhtml

原本準備直接開講NoSQL的(當時開篇就是說的NoSQL)考慮到有些同志可能連MySQL系都沒接觸過,因此咱們2019說數據系的時候預計從MySQL(穿插MSSQL)開始,這篇文章就當試水篇,效果好就繼續往下寫~(這篇偏理論和運維)mysql

1.1.MariaDB and MySQL

官方文檔:https://mariadb.com/kb/zh-cn/mariadbgit

目前主流:MySQL 5.7 or MariaDB 5.5.x(推薦)github

多一句嘴,MySQL當年被Oracle收購後,MySQL之父以爲靠Oracle維護MySQL很不靠譜,而後就跳槽弄了個MariaDB(不少Oracle競爭對手扶持着),目前MariaDB是發展最快的MySQL分支版本(PS:MySQL如今是雙協議了,大部分公司用的版本都是<=5.7sql

而後得說下遷移問題:MySQL 5.xMariaDB 5.x基本上是無縫的,MariaDB最新穩定版爲:MariaDB 5.5shell

PS:MariaDB有兩個分支,而10.x分支是不兼容MySQL的數據庫

MariaDBMySQL兼容性能夠查看:ubuntu

https://mariadb.com/kb/zh-cn/mariadb-vs-mysql-compatibility/centos

PS:國內比較火的還有阿里的MySQL分支https://github.com/alibaba/AliSQL安全

不談其餘的,我們看看它們開發的積極程度就知道爲何MariaDB是主流了
1.積極.png

使用歸納(推薦)

若是想要使用MariaDB10.x的同志能夠考慮MySQL8.x(社區完善)

若是想要使用MySQL5.x的同志能夠考慮MariaDB5.5.x(高性能且兼容)

1.2.MariaDB部署

網絡配置若是不會能夠看我之前寫的文章:http://www.javashuo.com/article/p-xulcawzr-by.html

1.環境配置和初始化

安裝很簡單,以CentOS爲例:
1.CentOS.png

systemctl start mariadb.service   # 啓動MariaDB
systemctl enable mariadb.service  # 設置開機啓動

systemctl stop mariadb.service    # 中止MariaDB
systemctl restart mariadb.service # 重啓MariaDB

1.運行.png

PS:Win安裝注意這一步:
1.win.png

執行文件簡單說明:有時候咱們 ps aux | grep mysql 的時候,發現運行的並非/usr/bin/下的mysqld而是mysqld_safe,那這個mysqld_safe是啥呢?==> 線程安全的實例

MariaDB的程序組成:ls /usr/bin | grep mysql

  1. Client:
    • mysql 命令行客戶端
    • mysqldump 數據庫備份用
    • mysqladmin 遠程管理工具
    • mysqlbinlog 二進制日誌管理工具
    • ...
  2. 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"(腳本直接運行)

不少人安裝完成後是這樣設置密碼的:(不推薦)
1.不推薦.png

正確打開方式:mysql_secure_installation
1.安全初始化1.png

若是容許root遠程登陸:Disallow root login remotely? [Y/n] n
1.安全初始化2.png

安全初始化後登陸圖示:
1.安全初始化後登陸.png
1.基本信息.png

2.配置文件

MariaDB 5.5.60爲例:

  1. Linux:配置文件查找順序(找不到就往下繼續)
    • /etc/my.cnf --> /etc/mysql/conf.d/*.cnf --> ~/.my.cnf
  2. 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禁止遠程登陸了,如今咱們建立一個其餘用戶
1.新增用戶.png

2.給用戶權限
1.給權限.png

3.防火牆放行指定端口
1.防火牆.png

4.遠程客戶端測試一下
1.成功.png

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遠程鏈接http://www.javashuo.com/article/p-wrzuikpx-dz.html

擴展:爲用戶添加新數據庫的權限

PS:先使用root建立數據庫,而後再受權grant all privileges on 數據庫.* to 用戶名@"%" identified by "密碼";並刷新flush privileges;

3.1.爲用戶添加新數據庫權限.png

查看權限:show grants for dnt;
3.2.查看權限.png

效果:
3.3.效果.png

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.1.Ubuntu.png

2.容許遠程鏈接:註釋掉 bind-address=127.0.0.1(/etc/mysql/mysql.conf.d/mysqld.cnf)
2.2.遠程鏈接.png

PS:經常使用配置(/etc/mysql/mysql.conf.d/mysqld.cnf
2.2.1.經常使用配置.png

3.關於爲何是這個路徑的說明:sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
2.3.爲何是這個路徑.png

4.全部配置修改都須要從新啓動下:sudo systemctl restart mysql
2.4.記得重啓一下

5.第一次初始化和MariaDB不太同樣:sudo mysql_secure_installation(其餘一路y便可)

須要選下你設置root密碼的複雜度:(通常1就能夠了,就算設置再複雜,入了系統也是虛的)
2.5.初始化-注意下密碼複雜程度

PS:能夠看看拓展文章:Ubuntu16安裝mysql5.7未提示輸入密碼,安裝後修改mysql默認密碼【不推薦】修改mysql密碼策略

6.而後輸入密碼你就能夠登陸了sudo mysql -uroot -p(PS:你直接sudo mysql也能夠直接登陸)

這邊我就不像上節課一步步演示了,直接受權和建立一步走了grant all privileges on 數據庫.* to "用戶名"@"%" identified by "複雜密碼";
2.6.受權建立一步走.png

7.記得flush privileges;刷新一下系統表
2.7.測試.png

課後拓展:

MySQL5.7.26 忘記Root密碼小計:http://www.javashuo.com/article/p-heuahocu-cm.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)

文章結尾貼一節58MySQL軍規:(適用於併發量大,數據量大的典型互聯網業務

1.基礎規範

  1. 表存儲引擎必須使用InnoDB
  2. 表字符集默認使用utf8,必要時候使用utf8mb4
    • utf8通用,無亂碼風險,漢字3字節,英文1字節
    • utf8mb4utf8的超集,存儲4字節時使用(eg:表情符號)
  3. 禁止使用存儲過程,視圖,觸發器,Event
    • 調試,排錯,遷移都比較困難,擴展性較差
    • 對數據庫性能影響較大,互聯網業務,能讓站點層和服務層乾的事情,不要交到數據庫層
  4. 禁止在數據庫中存儲大文件(eg:照片)
    • 能夠將大文件存儲在對象存儲系統,數據庫中存儲路徑
  5. 禁止在線上環境作數據庫壓力測試
    • 測試,開發,線上數據庫環境必須隔離

2.命名規範

  1. 庫名,表名,列名必須用小寫,採用下劃線分隔
    • abc,Abc,ABC都是給本身埋坑
  2. 庫名,表名,列名必須見名知義,長度不要超過32字符
    • tmp,wushan誰TM知道這些庫是幹嗎的
  3. 庫備份必須以bak爲前綴,以日期爲後綴
    • 從庫必須以-s爲後綴
    • 備庫必須以-ss爲後綴

3.表設計規範

  1. 單實例表個數必須控制在2000個之內
  2. 單表分表個數必須控制在1024個之內
  3. 表必須有主鍵,推薦使用unsigned整數爲主鍵
    • 潛在坑:刪除無主鍵的表,若是是row模式的主從架構,從庫會掛住
  4. 禁止使用外鍵,若是要保證完整性,應由應用程式實現
    • 外鍵使得表之間相互耦合,影響update/delete等SQL性能
    • 有可能形成死鎖,高併發狀況下容易成爲數據庫瓶頸
  5. 建議將大字段,訪問頻度低的字段拆分到單獨的表中存儲,分離冷熱數據
    • 垂直拆分的依據,儘可能把長度較短,訪問頻率較高的屬性放在主表裏
    • 流量大數據量大時,數據訪問要有service層,而且service層不要經過join來獲取主表和擴展表的屬性
    • 具體能夠參考沈劍大牛寫的《如何實施數據庫垂直拆分》

4.列設計規範

  1. 根據業務區分使用tinyint/int/bigint,分別會佔用1/4/8字節
  2. 根據業務區分使用char/varchar(PS:沒有MSSQL裏的nvarchar
    • 字段長度固定,或者長度近似的業務場景,適合使用char可以減小碎片,查詢性能高
    • 字段長度相差較大,或者更新較少的業務場景,適合使用varchar,可以減小空間
  3. 根據業務區分使用datetime/timestamp
    • datetime佔用5個字節,timestamp佔用4個字節
    • 存儲年使用year,存儲日期使用date,存儲時間使用datetime
  4. 必須把字段定義爲NOT NULL並設默認值
    • NULL須要更多的存儲空間
    • NULL的列使用索引,索引統計,值都更加複雜,MySQL更難優化
    • NULL只能採用IS NULL或者IS NOT NULL,而在=/!=/in/not in時有大坑
  5. 使用int unsigned存儲IPv4,不要用char(15)
  6. 使用varchar(20)存儲手機號,不要使用整數
    • 手機號不會用來作數學運算
    • varchar能夠模糊查詢(eg:like ‘138%’)
    • 牽扯到國家代號,可能出現+、-、()等字符,eg:+86
  7. 使用tinyint來代替enum
    • enum增長新值要進行DDL操做

5.索引規範(經常使用)

  1. 惟一索引使用uniq_字段名來命名(uq_表名_字段名
  2. 非惟一索引使用idx_字段名來命名(ix_表名_字段名
  3. 單張表索引數量建議控制在5個之內
    • 互聯網高併發業務,太多索引會影響寫性能
    • 異常複雜的查詢需求,能夠選擇ES等更爲適合的方式存儲
    • 生成執行計劃時,若是索引太多,會下降性能,並可能致使MySQL選擇不到最優索引
  4. 組合索引字段數不建議超過5個
    • 若是5個字段還不能極大縮小row範圍,八成是設計有問題
  5. 不建議在頻繁更新的字段上創建索引
  6. 儘可能不要join查詢,若是要進行join查詢,被join的字段必須類型相同,並創建索引
    • join字段類型不一致容易致使全表掃描
  7. 理解組合索引最左前綴原則,避免重複建設索引
    • 若是創建了(a,b,c),至關於創建了(a), (a,b), (a,b,c)

6.SQL規範(經常使用)

  1. 禁止使用select *,只獲取必要字段
    • 指定字段能有效利用索引覆蓋
    • select *會增長cpu/io/內存/帶寬的消耗
    • 指定字段查詢,在表結構變動時,能保證對應用程序無影響
  2. insert必須指定字段,禁止使用insert into T values()
    • 指定字段插入,在表結構變動時,能保證對應用程序無影響
  3. 隱式類型轉換會使索引失效,致使全表掃描(很重要)
  4. 禁止在where條件列使用函數或者表達式
    • 致使不能命中索引,全表掃描
  5. 禁止負向查詢以及%開頭的模糊查詢
    • 致使不能命中索引,全表掃描
  6. 禁止大表join子查詢
  7. 同一個字段上的or必須改寫爲inin的值必須少於50個
  8. 應用程序必須捕獲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
相關文章
相關標籤/搜索