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


傳統數據庫

上篇文章:聊聊數據庫~開篇 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.xMariaDB 5.x基本上是無縫的,MariaDB最新穩定版為:MariaDB 5.5

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

MariaDBMySQL兼容性可以查看:

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

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

不談其他的,咱們看看它們開發的積極程度就知道為什么MariaDB是主流了
1.積極.png

使用概括(推薦)

如果想要使用MariaDB10.x的同志可以考慮MySQL8.x(社區完善)

如果想要使用MySQL5.x的同志可以考慮MariaDB5.5.x(高性能且兼容)

1.2.MariaDB部署

網絡配置如果不會可以看我以前寫的文章:https://www.cnblogs.com/dunitian/p/6658578.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遠程連接https://www.cnblogs.com/dunitian/p/5474501.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密碼小計: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)

文章結尾貼一節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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM