【MySQL 安装】基本操作命令

提示:本文章内容为繁体,基本都看得懂的。


提示:以下是本篇文章正文内容,下面案例可供参考

Installation 命令行安裝

Macos homebrew 安裝

brew install mysql
brew services list

Name              Status  User      File
...
mysql             started xxxxx ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
...
unbound           stopped

Status 為 started 代表mysql正在運行。

停止MySQL

brew services stop mysql
Stopping `mysql`... (might take a while)
==> Successfully stopped `mysql` (label: homebrew.mxcl.mysql)
brew services list

Name              Status  User      File
...
mysql             stopped xxxxx ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
...
unbound           stopped

Status 為 stopped 代表 mysql 停止運行。

啓動MySQL

brew services start mysql
==> Successfully started `mysql` (label: homebrew.mxcl.mysql)

MySQL-client

mysql-client 用於連接MySQL資料庫,在連接後可以直接對資料庫進行操作。

安裝

brew install mysql-client

連接指令

mysql -h <host> -u <user> -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 95788
Server version: 8.0.22 Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

MySQL 是一個資料庫伺服器,每個MySQL中有不止一個資料庫。當伺服器剛被創建時已經有一些跟MYSQL自身有關的資料庫存在其中,比如帳號密碼權限等等設備。因此還沒有創建任何資料庫時就已經有一些資料庫。可以使用SHOW DATABASES; 查看資料庫列表。

創造資料庫指令

CREATE DATABASE <database name>;

創造資料庫後想要對該資料庫進行操作必需進入該資料庫中。

USE <database name>;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

當顯示Database changed代表你已經進入到該資料庫中,接著讓我們創造一個資料表。在我們創造資料表前先了解一些知識。

每個MySQL有不止一個資料庫,每個資料庫中有不止一個表,每個資料表中有不止一筆資料。因為我們得到一個樹狀結構。

MySQL → Database → Table → Row 可以確定一筆資料。

資料表可以有多個欗位。每個欗位必須指令資料型態和欄位名稱(Column)。因此在創建資料表前來了解一些資料型態。重點關注字字串型態VARCHAR和數值型態INT。其他可以先不理。

資料型態

MySQL有眾多資料型態我們只取常用的解釋,詳細請到MySQL官方文檔查閱。

在了解VARCHAR和INT這兩個資料型態後讓我們來創造一個資料庫。我們將創造一個learn_table資料表(之後我們稱之為table),因為SQL大小寫不敏感所以我們使用Lower Snake Case(一種以小寫和下劃線命名的風格)風格命名。

CREATE TABLE learn_table
(
id INT,
name VARCHAR(255)
)ENGINE=innoDB,CHARSET=utf8;

每個資料表都會必須有一個主鍵,當我們沒有指定主鍵時會發生以下事件,這裹只是提及不需要確切理解,因為在正常情況下我們都會主動指定主鍵。

如果在创建表时没有显式地定义主键,则InnoDB存储引擎会按如下方式选择或创建主键:

1 首先判断表中是否有非空的唯一索引,如果有,则该列即为主键.

2 如果不符合上述条件,InnoDB存储引擎自动创建一个6字节大小的指针.

這裹我們要刪除剛剛創鍵的table,因為我們沒有主動指令主鍵,所以這個table效能不佳,並不是最佳實現。

DROP TABLE learn_table;

讓我們重新創建一個table,這裹我們指定id作為主鍵。

主鍵是一個不能重複的欗位,意味著如果有一個 id = 1012,就不能有第二個 id = 1012的資料,因此主鍵可以用於確認一筆資料。

CREATE TABLE learn_table
(
id INT, 
name VARCHAR(255),
first_name VARCHAR(10),
PRIMARY KEY(id)
)ENGINE=innoDB;

id INT 表示一個INT 的欗位叫id,name VARCHAR(255) 表示一個最長為255的動態長度字串資料,同理first_name VARCHAR(10) 最長為10的動態長度的字串資料。PRIMARY KEY(id) 表示我把id設定為主鍵。

讓我們插入一些資料到這個table。

格式為 INSERT INTO <table name> ([<column name>]) VALUE ([<VALUE>]);

INSERT INTO learn_table (id,name) VALUE ('1','hello');
Query OK, 1 row affected (0.08 sec)

當我們再插入一筆id = '1’的資料時會出現錯誤。

INSERT INTO learn_table (id,name) VALUE ('1','hello');
ERROR 1062 (23000): Duplicate entry '1' for key 'learn_table.PRIMARY'

驗證了id作為主鍵不能重複。

我們也可以同時插入多筆資料。

INSERT INTO learn_table (id, name) VALUES ('3','hello'),('4','hello'),('5','hello');

現在讓我們列印出learn_table的資料。指令為 SELECT [<column>] FROM <table name>; 以下範列使用* 表示要列印出所以欗位。

SELECT * FROM learn_table;
+----+-------+------------+
| id | name  | first_name |
+----+-------+------------+
|  1 | hello | NULL       |
|  3 | hello | NULL       |
|  4 | hello | NULL       |
|  5 | hello | NULL       |
+----+-------+------------+

first_name是NULL因為我們每次插入時都沒有指定它的值。我們也可以指定想要看的欗位。

SELECT id,name FROM learn_table;
+----+-------+
| id | name  |
+----+-------+
|  1 | hello |
|  3 | hello |
|  4 | hello |
|  5 | hello |
+----+-------+

我們也可以指定要的Row,使用WHERE

SELECT id AS uid, name FROM learn_table WHERE id = '1';
+----+-------+
| id | name  |
+----+-------+
|  1 | hello |
+----+-------+
SELECT id, name FROM learn_table WHERE id > '1';
+----+-------+
| id | name  |
+----+-------+
|  3 | hello |
|  4 | hello |
|  5 | hello |
+----+-------+
SELECT id, name FROM learn_table WHERE id < '4';
+----+-------+
| id | name  |
+----+-------+
|  1 | hello |
|  3 | hello |
+----+-------+
SELECT id, name FROM learn_table WHERE id < '4' OR id = '5';
+----+-------+
| id | name  |
+----+-------+
|  1 | hello |
|  3 | hello |
|  5 | hello |
+----+-------+
SELECT id, name FROM learn_table WHERE id < '4' AND name = 'hello';
+----+-------+
| id | name  |
+----+-------+
|  1 | hello |
|  3 | hello |
+----+-------+
SELECT id, name FROM learn_table WHERE id IN ('1','4');
+----+-------+
| id | name  |
+----+-------+
|  1 | hello |
|  4 | hello |
+----+-------+
SELECT id, name FROM learn_table WHERE name LIKE 'g%d';

WHERE 在SQL中經常使用,有各種型式的使用方法,讓我們試著刪除資料。註意在真實環境如果不是真的知道自己在做甚麼請必定使用WHERE 在刪除指令中。

改顯示的欗位名。

SELECT id AS uid FROM learn_table;
+-----+
| uid |
+-----+
|   4 |
|   5 |
+-----+

刪除資料

DELETE FROM learn_table;
Query OK, 4 rows affected (0.08 sec)
SELECT * FROM learn_table;
Empty set (0.08 sec)

learn_table 已經空了。因為我們沒有加上任何WHERE限制所以它直接把整個table清空,這是我們在真實環境必須要避免的。

讓我們重新插入資料。

INSERT INTO learn_table (id, name) VALUES ('3','human'),('4','god'),('5','man'),('412','good');

再一次刪除資料並使用WHERE限制。

DELETE FROM learn_table WHERE name IN ('good');

子語句,為了使用這個奇巧淫技,我們需要多一個table。

CREATE TABLE name_table
(
name VARCHAR(255),
PRIMARY KEY(name)
)ENGINE=innoDB,CHARSET=utf8;

讓我們來了解指令尾的ENGINE=innoDB; ,在CREATE TABLE 時有一些關於這個表的設定可以在指令尾使用,比如ENGINE=innoDB; 表示我們在這個表上使用innoDB引擎,mysql有幾種引擎供使用,這裹不多加贅述。CHARSET=utf8 表示這個table的字串使用utf8編碼。

然後讓我們插入一些資料。

INSERT INTO name_table (name) VALUES ('human'),('good');
SELECT name FROM name_table;

現在有兩個table就可以使用子語句,讓我們一次性刪除 learn_table 的name在name_table出現的資料。

DELETE FROM learn_table WHERE name IN (SELECT name FROM name_table);

可能你會想為甚麼要使用子語句,我們其實可以使用 SELECT 把 name 取出來再使用 for 來刪除資料,但其實子語句有其深層意義但在這裹就不多贅述。

更改資料,SQL使用UPDATE來更改資料,因為UPDATE 會破壞資料,所以也必須使用WHERE 限制其作用的範圍,不然整個table都資料都會變成一樣的。

格式為UPDATE <table> SET [<column> = '<value>'] WHERE <condition>;

UPDATE learn_table SET name = 'dan chen', first_name='yunda' WHERE id = '1';

UPDATE 同樣支援子語句,可是這軒涉到table 的join 等等更複雜的操作,所以在這先不演試。

到這裡我們己經介紹了增刪改查這足以完成絕大多數操作,增刪查改(英語:CRUD),全稱增加(Create,意為「建立」)、刪除(Delete)、查詢(Read,意為「讀取」)、改正(Update,意為「更新」)。以下是這些操作在其它系統中對應的操作。

安全性

SQL injection 是一種常見的弱點,攻擊方式是使用跳脫字符跳脫參數。以下用node 伺服器為例子。

var mysql = require('mysql');
var con = mysql.createConnection({
  host: "localhost",
  user: "yourusername",
  password: "yourpassword"
});
con.connect(function(err) {
  if (err) throw err;
  console.log("Connected!");
});
con.query(`SELECT * FROM learn_mysql WHERE id = '${<參數>}'`, function (err, result) {
  if (err) throw err;
  console.log("Result: " + result);
});

可以看到參數左右有' 符號,那如果我的參數包含了' 就可以跳脫限制,比如我使用' OR 1 = '1 作為參數就會發現sql語句變成了SELECT * FROM learn_mysql WHERE id = '' OR 1 = '1' 讓我們來解釋這一語句的意思。列印出所有id = ''或者 1 = '1'的欗位,id= ‘’ 不一定會成立可是1 = '1'是永真的語句,所以會列印出所有欗位。這樣可以讓用戶有權力不符的情況下查看所以資料。可以想像如果在DELETE或UPDATE請求時後果會很嚴重,會直接破壞所有資料。

預防方法

我們可以使用參數式來預防SQL injection,在不同語言不同函式數有不同寫法,以下我會以node js 的 mysql 為範例,一通則百通。

con.query(`SELECT * FROM learn_mysql WHERE id = ?`,[<參數>], function (err, result) {
  if (err) throw err;
  console.log("Result: " + result);
});

註意' 已經不存在而使用? 取代參數出現的地。這樣在函式庫內部會對參數進行處理從而避免SQL injection。

猜你喜欢

转载自blog.csdn.net/weixin_43523043/article/details/126725622