1. 程式人生 > 其它 >go官網依賴包下載失敗

go官網依賴包下載失敗

資料庫

資料庫操作

結構化查詢語句分類

img

資料庫操作

命令列操作資料庫

建立資料庫 : create database [if not exists] 資料庫名;

刪除資料庫 : drop database [if exists] 資料庫名;

檢視資料庫 : show databases;

使用資料庫 : use 資料庫名;

NULL值

  • 理解為 "沒有值" 或 "未知值"
  • 不要用NULL進行算術運算 , 結果仍為NULL

資料欄位屬性

UnSigned

  • 無符號的
  • 宣告該資料列不允許負數 .

ZEROFILL

  • 0填充的
  • 不足位數的用0來填充 , 如int(3),5則為005

Auto_InCrement

  • 自動增長的 , 每新增一條資料 , 自動在上一個記錄數上加 1(預設)
  • 通常用於設定主鍵 , 且為整數型別
  • 可定義起始值和步長
    • 當前表設定步長(AUTO_INCREMENT=100) : 隻影響當前表
    • SET @@auto_increment_increment=5 ; 影響所有使用自增的表(全域性)

NULL 和 NOT NULL

  • 預設為NULL , 即沒有插入該列的數值
  • 如果設定為NOT NULL , 則該列必須有值

DEFAULT

  • 預設的
  • 用於設定預設值
  • 例如,性別欄位,預設為"男" , 否則為 "女" ; 若無指定該列的值 , 則預設值為"男"的值

操作 描述
inner join 如果表中至少有一個匹配,就返回行
left join 左外連線 會從左表中返回所有的值,即使右表沒有
right join 會從右表中返回所有的值,即使左表沒有

select查詢

SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias]
    [left | right | inner join table_name2]  -- 聯合查詢
    [WHERE ...]  -- 指定結果需滿足的條件
    [GROUP BY ...]  -- 指定結果按照哪幾個欄位來分組
    [HAVING]  -- 過濾分組的記錄必須滿足的次要條件
    [ORDER BY ...]  -- 指定查詢記錄按一個或多個條件排序
    [LIMIT {[offset,]row_count | row_countOFFSET offset}];
    --  指定查詢的記錄從哪條至哪條

作用:

  • 可給資料列取一個新別名
  • 可給表取一個新別名
  • 可把經計算或總結的結果用另一個新名稱來代替
SELECT *FROM student
SELECT *FROM result
SELECT  `studentNo`,`studentName` FROM student 

SELECT  `studentNo` AS 學號,`studentName` AS 名字 FROM student 
--函式拼接字串 conact(a,b)
SELECT CONCAT('姓名:',studentname)AS 新名字 FROM student
--distinct 去重
SELECT *FROM result
SELECT `studentNo` FROM result
 SELECT DISTINCT `studentNo` FROM result
SELECT VERSION()
SELECT 100*3-9 AS 計算結果
SELECT `studentNo`,`studentResult`+2 AS '提分後' FROM result

========================WHERE==================
SELECT `studentNO`,`studentResult` FROM result

--查詢成績在95-100分之間的
SELECT `studentNO`,`studentResult` FROM result
WHERE `studentResult`>=95 AN D `studentResult`<=100
SELECT `studentNO`,`studentResult` FROM result
WHERE `studentResult`>=95 && `studentResult`<=100

--模糊查詢(區間)
SELECT `studentNO`,`studentResult` FROM result
WHERE `studentResult`BETWEEN 90 AND 98

--查詢除了1000號學生之外的同學的成績
SELECT `studentNO`,`studentResult` FROM result
WHERE  `studentNo`!=1000 

--查詢姓劉的同學 名字後面只有一個字的
SELECT `studentNo`,`studentName` FROM student
WHERE studentName LIKE '劉_'

--查詢姓劉的同學 名字後面只有兩個個字的
SELECT `studentNo`,`studentName` FROM student
WHERE studentName LIKE '劉__'

--查詢名字中間有一字的同學  %一%
SELECT `studentNo`,`studentName` FROM student
WHERE studentName LIKE '%一%'

--===========IN (具體的一個或多個值)=============
--查詢1001 1002 1003 號學生
SELECT `studentNo`,`studentName` FROM student
WHERE `studentNo` IN (1001,1002,1003);

--查詢在安徽的學生
SELECT `studentNo`,`studentName` FROM student
WHERE address='安徽'

SELECT `studentNo`,`studentName` FROM student
WHERE address IN ('安徽','西安');

--=======NULL NOT NULL========

--查詢地址為空的學生
SELECT `studentNo`,`studentName` FROM student
WHERE address='' OR address IS NULL;

--查詢有出生日期的學生
SELECT `studentNo`,`studentName` FROM student
WHERE borndate IS NOT NULL



連表查詢

--============連表查詢==========
--查詢參加考試的同學(學號,姓名,科目編號,分數)
SELECT *FROM `student`
SELECT *FROM `result`

/*思路
1.分析需求,分析查詢的欄位來自哪些表,(連表查詢)
2.確定用那種連線查詢?7種
確定交叉點(這兩個表中哪個資料是相同的)
判斷的條件:學生表中的 sudentNo=成績表studentNo
inner join  並集
*/

--join(連線的表) on(判斷的條件) 連線查詢
--where   等值查詢


--inner JOIN  並集
SELECT s.studentNo,studentName,subjectNo,studentResult
FROM student AS s
INNER JOIN result AS r
WHERE s.studentNo=r.studentNo

--Right JOIN
SELECT s.studentNo,studentName,subjectNo,studentResult
FROM student AS s
RIGHT JOIN result AS r
ON s.studentNo=r.studentNo

--left JOIN
SELECT s.studentNo,studentName,subjectNo,studentResult
FROM student AS s
LEFT JOIN result AS r
ON s.studentNo=r.studentNo

--====查詢缺考的同學======
SELECT s.studentNo,studentName,subjectNo,studentResult
FROM student AS s
LEFT JOIN result AS r
ON s.studentNo=r.studentNo
WHERE studentResult IS NULL
--思考題(查詢了參加考試的同學資訊:學號,學生姓名,科目名,分數)
/*思路
1.分析需求,分析查詢的欄位來自哪些表,(連表查詢)
2.確定用那種連線查詢?7種
確定交叉點(這兩個表中哪個資料是相同的)
判斷的條件:學生表中的 sudentNo=成績表studentNo
inner join  並集
*/
SELECT s.studentNo,studentName,subjectName,studentResult
FROM student AS s
RIGHT JOIN result AS r
ON r.studentNo=s.studentNo 
INNER JOIN `subject` AS sub
ON r.subjectNo=sub.subjectNo

--我要查詢哪些資料 SELECT
--從哪些表查詢 FROM 表 xxx JOIN 連線的表 ON 交叉條件
--假設存在多張表查詢  慢慢來 先查詢表兩張表在慢慢增加

--from a LEFT JOIN b
--from a RIGHT JOIN b

自連線

自己的表和自己的表連線,核心:一張表拆為兩張一樣的表

父類

categoryid categoryName
2 資訊科技
3 軟體開發
5 美術設計

子類

pid categoryid categoryName
3 4 資料庫
2 8 辦公資訊
3 6 web開發
5 7 美術設計

操作:查詢父類對應的子類關係

父類 子類
資訊科技 辦公資訊
軟體開發 資料庫
軟體開發 web開發
美術設計 ps技術
======自連線========

CREATE TABLE `category` (
`categoryid` INT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主體id',
`pid` INT(10) NOT NULL COMMENT '父id',
`categoryName` VARCHAR(40) NOT NULL COMMENT '主體名字',
PRIMARY KEY(`categoryid` )
)ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;


--查詢父子資訊 把一張表看為兩張一模一樣的表
SELECT a.`categoryName` AS '父欄目',b.`categoryName` AS '子欄目'
FROM `category` AS a,`category` AS b
WHERE a.`categoryid`=b.`pid`

--查詢學員所屬的年級(學號,學生姓名,年級名稱)

SELECT studentNo,studentName,gradeName
FROM student s
INNER JOIN grade g
WHERE s.gradeid=g.gradeid

--查詢科目所屬的年級(科目名稱,科目年級)
SELECT subjectName,gradeName
FROM `subject` sub
INNER JOIN grade g
ON sub.gradeid=g.gradeid

----思考題(查詢了參加資料庫結構-1 考試的同學資訊:學號,學生姓名,科目名,分數)
SELECT s.studentNo,studentName,subjectName,studentResult
FROM student s
INNER JOIN `result` r
ON s.studentNo=r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
WHERE subjectName='Java程式設計-1'

分頁和排序

-======================分頁和排序 ORDER BY===================
--排序: 升序  ASC,降序 DESC
SELECT s.studentNo,studentName,subjectName,studentResult
FROM student s
INNER JOIN `result` r
ON s.studentNo=r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
WHERE subjectName='Java程式設計-1'
ORDER BY studentResult DESC

-- 100萬
-- 為什麼要分頁
-- 緩解資料庫的壓力,給人體驗更好, 瀑布流

-- 分頁 每頁只顯示五條資料
-- 語法:limit 起始值  頁面的大小
--limit 0,5 1~5
--limit 1,5 2~6
--limmit 6,5 第二頁
SELECT s.studentNo,studentName,subjectName,studentResult
FROM student s
INNER JOIN `result` r
ON s.studentNo=r.studentNo
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
WHERE subjectName='Java程式設計-1'
ORDER BY studentResult DESC
LIMIT 4,2

-- 第一頁  LIMIT 0,5    (1-1)*5
-- 第二頁  LIMIT 5,5     (2-1)*5
-- 第三頁  LIMIT 10,5     (3-1)*5
-- 第N頁  LIMIT 0,5        (n-1)*pagesize, pagesize
--[pagesize:頁面大小]
--[(n-1)*pagesize:起始值]
--[n當前頁]
--[資料總數/頁面大小]
-- 思考
-- 查詢 java第一學年 課程成績排名前十的學生,並且分數要大於80的學生資訊(學號,姓名,課程名稱,分數)
SELECT s.studentNo,studentName,subjectName,studentResult
FROM student s
INNER JOIN `subject` sub
ON s.gradeid=sub.gradeid
INNER JOIN result r
ON r.subjectNo=sub.subjectNo
WHERE subjectName='Java程式設計-1' AND studentResult>=80
ORDER BY studentResult DESC

子查詢

-- ================where===================================

-- 1.查詢 Java程式設計-1 的所有考試結果(學號,科目編號,成績),降序排列
-- 方式一:使用連線查詢
SELECT studentNo,r.subjectNo,studentResult
FROM result r
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
WHERE subjectName='Java程式設計-1'
ORDER BY studentResult DESC

-- 方式二:使用子查詢()

SELECT studentNo,subjectNo,studentResult
FROM result 
WHERE subjectNo=ANY(
SELECT subjectNo FROM `subject`
WHERE subjectName='Java程式設計-1'
)
ORDER BY studentResult DESC

-- 分數不小於80分的學生的學號和姓名
-- 方式一:使用連線查詢
SELECT s.studentNo,studentName
FROM student s
INNER JOIN `result` r
ON s.studentNo=r.studentNo
WHERE studentResult>=80

-- 方式二:使用子查詢()

SELECT studentNo,studentName
FROM student 
WHERE studentNo=ANY(
SELECT studentNo FROM `result`
WHERE  studentResult>=8
)
-- 在這基礎上增加一個科目,C語言-3
-- 查詢高等數學-2的編號
SELECT s.studentNo,studentName
FROM student s
INNER JOIN `result` r
ON s.studentNo=r.studentNo
WHERE studentResult>=80 AND subjectNo=(
SELECT subjectNo FROM `subject`
WHERE subjectName='C語言-3'
)
-- 在改造(由裡及外)
SELECT studentNo,studentName FROM student WHERE studentNo IN(
SELECT studentNo FROM result WHERE studentResult>=80 AND subjectNo=(
SELECT subjectNo FROM `subject` WHERE subjectName='C語言-3'
)
)
--

分組和過濾

-- 查詢不同課程的平均分,最高分,最低分
-- 核心:(根據不同的課程分組)

SELECT subjectName,AVG(studentResult) AS 平均分,MAX(studentResult) AS 最大值,MIN(studentResult) AS 最小值
FROM result r
INNER JOIN `subject` sub
ON r.subjectNo=sub.subjectNo
GROUP BY r.subjectNo   -- 通過什麼欄位來分組
HAVING 平均分>80

MySQL函式

-- ===========================常用函式=======================

-- 數學運算
SELECT ABS(-8)   -- 絕對值
SELECT CEILING(9.4) -- 向上取整
SELECT FLOOR (9.4)  -- 向下取整
SELECT RAND()        -- 返回一個0~1之間的隨機數
SELECT SIGN(100)       -- 判斷一個數的符號 0-0 負數返回-1,正數返回1

-- 字串函式
SELECT CHAR_LENGTH('好好學習,休息休息') -- 字串長度
SELECT CONCAT('我','愛','學習')   -- 拼接字串
SELECT INSERT('我愛helloworld',1,2,'超級熱愛')  -- 查詢,從某個位置開始替換某個長度
SELECT LOWER('LoginServlet')  -- 小寫字母 
SELECT UPPER('LoginServlet')  -- 大寫字母
SELECT INSTR('LoginServlet','S') -- 返回第一次出現的字串的索引
SELECT REPLACE("我是嘻嘻試試哈哈","嘻嘻","哈哈") -- 替換出現的指定字串
SELECT SUBSTR("我是嘻嘻試試哈哈",4,6)  -- 返回出現的指定字串(源字串,擷取的位置,擷取的長度)
SELECT REVERSE('清晨我上馬')          -- 反轉

-- 查詢姓劉的同學,改為周
SELECT REPLACE (studentName,"劉","周") FROM student
WHERE studentName LIKE'劉%'

-- 日期和日期函式(記住)
SELECT CURRENT_DATE() -- 獲取當前日期
SELECT CURDATE()  -- 獲取當前日期
SELECT NOW()    -- 獲取當前時間
SELECT LOCALTIME()  -- 本地時間
SELECT SYSDATE()  -- 系統時間

SELECT YEAR(NOW())
SELECT MONTH(NOW())
SELECT DAY(NOW())
SELECT HOUR(NOW())
SELECT MINUTE(NOW())
SELECT SECOND(NOW())

-- 系統
SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()

5.1聚合函式(常用)

函式名稱 描述
COUNT() 計數
SUM() 求和
AVG() 平均值
MAX() 最大值
MIN() 最小值
..... ....
-- ===========================聚合函式======================
-- 都能統計表中的資料(想查詢一個表中有多少個記錄,就是用這個count())
SELECT COUNT(studentName) FROM student;   -- count(欄位),會忽略所有的null值
SELECT COUNT(*) FROM student              -- count(*),不會忽略null·值  本質 計算行數
SELECT COUNT(1) FROM result               -- count(1), 不會忽略所有的null值 本質 計算行數


SELECT SUM(studentResult) AS 總和 FROM result
SELECT AVG(studentResult) AS  平均分 FROM result
SELECT MAX(studentResult) AS 最大值 FROM result
SELECT MIN(studentResult) AS 最小值 FROM result

5.2 資料庫級別的MD5加密

什麼是MD5?

主要增強演算法複雜度和不可逆性

MD5不可逆,具體的值的MD5是一樣的

MD5破解網站的原理,背後有一個字典,MD5加密後的值,加密前的值

-- =================測試MD5 加密===========
CREATE TABLE `testmd5`(
`id` INT(10) NOT NULL,
`name` VARCHAR(40) NOT NULL,
`pwd` VARCHAR(60) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO `testmd5` VALUES(1,'小明','123456'),(2,'小王','123456'),(3,'小劉','123456')

-- 明文加密
UPDATE `testmd5` SET pwd=MD5(pwd) WHERE id=1  

UPDATE `testmd5` SET pwd=MD5(pwd)  --加密全部的密碼

-- 插入的時候加密
INSERT INTO `testmd5` VALUES(4,'小he',MD5('123456'))

-- 如何校驗:將使用者傳遞進來的密碼,進行MD5加密,然後比對加密後的值
SELECT * FROM testmd5 WHERE `name`='小he' AND pwd=MD5('123456')

6.事務

什麼是事務

  • 事務就是將一組SQL語句放在同一批次內去執行
  • 如果一個SQL語句出錯,則該批次內的所有SQL都將被取消執行
  • MySQL事務處理只支援InnoDB和BDB資料表型別

事務的ACID原則

  • 原子性(Atomicity)
    原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
    一致性(Consistency)
    事務前後資料的完整性必須保持一致。 1000
    隔離性(Isolation)
    事務的隔離性是多個使用者併發訪問資料庫時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作資料所幹擾,多個併發事務之間要相互隔離。
    永續性(Durability) --事務提交
    永續性是指一個事務一旦被提交,它對資料庫中資料的改變就是永久性的,接下來即使資料庫發生故障也不應該對其有任何影響 (事務一旦提交則不可逆,被持久化到資料庫中)

隔離導致的一些問題

髒讀:

指一個事務讀取了另外一個事務未提交的資料

不可重複讀:

在一個事務內讀取表中的某一行資料,多次讀取結果不同。(這個不一定是錯誤,只是某些場合不對)

頁面統計查詢值

虛讀(幻讀)

是指在一個事務內讀取到了別的事務插入的資料,導致前後讀取不一致。
(一般是行影響,多了一行)

執行事務

-- ===================事務===================

-- mysql  是預設開啟事務提交的
SET autocommit=0 /* 關閉*/
SET autocommit=1 /* 開啟*/

-- 手動處理事務
SET autocommit=0  -- 關閉自動提交

-- 事務開啟
START TRANSACTION  -- 標記一個事務的開始,從這個之後的sql 都在同一個事務內

INSERT xx
INSERT zz

-- 提交:持久化(成功!)
COMMIT
-- 回滾:回到原來的樣子
ROLLBACK

-- 事務結束
SET autocomit=1 -- 開啟自動提交

-- 瞭解
SAVEPOINT  儲存點名 -- 設定一個事務的儲存點
ROLLBACK TO SAVEPOINT 儲存點名 -- 回滾到儲存點
RELEASE  SAVEPOINT  儲存點名  -- 撤銷儲存點

7.索引

索引的作用

  • 提高查詢速度

  • 確保資料的唯一性

  • 可以加速表和表之間的連線 , 實現表與表之間的參照完整性

  • 使用分組和排序子句進行資料檢索時 , 可以顯著減少分組和排序的時間

  • 全文檢索欄位進行搜尋優化.

基礎語法

-- 索引的使用
-- 1.在建立表的時候給欄位增加索引
-- 2. 建立完畢後,增加索引

-- 顯示所有索引資訊
SHOW INDEX FROM student

-- 增加一個全文索引(索引名) 列名
ALTER TABLE shcool.student ADD FULLTEXT `studentName`(`studentName`);

EXPLAIN SELECT * FROM student; --非全文索引
EXPLAIN SELECT * FROM student WHERE MATH(studentName) AGAINST('劉')

分類

  • 主鍵索引 (Primary Key)
  • 唯一索引 (Unique)
  • 常規索引 (Index)
  • 全文索引 (FullText)

主鍵索引

主鍵 : 某一個屬性組能唯一標識一條記錄

特點 :

  • 最常見的索引型別
  • 確保資料記錄的唯一性
  • 確定特定資料記錄在資料庫中的位置

唯一索引

作用 : 避免同一個表中某資料列中的值重複

與主鍵索引的區別

  • 主鍵索引只能有一個
  • 唯一索引可能有多個
CREATE TABLE `Grade`(



    `GradeID` INT(11) AUTO_INCREMENT PRIMARYKEY,



    `GradeName` VARCHAR(32) NOT NULL UNIQUE



    -- 或 UNIQUE KEY `GradeID` (`GradeID`)



)

常規索引

作用 : 快速定位特定資料

注意 :

  • index 和 key 關鍵字都可以設定常規索引
  • 應加在查詢找條件的欄位
  • 不宜新增太多常規索引,影響資料的插入,刪除和修改操作
CREATE TABLE `result`(



    -- 省略一些程式碼



    INDEX/KEY `ind` (`studentNo`,`subjectNo`) -- 建立表時新增



)
-- 建立後新增



ALTER TABLE `result` ADD INDEX `ind`(`studentNo`,`subjectNo`);

全文索引

百度搜索:全文索引

作用 : 快速定位特定資料

注意 :

  • 只能用於MyISAM型別的資料表
  • 只能用於CHAR , VARCHAR , TEXT資料列型別
  • 適合大型資料集
 /*
#方法一:建立表時
      CREATE TABLE 表名 (
                欄位名1  資料型別 [完整性約束條件…],
                欄位名2  資料型別 [完整性約束條件…],
                [UNIQUE | FULLTEXT | SPATIAL ]   INDEX | KEY
                [索引名]  (欄位名[(長度)]  [ASC |DESC])
                );
#方法二:CREATE在已存在的表上建立索引
        CREATE  [UNIQUE | FULLTEXT | SPATIAL ]  INDEX  索引名
                     ON 表名 (欄位名[(長度)]  [ASC |DESC]) ;
#方法三:ALTER TABLE在已存在的表上建立索引
        ALTER TABLE 表名 ADD  [UNIQUE | FULLTEXT | SPATIAL ] INDEX
                             索引名 (欄位名[(長度)]  [ASC |DESC]) ;
                            
                            
#刪除索引:DROP INDEX 索引名 ON 表名字;
#刪除主鍵索引: ALTER TABLE 表名 DROP PRIMARY KEY;
#顯示索引資訊: SHOW INDEX FROM student;
*/
 
/*增加全文索引*/
ALTER TABLE `school`.`student` ADD FULLTEXT INDEX `studentname` (`StudentName`);
 
/*EXPLAIN : 分析SQL語句執行效能*/
EXPLAIN SELECT * FROM student WHERE studentno='1000';
 
/*使用全文索引*/
-- 全文搜尋通過 MATCH() 函式完成。
-- 搜尋字串作為 against() 的引數被給定。搜尋以忽略字母大小寫的方式執行。對於表中的每個記錄行,MATCH() 返回一個相關性值。即,在搜尋字串與記錄行在 MATCH() 列表中指定的列的文字之間的相似性尺度。
EXPLAIN SELECT *FROM student WHERE MATCH(studentname) AGAINST('love');
 
/*
開始之前,先說一下全文索引的版本、儲存引擎、資料型別的支援情況
MySQL 5.6 以前的版本,只有 MyISAM 儲存引擎支援全文索引;
MySQL 5.6 及以後的版本,MyISAM 和 InnoDB 儲存引擎均支援全文索引;
只有欄位的資料型別為 char、varchar、text 及其系列才可以建全文索引。
測試或使用全文索引時,要先看一下自己的 MySQL 版本、儲存引擎和資料型別是否支援全文索引。
*/

批量插入資料:100w

DROP FUNCTION IF EXISTS mock_data;
DELIMITER $$
CREATE FUNCTION mock_data()
RETURNS INT
BEGIN
  DECLARE num INT DEFAULT 1000000;
  DECLARE i INT DEFAULT 0;
  WHILE i < num DO
   INSERT INTO app_user(`name`, `email`, `phone`, `gender`, `password`, `age`)
    VALUES(CONCAT('使用者', i), '[email protected]', CONCAT('18', FLOOR(RAND()*(999999999-100000000)+100000000)),FLOOR(RAND()*2),UUID(), FLOOR(RAND()*100));
   SET i = i + 1;
  END WHILE;
  RETURN i;
END;
SELECT mock_data();

索引效率測試

無索引

SELECT * FROM app_user WHERE name = '使用者9999'; -- 檢視耗時
SELECT * FROM app_user WHERE name = '使用者9999';
SELECT * FROM app_user WHERE name = '使用者9999';
 
mysql> EXPLAIN SELECT * FROM app_user WHERE name = '使用者9999'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: app_user
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 992759
     filtered: 10.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)

建立索引

CREATE INDEX idx_app_user_name ON app_user(name);

測試普通索引

mysql> EXPLAIN SELECT * FROM app_user WHERE name = '使用者9999'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: app_user
   partitions: NULL
         type: ref
possible_keys: idx_app_user_name
          key: idx_app_user_name
      key_len: 203
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)
 
mysql> SELECT * FROM app_user WHERE name = '使用者9999';
1 row in set (0.00 sec)
 
mysql> SELECT * FROM app_user WHERE name = '使用者9999';
1 row in set (0.00 sec)
 
mysql> SELECT * FROM app_user WHERE name = '使用者9999';
1 row in set (0.00 sec)

索引準則

  • 索引不是越多越好
  • 不要對經常變動的資料加索引
  • 小資料量的表建議不要加索引
  • 索引一般應加在查詢條件的欄位

索引的資料結構

-- 我們可以在建立上述索引的時候,為其指定索引型別,分兩類
hash型別的索引:查詢單條快,範圍查詢慢
btree型別的索引:b+樹,層數越多,資料量指數級增長(我們就用它,因為innodb預設支援它)
 
-- 不同的儲存引擎支援的索引型別也不一樣
InnoDB 支援事務,支援行級別鎖定,支援 B-tree、Full-text 等索引,不支援 Hash 索引;
MyISAM 不支援事務,支援表級別鎖定,支援 B-tree、Full-text 等索引,不支援 Hash 索引;
Memory 不支援事務,支援表級別鎖定,支援 B-tree、Hash 等索引,不支援 Full-text 索引;
NDB 支援事務,支援行級別鎖定,支援 Hash 索引,不支援 B-tree、Full-text 等索引;
Archive 不支援事務,支援表級別鎖定,不支援 B-tree、Hash、Full-text 等索引;

8.許可權管理和備份

基本命令

/* 使用者和許可權管理 */ ------------------
使用者資訊表:mysql.user
 
-- 重新整理許可權
FLUSH PRIVILEGES
 
-- 增加使用者  CREATE USER kuangshen IDENTIFIED BY '123456'
CREATE USER 使用者名稱 IDENTIFIED BY [PASSWORD] 密碼(字串)
    -- 必須擁有mysql資料庫的全域性CREATE USER許可權,或擁有INSERT許可權。
    -- 只能建立使用者,不能賦予許可權。
    -- 使用者名稱,注意引號:如 'user_name'@'192.168.1.1'
    -- 密碼也需引號,純數字密碼也要加引號
    - -要在純文字中指定密碼,需忽略PASSWORD關鍵詞。要把密碼指定為由PASSWORD()函式返回的混編值,需包含關鍵字PASSWORD
 
-- 重新命名使用者  RENAME USER kuangshen TO kuangshen2
RENAME USER old_user TO new_user
 
-- 設定密碼
SET PASSWORD = PASSWORD('密碼')    -- 為當前使用者設定密碼
SET PASSWORD FOR 使用者名稱 = PASSWORD('密碼')    -- 為指定使用者設定密碼
 
-- 刪除使用者  DROP USER kuangshen2
DROP USER 使用者名稱
 
-- 分配許可權/新增使用者
GRANT 許可權列表 ON 表名 TO 使用者名稱 [IDENTIFIED BY [PASSWORD] 'password']
    -- all privileges 表示所有許可權
    -- *.* 表示所有庫的所有表
    -- 庫名.表名 表示某庫下面的某表
 
-- 檢視許可權   SHOW GRANTS FOR root@localhost;
SHOW GRANTS FOR 使用者名稱
    -- 檢視當前使用者許可權
    SHOW GRANTS; 或 SHOW GRANTS FOR CURRENT_USER; 或 SHOW GRANTS FOR CURRENT_USER();
 
-- 撤消許可權
REVOKE 許可權列表 ON 表名 FROM 使用者名稱
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 使用者名稱    -- 撤銷所有許可權

8.1MySQL備份

資料庫備份必要性

  • 保證重要資料不丟失
  • 資料轉移

MySQL資料庫備份方法

  • mysqldump備份工具
  • 資料庫管理工具,如SQLyog
  • 直接拷貝資料庫檔案和相關配置檔案

mysqldump客戶端

作用 :

  • 轉儲資料庫
  • 蒐集資料庫進行備份
  • 將資料轉移到另一個SQL伺服器,不一定是MySQL伺服器

img

-- 匯出
1. 匯出一張表 -- mysqldump -uroot -p123456 school student >D:/a.sql
  mysqldump -u使用者名稱 -p密碼 庫名 表名 > 檔名(D:/a.sql)
2. 匯出多張表 -- mysqldump -uroot -p123456 school student result >D:/a.sql
  mysqldump -u使用者名稱 -p密碼 庫名 表1 表2 表3 > 檔名(D:/a.sql)
3. 匯出所有表 -- mysqldump -uroot -p123456 school >D:/a.sql
  mysqldump -u使用者名稱 -p密碼 庫名 > 檔名(D:/a.sql)
4. 匯出一個庫 -- mysqldump -uroot -p123456 -B school >D:/a.sql
  mysqldump -u使用者名稱 -p密碼 -B 庫名 > 檔名(D:/a.sql)
 
可以-w攜帶備份條件
 
-- 匯入
1. 在登入mysql的情況下:-- source D:/a.sql
  source  備份檔案
2. 在不登入的情況下
  mysql -u使用者名稱 -p密碼 庫名 < 備份檔案

9.規範資料庫設計

為什麼需要資料庫設計

當資料庫比較複雜時我們需要設計資料庫

糟糕的資料庫設計 :

  • 資料冗餘,儲存空間浪費
  • 資料更新和插入的異常
  • 程式效能差

良好的資料庫設計 :

  • 節省資料的儲存空間
  • 能夠保證資料的完整性
  • 方便進行資料庫應用系統的開發

軟體專案開發週期中資料庫設計 :

  • 需求分析階段: 分析客戶的業務和資料處理需求
  • 概要設計階段:設計資料庫的E-R模型圖 , 確認需求資訊的正確和完整.

設計資料庫步驟

  • 收集資訊
    • 與該系統有關人員進行交流 , 座談 , 充分了解使用者需求 , 理解資料庫需要完成的任務.
  • 標識實體[Entity]
    • 標識資料庫要管理的關鍵物件或實體,實體一般是名詞
  • 標識每個實體需要儲存的詳細資訊[Attribute]
  • 標識實體之間的關係[Relationship]

三大正規化

問題 : 為什麼需要資料規範化?

不合規範的表設計會導致的問題:

  • 資訊重複
  • 更新異常
  • 插入異常
    • 無法正確表示資訊
  • 刪除異常
    • 丟失有效資訊

三大正規化

第一正規化 (1st NF)

第一正規化的目標是確保每列的原子性,如果每列都是不可再分的最小資料單元,則滿足第一正規化

第二正規化(2nd NF)

第二正規化(2NF)是在第一正規化(1NF)的基礎上建立起來的,即滿足第二正規化(2NF)必須先滿足第一正規化(1NF)。

第二正規化要求每個表只描述一件事情

第三正規化(3rd NF)

如果一個關係滿足第二正規化,並且除了主鍵以外的其他列都不傳遞依賴於主鍵列,則滿足第三正規化.

第三正規化需要確保資料表中的每一列資料都和主鍵直接相關,而不能間接相關。

規範化和效能的關係

為滿足某種商業目標 , 資料庫效能比規範化資料庫更重要

在資料規範化的同時 , 要綜合考慮資料庫的效能

通過在給定的表中新增額外的欄位,以大量減少需要從中搜索資訊所需的時間

通過在給定的表中插入計算列,以方便查詢