Mysql 安裝+基礎 【vaynexiao】

免安裝版

mysql5.7 64位免安裝版下載地址:
https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19-winx64.zip

  • 下載後得到zip壓縮包,放在固定文件夾下,以後就不能變動了。
  • 解壓到自己想要安裝到的目錄,本人解壓到的是C:\Environment
  • 添加環境變量
    1. 選擇PATH,在其後面添加: 你的mysql 安裝文件下面的bin文件夾
      C:\Environment\mysql-5.7.19-winx64\bin
      2 在C:\Environment\mysql-5.7.19-winx64下新建 my.ini 文件
      3 編輯 my.ini 文件 ,注意替換路徑位置
      [mysqld]
      basedir=C:\Environment\mysql-5.7.19-winx64
      datadir=C:\Environment\mysql-5.7.19-winx64\data
      port=3306
      skip-grant-tables
  • 啓動管理員模式下的CMD,並將路徑切換至mysql下的bin目錄,然後輸入mysqld –install (安裝mysql)
    如果提示 由於找不到msvcp120.dll是因爲缺少運行庫
    自行下載安裝vcredist 地址:https://www.microsoft.com/zh-CN/download/details.aspx?id=40784
  • 再輸入 mysqld --initialize-insecure --user=mysql 初始化數據文件
  • 然後再次啓動mysql net start mysql
  • 然後用命令 mysql –u root –p 進入mysql管理界面(密碼可爲空)如果提示無法連接就自行去啓動服務
  • 進入界面後更改root密碼
    update mysql.user set authentication_string=password(‘root’) where user=‘root’ and Host = ‘localhost’;
    (最後輸入flush privileges; 刷新權限)
  1. 修改 my.ini文件刪除最後一句skip-grant-tables
  2. 重啓mysql即可正常使用,語句不需要分號
    net stop mysql
    net start mysql
  3. 連接上後在cmd中可以直接連接,此時密碼就修改後的root
    mysql -u root -proot
    表示使用root/root進行連接
    (清空服務命令:sc delete mysql; 別輕易使用這個)

基本sql命令

update user set password=password('123456')where user='root'; --修改密碼
flush privileges;  --刷新數據庫
show databases; --顯示所有數據庫
use dbname; --打開某個數據庫
show tables; --顯示數據庫mysql中所有的表
describe/desc user; --顯示錶mysql數據庫中user表的列信息
create database [if not exists] name; --創建數據庫
drop database [if exists] name --刪除數據庫
drop table [if exists] tablename --刪除數據庫
use databasename; --選擇數據庫

exit; --退出Mysql
? 命令關鍵詞 : --尋求幫助

# --表示註釋
/**/ --表示區域註釋

語句定義

sql語句分類

名稱 解釋 命令
DDL定義語言 創建庫、表的語句 create drop alter
DML操作語言 操作數據庫中數據的語句 insert update delete
DQL查詢語言 查詢數據庫中數據 select
DCL控制語言 管理權限及數據的更改狀態 grant commit rollback
# 目標 : 創建一個school數據庫
# 創建學生表(列,字段)
# 學號int 登錄密碼varchar(20) 姓名,性別varchar(2),出生日期(datatime),家庭住址,email
# 創建表之前 , 一定要先選擇數據庫
CREATE TABLE IF NOT EXISTS `student` (
  `id` int(4) NOT NULL AUTO_INCREMENT COMMENT '學號',
  `name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',
  `pwd` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密碼',
  `sex` varchar(2) NOT NULL DEFAULT '男' COMMENT '性別',
  `birthday` datetime DEFAULT NULL COMMENT '生日',
  `address` varchar(100) DEFAULT NULL COMMENT '地址',
  `email` varchar(50) DEFAULT NULL COMMENT '郵箱',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
# 查看數據庫的定義
SHOW CREATE DATABASE school;
# 查看數據表的定義
SHOW CREATE TABLE student;
# 顯示錶結構
DESC student;
# 設置嚴格檢查模式(不能容錯了)
SET sql_mode='STRICT_TRANS_TABLES';
create database boss_0227;--不能數字開頭
show databases;
drop databases boss_0227;
user study;--使用該數據庫
create table user(
    id int PRIMARY key auto_increment,
    password varchar(16)
)
desc user;--查看錶設計
insert into user values(1,'張三');
select * from user;
delete from user where id=1;--sql server 可以不寫from,mysql必須寫,建議始終都寫from
update user set password='123' where id=1;
rename table user to user2;--修改表名

select studentNo as no,studentName as name from student as stu;
select concat("a",studentName) as newName from student;
SELECT DISTINCT studentno FROM result; -- 瞭解:DISTINCT 去除重複項 , (默認是ALL)
# selcet查詢中可以使用表達式
SELECT @@auto_increment_increment; # 查詢自增步長
SELECT VERSION(); #查詢版本號
SELECT 100*3-1 AS 計算結果; # 表達式
# 學員考試成績集體提分一分查看
SELECT studentno,StudentResult+1 AS '提分後' FROM result;

SELECT studentno,studentresult FROM result
WHERE NOT studentno=1000;  -- not 等於 !=

order by stuNo   limit 0,10; -- 先排序後limit

alter table old_name rename as new_name --修改表名
alter table user add usercode varchar(200) --增加usercode字段
alter table user modify usercode varchar(250) --修改字段屬性
alter table user change usercode usercode_new varchar(200) --修改字段名 及屬性
alter table user drop usercode --刪除字段usercode

# 數學函數 (這裏只列出一些常用的)
SELECT ABS(-8);  /*絕對值*/
SELECT CEILING(9.4);  /*向上取整*/
SELECT FLOOR(9.4);  /*向下取整*/
SELECT RAND();  /*隨機數,返回一個0-1之間的隨機數*/
SELECT SIGN(0); /*符號函數: 負數返回-1,正數返回1,0返回0*/

#字符串函數
SELECT CHAR_LENGTH('狂神說堅持就能成功'); /*返回字符串包含的字符數*/
SELECT CONCAT('我','愛','程序');  /*合併字符串,參數可以有多個*/
SELECT INSERT('我愛編程helloworld',1,2,'超級熱愛');  /*替換字符串,從某個位置開始替換某個長度,下標從1開始*/
SELECT LOWER('KuangShen'); /*小寫*/
SELECT UPPER('KuangShen'); /*大寫*/
SELECT LEFT('hello,world',5);  /*從左邊截取*/
SELECT RIGHT('hello,world',5);  /*從右邊截取*/
SELECT INSTR('hello','ll');  /*從返回str的的下標,下標從1開始*/
SELECT REPLACE('狂神說堅持就能成功,再堅持一下','堅持','努力');  /*替換所有符合regex的字符串*/
SELECT SUBSTR('狂神說堅持就能成功',4,6); /*截取字符串,開始index和長度,下標從1開始*/
SELECT REVERSE('狂神說堅持就能成功'); /*反轉*/

#日期和時間函數
# 兩者作用等價
SELECT CURRENT_DATE();   /*獲取當前日期 2020-03-08 */
SELECT CURDATE();   /*獲取當前日期 2020-03-08 */
SELECT NOW();   /*獲取當前日期和時間 2020-03-08 20:03:08 */
SELECT LOCALTIME();   /*獲取當前日期和時間 2020-03-08 20:03:08 */
SELECT SYSDATE();   /*獲取當前日期和時間 2020-03-08 20:03:08 */
/*獲取年月日,時分秒*/
SELECT YEAR(NOW());
SELECT MONTH(NOW());
SELECT DAY(NOW());
SELECT HOUR(NOW());
SELECT MINUTE(NOW());
SELECT SECOND(NOW());

#系統信息函數
SELECT VERSION();  /*版本*/
SELECT USER();  /*用戶 @root */

/*COUNT:非空的*/
SELECT COUNT(studentname) FROM student;
SELECT COUNT(*) FROM student;
SELECT COUNT(1) FROM student;  /*推薦*/

SELECT SUM(StudentResult) AS 總和 FROM result;
SELECT AVG(StudentResult) AS 平均分 FROM result;
SELECT MAX(StudentResult) AS 最高分 FROM result;
SELECT MIN(StudentResult) AS 最低分 FROM result;


insert into user values(4,'bob',MD5('123456'));

select * from `user`
where `name`='bob' AND pwd=MD5('123456');

# 創建外鍵的方式一 : 創建子表同時創建外鍵
# 年級表(id\年級名稱)
CREATE TABLE `grade` (
  `gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年級ID',
  `gradename` VARCHAR(50) NOT NULL COMMENT '年級名稱',
  PRIMARY KEY (`gradeid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
# 學生信息表
#(學號,姓名,性別,年級,手機,地址,出生日期,郵箱,身份證號)
CREATE TABLE `student` (
  `studentno` INT(4) NOT NULL COMMENT '學號',
  `studentname` VARCHAR(20) NOT NULL DEFAULT '匿名' COMMENT '姓名',
  `sex` TINYINT(1) DEFAULT '1' COMMENT '性別',
  `gradeid` INT(10) DEFAULT NULL COMMENT '年級',
  `phoneNum` VARCHAR(50) NOT NULL COMMENT '手機',
  `address` VARCHAR(255) DEFAULT NULL COMMENT '地址',
  `borndate` DATETIME DEFAULT NULL COMMENT '生日',
  `email` VARCHAR(50) DEFAULT NULL COMMENT '郵箱',
  `idCard` VARCHAR(18) DEFAULT NULL COMMENT '身份證號',
  PRIMARY KEY (`studentno`),
  KEY `FK_gradeid` (`gradeid`),
  CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

# 創建外鍵方式二 : 創建子表完畢後,修改子表添加外鍵
ALTER TABLE student
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`);

# 刪除外鍵
ALTER TABLE student DROP FOREIGN KEY FK_gradeid;
# 發現執行完上面的,索引還在,所以還要刪除索引
# 注:這個索引是建立外鍵的時候默認生成的
ALTER TABLE student DROP INDEX FK_gradeid;


添加數據
INSERT命令
語法 : 
INSERT INTO 表名[(字段1,字段2,字段3,...)] VALUES('值1','值2','值3')
注意 : 
字段或值之間用英文逗號隔開.
'字段1,字段2...'該部分可省略 , 但添加的值務必與表結構,數據列,順序相對應,且數量一致.
可同時插入多條數據 , values 後用英文逗號隔開.
複製代碼
# 使用語句如何增加語句?
# 語法 : INSERT INTO 表名[(字段1,字段2,字段3,...)] VALUES('值1','值2','值3')
INSERT INTO grade(gradename) VALUES ('大一');
# 主鍵自增,那能否省略呢?
INSERT INTO grade VALUES ('大二');
# 查詢:INSERT INTO grade VALUE ('大二')錯誤代碼: 1136
# Column count doesn`t match value count at row 1
# 得出結論:'字段1,字段2...'該部分可省略 , 但添加的值務必與表結構,數據列,順序相對應,且數量一致.
# 一次插入多條數據
INSERT INTO grade(gradename) VALUES ('大三'),('大四');

update user set col_name = value [,col_name2 = value2] --修改值
delete from 表名 [where condition]  --不加條件刪除全部數據
truncate table 表名 --格式化表,速度比delete快很多,且會重置auto_increment計數器

limit

sql server 使用了stuNo作爲分組字段,那麼其他字段要麼以聚合函數出現,要麼不能出現;
但mysql不同,mysql即使只按照其中一個字段分組,其他字段同樣可以直接查出來,
因爲mysql中,系統用了limit(1)將查詢的第一條數據顯示。這是一個很大的區別。

補充:

-- select now(); sqlserver中不支持
-- select curdate();sqlserver中不支持
-- select curtime();sqlserver中不支持
select PI();-- 3.141593 在sql server中運行結果:3.14159265358979
-- select mod(45,7);-- 求餘sqlserver中不支持
select sqrt(25);-- 求開方
select round(12.345678,2)-- 12.35 sqlsever得到:12.350000
select 7.1 div 7; -- 相除的結果取整數
select 7.1 mod 8;-- 7.1 取餘數
select length('小搬運工很帥!')--  爲啥得出長度是21
MySql中添加用戶,新建數據庫,用戶授權,刪除用戶,修改密碼(注意每行後邊都跟個;表示一個命令語句結束):
 
1.新建用戶
  1.1 登錄MYSQL:
	  @>mysql -u root -p
	  @>密碼
  1.2 創建用戶:
	  mysql> insert into mysql.user(Host,User,Password) values("localhost","test",password("1234"));
	  這樣就創建了一個名爲:test 密碼爲:1234 的用戶。
	  注意:此處的"localhost",是指該用戶只能在本地登錄,不能在另外一臺機器上遠程登錄。
	  如果想遠程登錄的話,將"localhost"改爲"%",表示在任何一臺電腦上都可以登錄。也可以指定某臺機器可以遠程登錄。
  1.3 然後登錄一下:
	  mysql>exit;
	  @>mysql -u test -p
	  @>輸入密碼
	  mysql>登錄成功
 
2.爲用戶授權
  授權格式:grant 權限 on 數據庫.* to 用戶名@登錄主機 identified by "密碼"; 
  2.1 登錄MYSQL(有ROOT權限),這裏以ROOT身份登錄:
	  	@>mysql -u root -p
	  	@>密碼
  2.2 首先爲用戶創建一個數據庫(testDB):
  		mysql>create database testDB;
  2.3 授權test用戶擁有testDB數據庫的所有權限(某個數據庫的所有權限):
		mysql>grant all privileges on testDB.* to test@localhost identified by '1234';
		mysql>flush privileges;//刷新系統權限表
		格式:grant 權限 on 數據庫.* to 用戶名@登錄主機 identified by "密碼"; 
  2.4 如果想指定部分權限給一用戶,可以這樣來寫:
	  mysql>grant select,update on testDB.* to test@localhost identified by '1234';
	  mysql>flush privileges; //刷新系統權限表
  2.5 授權test用戶擁有所有數據庫的某些權限:   
  		mysql>grant select,delete,update,create,drop on *.* to test@"%" identified by "1234";
		//test用戶對所有數據庫都有select,delete,update,create,drop 權限。
  		//@"%" 表示對所有非本地主機授權,不包括localhost。(localhost地址設爲127.0.0.1,如果設爲真實的本地地址,不知道是否可以,沒有驗證。)
 		//對localhost授權:加上一句grant all privileges on testDB.* to test@localhost identified by '1234';即可。
 
3. 刪除用戶
   	@>mysql -u root -p
  	@>密碼
   	mysql>Delete FROM user Where User='test' and Host='localhost';
   	mysql>flush privileges;
   	mysql>drop database testDB; //刪除用戶的數據庫
	刪除賬戶及權限:>drop user 用戶名@'%';
	>drop user 用戶名@ localhost; 
 
4. 修改指定用戶密碼
    @>mysql -u root -p
    @>密碼
    mysql>update mysql.user set password=password('新密碼') where User="test" and Host="localhost";
    mysql>flush privileges; 	
執行如下命令,即可把root密碼修改爲admin
set password for root@localhost = password('admin');
mysql隨機獲取記錄
SELECT * FROM mydb_user  ORDER BY  RAND() LIMIT 5;
獲取當前日期+時間
select now();
select now() as Systemtime;
select sysdate() as Systemtime;
-- 2019-09-30 13:41:00
select curdate();
select current_date as Systemtime;
-- 2019-09-30
Incorrect integer value: '' for column 'id' at row 1
數據格式爲datetime,而且navicat默認給的是Empty String所以存不進去,和填寫的註釋內容無關。

 
 
CREATE DATABASE mybatis DEFAULT CHARACTER SET utf8;

再補充:

1show create table 舊錶;
這樣會將舊錶的創建命令列出。我們只需要將該命令拷貝出來,更改table的名字,就可以建立一個完全一樣的表

4、複製舊錶的數據到新表-新表需已存在(假設兩個表結構不一樣)
insert into 新表(字段1,字段2,.......) select 字段1,字段2,...... from 舊錶

5,跨庫只複製數據
insert into db1.table1 select * from db2.table2 (完全複製,需新表已存在)
insert into db1.table1 select distinct * from db2.table2(不復制重複紀錄,需新表已存在)
insert into tdb1.able1 select top 5 * from   db2.table2 (前五條紀錄,需新表已存在)

select * from information_schema.tables

6select * from tb_data_new limit 5,5; 
查詢出6-10,從5開始查處5條,但不包括第5SELECT * from user LIMIT 0,5;
-- 等價於 SELECT * FROM user LIMIT 5;

SELECT * from user LIMIT 2 OFFSET 3; -- 跳過3個查2個
-- 等價於 SELECT * FROM user  LIMIT 3,2;

SELECT * FROM orange LIMIT 10,15;  -- 檢索記錄11-25

第n頁: limit (pageNo-1)*pageSize,pageSize
pageNo:頁碼     pageSize:單頁顯示條數

7,開啓事務
start transaction https://www.v2ex.com/t/501189
begin

索引

mysql
CREATE TABLE `user_copy` (
  `id` INT(6) NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `name` VARCHAR(50) NOT NULL COMMENT '名稱',
  `pwd` VARCHAR(32) NOT NULL COMMENT '密碼',
  `create_time` DATETIME DEFAULT NULL DEFAULT COMMENT '創建日期',
  PRIMARY KEY (`id`)
) ENGINE=MYISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COMMENT='測試表';

DELIMITER $$
CREATE FUNCTION mock_data() 
RETURNS INT
BEGIN
    DECLARE num INT DEFAULT 1000000;
    DECLARE i INT DEFAULT 0;
    WHILE i < num DO
        INSERT INTO user_copy (NAME, pwd, create_time)
        VALUES ( CONCAT('用戶',i), CONCAT('用戶',i,'@qq.com'), UNIX_TIMESTAMP(NOW()) );
        SET i = i + 1;
    END WHILE;
    RETURN i;
END;
-- 調用函數
SELECT mock_data() -- 38.941 sec
TRUNCATE user_copy -- 0.035 sec
DROP FUNCTION IF EXISTS mock_data; -- 1.014 sec

SELECT NAME FROM user_copy WHERE pwd='用戶[email protected]'; -- 0.431 sec -- 0.001 sec
EXPLAIN SELECT NAME FROM user_copy WHERE pwd='用戶[email protected]'; -- rows=1000000
CREATE INDEX idx_pwd  ON user_copy(pwd); -- 15.933 sec

備份

  • data文件遷移
  • 可視化工具中操作導出爲abc.sql

分庫分表

垂直分表

將訪問頻次低的商品描述信息單獨存放在一張表中,訪問頻次較高的商品基本信息單獨放在一張表中
在這裏插入圖片描述
垂直分表定義:將一個表按照字段分成多表,每個表存儲其中一部分字段。
它帶來的提升是:

  • 爲了避免IO爭搶並減少鎖表的機率,查看詳情的用戶與商品信息瀏覽互不影響
  • 充分發揮熱門數據的操作效率,商品信息的操作的高效率不會被商品描述的低效率所拖累。

爲什麼大字段IO效率低:第一是由於數據量本身大,需要更長的讀取時間;第二是跨頁,頁是數據庫存儲單位,很多查找及定位操作都是以頁爲單位,單頁內的數據行越多數據庫整體性能越好,而大字段佔用空間大,單頁內存儲行數少,因此IO效率較低。第三,數據庫以行爲單位將數據加載到內存中,這樣表中字段長度較短且訪問頻率較高,內存能加載更多的數據,命中率更高,減少了磁盤IO,從而提升了數據庫性能。

通常我們按以下原則進行垂直拆分:

  • 把不常用的字段單獨放在一張表;
  • 把text,blob等大字段拆分出來放在附表中;
  • 經常組合查詢的列放在一張表中;

垂直分庫

通過垂直分表性能得到了一定程度的提升,但是還沒有達到要求,並且磁盤空間也快不夠了,因爲數據還是始終限制在一臺服務器,庫內垂直分表只解決了單一表數據量過大的問題,但沒有將表分佈到不同的服務器上,因此每個表還是競爭同一個物理機的CPU、內存、網絡IO、磁盤。

經過思考,他把原有的SELLER_DB(賣家庫),分爲了PRODUCT_DB(商品庫)和STORE_DB(店鋪庫),並把這兩個庫分散到不同服務器,如下圖:
在這裏插入圖片描述
由於商品信息與商品描述業務耦合度較高,因此一起被存放在PRODUCT_DB(商品庫);而店鋪信息相對獨立,因此單獨被存放在STORE_DB(店鋪庫)。
垂直分庫是指按照業務將表進行分類,分佈到不同的數據庫上面,每個庫可以放在不同的服務器上,它的核心理念是專庫專用。

水平分庫

將店鋪ID爲單數的和店鋪ID爲雙數的商品信息分別放在兩個庫中。

水平分庫是把同一個表的數據按一定規則拆到不同的數據庫中,每個庫可以放在不同的服務器上。

當一個應用難以再細粒度的垂直切分,或切分後數據量行數巨大,存在單庫讀寫、存儲性能瓶頸,這時候就需要進行水平分庫了,經過水平切分的優化,往往能解決單庫存儲量及性能瓶頸。但由於同一個表被分配在不同的數據庫,需要額外進行數據操作的路由工作,因此大大提升了系統複雜度。
在這裏插入圖片描述

水平分表

水平分表是在同一個數據庫內,把同一個表的數據按一定規則拆到多個表中。

在這裏插入圖片描述

總結

  • 垂直分表:可以把一個寬表的字段按訪問頻次、是否是大字段的原則拆分爲多個表,這樣既能使業務清晰,還能提升部分性能。拆分後,儘量從業務角度避免聯查,否則性能方面將得不償失。

  • 垂直分庫:可以把多個表按業務耦合鬆緊歸類,分別存放在不同的庫,這些庫可以分佈在不同服務器,從而使訪問壓力被多服務器負載,大大提升性能,同時能提高整體架構的業務清晰度,不同的業務庫可根據自身情況定製優化方案。但是它需要解決跨庫帶來的所有複雜問題。

  • 水平分庫:可以把一個表的數據(按數據行)分到多個不同的庫,每個庫只有這個表的部分數據,這些庫可以分佈在不同服務器,從而使訪問壓力被多服務器負載,大大提升性能。它不僅需要解決跨庫帶來的所有複雜問題,還要解決數據路由的問題(數據路由問題後邊介紹)。

  • 水平分表:可以把一個表的數據(按數據行)分到多個同一個數據庫的多張表中,每個表只有這個表的部分數據,這樣做能小幅提升性能,它僅僅作爲水平分庫的一個補充優化。

一般來說,在系統設計階段就應該根據業務耦合鬆緊來確定垂直分庫,垂直分表方案,在數據量及訪問壓力不是特別大的情況,首先考慮緩存、讀寫分離、索引技術等方案。若數據量極大,且持續增長,再考慮水平分庫水平分表方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章