1. 程式人生 > >Mysql 8.0 第3章 簡單教程 (翻譯+理解)

Mysql 8.0 第3章 簡單教程 (翻譯+理解)

教程

官方第三章文件 點我

由於第3章都是一些操作性的例項,這裡就提取一下重點內容。

3.1 從伺服器連線和斷開

(1)連線: 指定 主機(-h),連線使用者(-u),密碼(-p)

shell> mysql -
h host -u user -p Enter password: ********

(2)斷開:
成功連線後,您可以通過在提示符mysql>後鍵入QUIT(或\q)來隨時斷開連線:

mysql> QUIT
Bye

在Unix上,您也可以通過按Control + D斷開連線。

3.2 輸入查詢

這是一個簡單的查詢,要求伺服器告訴您它的版本號和當前日期。

mysql> SELECT VERSION(), CURRENT_DATE;
+-----------+--------------+
| VERSION() | CURRENT_DATE |
+-----------+--------------+
| 5.8.0-m17 | 2015-12-21 | +-----------+--------------+ 1 row in set (0.02 sec) mysql>

1.查詢語句以分號結尾,有些不用比如QUIT
2.輸出結果是表格形式,頭行顯示列名(你可以使用 as+別名 指定列名或用預設的)
3.輸出結果還顯示一個粗略的時間,表示查詢執行了多久,這個時間是系統時間(wall clock time)而不是CPU時間
4.關鍵字不區分大小寫,如 sElect 等同於sELECt

mysql> SeLeCt vErSiOn(), current_DATE;

5.select 後面接算數表示式可以做個計算器 select 1+2

;
6.一行可以寫多個語句,用分號分隔開就行

mysql> SELECT VERSION(); SELECT NOW();

7.一條語句太長可以多行,用分號分結尾就行

mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;

8.臨時取消語句:輸入\c
9. -> 等你輸入 '> "> `> /*> 這4個等你輸入相應的閉合字元

mysql> SELECT * FROM my_table WHERE name = 'Smith AND age < 30;
    '>

10.字串可以使用單引號或雙引號來包裹

3.3 建立和使用資料庫

後面的查詢例子都用了一個官方提供的寵物資料庫,先下載

1.顯示所有資料庫: SHOW DATABASES;

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+

2.使用某個資料庫 USE dbname;

mysql> USE test
Database changed

3.管理員使用者或root賦予使用者('your_mysql_name'@'your_client_host')某一資料庫(dbname)的所有許可權

GRANT ALL ON dbname.* TO 'your_mysql_name'@'your_client_host';

3.3.1 建立和選擇資料庫

1.建立資料庫,create database dbname:
linux機器上庫名區分大小寫,所以建議建立 小寫的 庫名,表名,列名。

mysql> CREATE DATABASE menagerie;

2.連線資料庫提供密碼的兩種方式
a. 使用-p, p後留空白,代表在下一行輸入密碼。

shell> mysql -h host -p -u user 
Enter password: ********

b. 使用-ppassword,p後直接跟密碼。

shell> mysql -h host  -u user -ppassword

3.3.2 建立表

1.顯示當前資料庫內的表 show tables;

2.建立一個寵物pet表和event表

CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
CREATE TABLE event (name VARCHAR(20), date DATE,type VARCHAR(15), remark VARCHAR(255));

3.VARCHAR型別可以指定列的長度,可選1~65535
4.檢查建立pet表的語法 describe pet;或者desc pet;

mysql> DESCRIBE pet;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name    | varchar(20) | YES  |     | NULL    |       |
| owner   | varchar(20) | YES  |     | NULL    |       |
| species | varchar(20) | YES  |     | NULL    |       |
| sex     | char(1)     | YES  |     | NULL    |       |
| birth   | date        | YES  |     | NULL    |       |
| death   | date        | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+

3.3.3 將資料載入到表中

1.可以使用LOAD DATAInsert into兩種方法載入資料
2.如果你的資料在txt中,可以用tab來區分每一個列,使用\N表示當前資料為空,使用'YYYY-MM-DD'表示一個日期。
下面是pet.txt中的資料:
在這裡插入圖片描述
3.1 使用LOAD DATA匯入資料

LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;

windows提供檔案路徑使用雙反斜線C:\\windows\\pet.txt

注意:如果出現錯誤The used command is not allowed with this MySQL version,那是因為系統變數local_infile沒有開啟。

解決方案:
(1)停止mysql服務,修改配置檔案,在[mysqld]部分增加

[mysqld]
local_infile = ON

(2)開啟mysql服務,使用mysql客戶端連線的時候提供引數--local-infile=1

shell> mysql -uxxx -P 34567 -p  menagerie --local-infile=1

(3)執行LOAD DATA,插入成功。
(4)如果你的匯入還有問題,請參閱 Section 6.1.6, “Security Issues with LOAD DATA LOCAL“

3.2 使用INSERT INTO 一次插入一條

INSERT INTO pet VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);

3.3.4 從表中檢索資訊

0.檢索pet表資料

select * from pet;
SELECT * FROM pet WHERE birth >= '1998-1-1';

1.修改某條資料

UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';

字串比較時通常對大小些不敏感,例如 BOWser

2.ANDOR可以混用,但AND比OR具有更高的優先順序.如果你使用兩個操作符,使用圓括號指明如何對條件進行分組

SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm') OR (species = 'dog' AND sex = 'f');

3.對選擇的列去重

SELECT DISTINCT owner FROM pet;

增加關鍵字DISTINCT檢索出每個唯一的輸出記錄,DISTINCT後面可以接多列進行最少輸出

4.對結果進行排序

SELECT name,birth FROM pet order by [binary] birth [ASC|DESC]; 

預設排序是升序(ASC) ,且大小寫不敏感,如果想敏感可以在列名前增加binary,如果降序可以用DESC;可以對每個列都進行排序 (有種先分組再在組內排序的意思)

mysql> SELECT name, species, birth FROM pet
    -> ORDER BY species, birth DESC;
+----------+---------+------------+
| name     | species | birth      |
+----------+---------+------------+
| Chirpy   | bird    | 1998-09-11 |
| Whistler | bird    | 1997-12-09 |
| Claws    | cat     | 1994-03-17 |
| Fluffy   | cat     | 1993-02-04 |
| Fang     | dog     | 1990-08-27 |
| Bowser   | dog     | 1989-08-31 |
| Buffy    | dog     | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim     | snake   | 1996-04-29 |
+----------+---------+------------+

5.日期計算
(1)年齡的兩種計算方式

  • 使用內建的TIMESTAMPDIFF方法(簡單)
SELECT name, birth, CURDATE(),TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age FROM pet;
  • 先算年,然後日期比較看是否要-1
SELECT name,birth,(YEAR(CURDATE())-YEAR(birth))- (RIGHT(CURDATE(),5)<RIGHT(birth,5)) AS age FROM pet; 

(2)下個月過生日計算的兩種方法:

  • 使用內建DATE_ADD函式
SELECT name, birth FROM pet  WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
  • 使用內建MOD函式
SELECT name, birth FROM pet  WHERE MONTH(birth) = MOD(MONTH(CURDATE()),12)+1

6.空值NULL
使用colnum IS NOT NULL而非colnum != NULL來進行比較,因為NULL是特殊的值,不能使用普通比較符來比較;

mysql> SELECT 1 IS NULL, 1 IS NOT NULL; 
		-> 0,1

NULL的算數比較結果都是NULL ,

mysql> SELECT 1 = NULL, 1 <> NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 <> NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
|     NULL |      NULL |     NULL |     NULL |
+----------+-----------+----------+----------+

In MySQL,0 or NULL means false and anything else means true

GROUP BY中,兩個NULL值視為相同

使用ORDER BY排序時,如果有NULL值,則它出現在最前面;DESC的時候,出現在最後面。

mysql> select sex from pet order by sex asc;

在這裡插入圖片描述

7.模式匹配

模式匹配允許你使用 _ 匹配任何單個字元(包含0個字元)
%匹配任意數目字元(包括0個字元)
模式匹配預設是忽略大小寫的(BINARY 來強制敏感)
使用LIKENOT LIKE (或者使用 REGEXPNOT REGEXP

mysql> SELECT * FROM pet WHERE name LIKE '%w%';
mysql> SELECT * FROM pet WHERE REGEXP_LIKE(name, '^b');

更多請見 Section 12.5.2, “Regular Expressions”.

8.計數
(1)瞭解每位業主擁有多少寵物

SELECT owner, COUNT(*) FROM pet GROUP BY owner;

(2)group by 用在 where 之後
(3)用在groupb by 語句中,如果你使用了某一列(name),和一個聚合函式列,你需要指定group by name,否則在ONLY_FULL_GROUP_BY這種sql模式下會報錯,例如:

mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY';
mysql> SELECT owner, COUNT(*) FROM pet;
ERROR 1140 (42000): In aggregated query without GROUP BY, expression
#1 of SELECT list contains nonaggregated column 'menager

修改為下面的語句,才會正常:

SELECT owner, COUNT(*) FROM pet group by owner;

9.連線多表

  • Inner join 連線兩張表 (比如,查詢寵物生寶寶時候的年齡和具體細節
SELECT pet.name, TIMESTAMPDIFF(YEAR,birth,date) AS age,remark
FROM pet INNER JOIN event ON pet.name = event.name
WHERE event.type = 'litter'; 
  • 連線自身
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species FROM pet AS p1, pet AS p2 
WHERE p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';
+--------+------+--------+------+---------+
| name   | sex  | name   | sex  | species |
+--------+------+--------+------+---------+
| Fluffy | f    | Claws  | m    | cat     |
| Buffy  | f    | Fang   | m    | dog     |
| Buffy  | f    | Bowser | m    | dog     |
+--------+------+--------+------+---------+

10.如果表有索引,SHOW INDEX FROM tbl_name生成有關索引的資訊。

3.5 在批處理模式下使用mysql

(1)windows下:

mysql -e "source C:\\Users\\eve\\Desktop\\batch.txt" [>file| more] [-t -vvv]

(2)linux 下:

msyql < batch.txt 

cron模式下不許使用互動,最好使用批處理檔案

3.6. 常用查詢的例子

1.例項表:

CREATE TABLE shop (article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,dealer  CHAR(20) DEFAULT '' NOT NULL,price DOUBLE(16,2)  DEFAULT '0.00' NOT NULL,PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),(3,'D',1.25),(4,'D',19.95);

(1)求某列中的最大值

SELECT MAX(article) AS article FROM shop;

(2)求擁有某列最大值的行

例如:找出最貴物品(article)的價格(price),經銷商(dealer),有三種解決方案

  • a 子查詢
SELECT article, dealer, price
FROM   shop
WHERE  price=(SELECT MAX(price) FROM shop);
  • b 左連線 或右連線
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price < s2.price
WHERE s2.article IS NULL;

SELECT s1.article, s1.dealer, s1.price
FROM shop s1
RIGHTJOIN shop s2 ON s1.price > s2.price
WHERE s1.article IS NULL;
  • c order by + limit
SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1;

如果有幾個最昂貴的文章,每個價格為19.95,LIMIT解決方案只顯示其中一個。

(3)求每組擁有的最大列值
例如:找到每種物品的最高價格

select article,max(price) from shop group by article;

(4)求每組內擁有某列最大值的行
例如:對每項物品,找出最貴价格的物品的經銷商。

  • 通過子查詢(這是一個相關子查詢,效率可能低下)
SELECT article, dealer, price
FROM   shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article)
ORDER BY article;
  • 在FROM內使用非相關子查詢
SELECT s1.article, dealer, s1.price
FROM shop s1
JOIN (
  SELECT article, MAX(price) AS price
  FROM shop
  GROUP BY article) AS s2
  ON s1.article = s2.article AND s1.price = s2.price
ORDER BY article;
  • 左外連線
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.article = s2.article AND s1.price < s2.price
WHERE s2.article IS NULL
ORDER BY s1.article;

更多關於連線的使用,請參考 第13.2.10.2節“JOIN語法”

  • 帶視窗函式的公用表表達式
WITH s1 AS (
   SELECT article, dealer, price,
          RANK() OVER (PARTITION BY article
                           ORDER BY price DESC
                      ) AS `Rank`
     FROM shop
) 
SELECT article, dealer, price
  FROM s1
  WHERE `Rank` = 1 
ORDER BY article;

2.使用使用者變數

SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;

3.確定每個月的訪問天數
3.1 例項表

CREATE TABLE t1 (year YEAR(4), month INT(2) UNSIGNED ZEROFILL,
             day INT(2) UNSIGNED ZEROFILL);
INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),
            (2000,2,23),(2000,2,23);
SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1 GROUP BY year,month

4.對於MyISAM表,在一張表的第二列定義列含有 AUTO_INCREMENT屬性,並將一二列做成多列索引,可以達成一種資料分組的情況,例如:

CREATE TABLE animals (
    grp ENUM('fish','mammal','bird') NOT NULL,
    id MEDIUMINT NOT NULL AUTO_INCREMENT,
    name CHAR(30) NOT NULL,
    PRIMARY KEY (grp,id)
) ENGINE=MyISAM;

INSERT INTO animals (grp,name) VALUES
    ('mammal','dog'),('mammal','cat'),
    ('bird','penguin'),('fish','lax'),('mammal','whale'),
    ('bird'