數據庫 MySQL 基本操作 語法 [MD]


博文地址

我的GitHub 我的博客 我的微信 我的郵箱
baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目錄

數據庫管理系統操作

參考:21分鍾MySQL基礎入門

查看版本號

-- 登錄前
mysql -V
mysql --help | grep Ver

-- 登錄后
select version();
status;

啟動及關閉服務

-- 啟動服務
net start mysql
mysqld --console

-- 關閉服務
net stop mysql
mysqladmin -uroot shudown

登錄及退出

-- 登錄
mysql [-D 所選擇的數據庫名] [-h 主機名] -u 用戶名 -p
mysql -u root -p

-- 退出
exit;
quit;
\q;

其他

-- 登錄前查看本地 MySQL 服務是否啟動
netstat -an|find "3306"

-- 登錄后查看MySQL端口號
show global variables like 'port';

數據庫操作

創建數據庫 create

create database db_name;
create database db_name character set gbk;

-- 創建一個使用字符集並帶校對規則的數據庫
create database db_name character set utf-8 collate utf8_bin;

查看數據庫 show/select

show databases;

-- 查看創建數據庫時的定義信息
show create database db_name;

-- 查看當前所選的數據庫
select database();

其他操作 alter/drop/use

-- 修改數據庫字符編碼
alter database db_name character set utf8;

-- 刪除數據庫
drop database db_name;

-- 進入(切換)數據庫,對於表的操作需要先進入庫
use db_name;

數據庫-表操作

詳細內容參考

MySQL有三大類數據類型,分別為數字、日期/時間、字符串,這三大類中又更細致的划分了許多子類型:

  • 數字類型
    • 整數: tinyint、smallint、mediumint、int、bigint
      取值范圍如果加了unsigned,代表無符號,則可存儲的最大值翻倍
      int(m) 里的 m 是表示 SELECT 查詢結果集中的顯示寬度,並不影響實際的取值范圍
    • 浮點數: float、double、real、decimal
  • 日期和時間: date、time、datetime、timestamp、year
  • 字符串類型
    • 字符串: char、varchar
    • 文本: text、tinytext、mediumtext、longtext
    • 二進制: blob、tinyblob、mediumblob、longblob

創建表 create

create table if not exists `user_accounts` (
  `id`             int(100) unsigned NOT NULL AUTO_INCREMENT primary key,
  `password`       varchar(32)       NOT NULL DEFAULT '' COMMENT '用戶密碼',
  `reset_password` tinyint(32)       NOT NULL DEFAULT 0  COMMENT '用戶類型:0-不需要重置密碼;1-需要重置密碼',
  `mobile`         varchar(20)       NOT NULL DEFAULT '' COMMENT '手機',
  `create_at`      timestamp(6)      NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
  `update_at`      timestamp(6)      NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  -- 創建唯一索引,不允許重復
  UNIQUE INDEX idx_user_mobile(`mobile`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8
COMMENT='用戶表信息';

數據類型的屬性解釋

  • NULL:數據列可包含NULL值
  • NOT NULL:數據列不允許包含NULL值
  • DEFAULT:默認值
  • PRIMARY KEY:主鍵
  • AUTO_INCREMENT:自動遞增,適用於整數類型
  • UNSIGNED:是指數值類型只能為正數(即無符號的)
  • CHARACTER SET name:指定一個字符集
  • COMMENT:對表或者字段說明

查看表 show/desc

-- 查看當前數據庫中所有表
show tables

-- 查看當前數據庫表建表語句
show create table tableName

-- 查看表結構,也可用全稱describe
desc tableName

刪除表 delete/truncate/drop

-- 清空表中的數據,不刪除表;可以回退,可以帶 where 條件的刪除
delete from tableName;

-- 刪除表中的所有數據,不刪除表;無法回退,默認所有的表內容都刪除,刪除速度比delete快
truncate table tableName;

-- 刪除整張表
drop table tableName;
DROP TABLE IF EXISTS tableName;

其他操作 rename

-- 重命名表
alter table oldName rename newName;
rename table oldName to newName;

-- 修改表的字符集
alter table tableName character set gbk;

數據庫-表-列操作 alter

添加列 add

-- 語法:alter table 表名 add [column] 列名 列數據類型 [after 插入位置];
alter table students add address char(60);
alter table students add column birthday date after age;
alter table students add `weeks` varchar(5) not null default "" after `number`;

修改列 change/modify

-- 語法:alter table 表名 change 列名稱 列新名稱 新數據類型;
alter table students change tel telphone char(13) default "-";
alter table students change name name char(16) not null;

-- 修改 COMMENT 前面必須得有類型屬性
alter table students change name name char(16) COMMENT '這里是名字';

-- change用於修改列名字,需要重建表;僅修改列屬性的時候建議使用modify,不需要重建表
alter table meeting modify `weeks` varchar(20) NOT NULL DEFAULT '' COMMENT '開放日期';
alter table meeting modify `id` INT NOT NULL;

-- FIRST 表示放在第一列的位置
alter table `user` modify COLUMN `id` varchar(50) NOT NULL FIRST;

刪除列 drop

-- 語法:alter table 表名 drop 列名稱;
alter table students drop birthday;

數據庫-表-記錄操作

插入記錄 insert into

-- 語法:INSERT INTO 表名稱 [(列1, 列2,...)] VALUES (值1, 值2,...)
INSERT INTO Persons (LastName, Address) VALUES ('JSLite', 'shanghai');
INSERT INTO meeting SET a=1,b=2;

-- 如果要插入所有字段可以省寫列列表,直接按表中字段順序寫值列表
insert into employee values (1,'ceo',800,'公司老大'), (2,'cto',300,'技術老大');

-- 插入一條數據,如果已存在就更新address和update_at字段,字符和日期型數據應包含在單引號中
INSERT INTO students (id,address,update_at) VALUES (3,'gz','2020-10-17') ON DUPLICATE KEY UPDATE id=VALUES(id), address=VALUES(address), update_at='2020-10-18';

-- 將一個表的數據插入到另外一個表:INSERT INTO 目標表 (列1,列2...) SELECT 字段1, 字段2, ... FROM 來源表;
INSERT INTO orders (num, title) SELECT m.user_id, m.title FROM meeting m where m.id=1;

更新記錄 update set

-- 語法:UPDATE 表名稱 SET 列名稱 = 新值 [WHERE]
UPDATE orders set title='新標題' WHERE id=1;

-- WHERE子句指定應更新哪些行。如沒有WHERE子句,則更新所有的行
update employee set salary = 3000 where name='張飛';
update employee set salary = 4000,job='ccc' where name='關羽';
update employee set salary = salary + 1000 where name='劉備';
update employee set salary = 5000;

-- 設置字段的值為另一個結果取出來的字段
update user set name = (select name from user1 where user1.id = 1 ) where id = (select id from user2 where user2 .name='小蘇');

刪除記錄 delete from

-- 語法:DELETE FROM 表名稱 [WHERE]
DELETE FROM Person WHERE LastName = 'JSLite'
DELETE from meeting where id in (2,3);

-- 如果不使用where子句,將刪除表中所有數據(不刪除表本身)
DELETE FROM table_name
DELETE * FROM table_name

-- 使用truncate刪除表中記錄和使用delete有所不同,參看mysql文檔
truncate table employee;

查找記錄 select from

-- 語法:SELECT 列名稱 FROM 表名稱 [WHERE]
select name,english from exam;
select * from exam;

-- 只拉一條數據(據說limit能優化性能)
SELECT * FROM users where id=3 limit 1

-- 過濾重復數據
select distinct english from exam;

-- 在所有學生數學分數上加10分顯示
select name, math+10 from exam;

-- 使用別名表示學生總分(as可以省略),統計每個學生的總分
select name as 姓名 ,english+math+chinese 總成績 from exam;
SELECT s.id from station s WHERE id in (13,14) and id not in (4);

-- 結果集顯示 Persons表的 LastName、FirstName字段,Orders表的OrderNo字段
SELECT p.LastName, p.FirstName, o.OrderNo FROM Persons p, Orders o WHERE p.Id_P = o.Id_P 

-- 中英文混合排序最簡單的辦法;ci是 case insensitive, 即 “大小寫不敏感”
SELECT tag, COUNT(tag) from news GROUP BY tag order by convert(tag using gbk) collate gbk_chinese_ci;
SELECT tag, COUNT(tag) from news GROUP BY tag order by convert(tag using utf8) collate utf8_unicode_ci;

數據庫-表-索引操作

參考 菜鳥教程:MySQL 索引

索引的建立對於 MySQL 的高效運行是很重要的,索引可以大大提高 MySQL 的檢索速度。

索引分單列索引組合索引

  • 單列索引:即一個索引只包含單個列,一個表可以有多個單列索引,但這不是組合索引
  • 組合索引:即一個索引包含多個列

建立索引會占用磁盤空間的索引文件。實際上,索引也是一張表,該表保存了主鍵與索引字段,並指向實體表的記錄

索引也有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,因為更新表時,MySQL 不僅要保存數據,還要保存索引文件。

建立索引的時機

WHEREJOIN中出現的列需要建立索引,但也不完全如此:

  • MySQL 只對< <= = > >= BETWEEN IN使用索引
  • 某些時候的LIKE也會使用索引
  • 在LIKE以通配符%_作為 開頭 查詢時,MySQL 不會使用索引

普通索引 index

普通索引的索引值可出現多次

-- 方式一,創建表的時候直接指定索引,語法:INDEX [indexName] (columnName[(length)])
CREATE TABLE tableName(
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `title` CHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    PRIMARY KEY (`id`),
    INDEX indexName (title(8))
    -- length:BLOB和TEXT類型必須指定 length;CHAR、VARCHAR類型時,length 可以小於字段實際長度
    -- 【INDEX indexName (title)】:可忽略 length,但是不能忽略 columnName 外的小括號
    -- 【INDEX (title)】:忽略 indexName 時,indexName 取 columnName 的值
);

-- 方式二,修改表結構方式添加索引,語法:ALTER table tableName ADD INDEX indexName(columnName[(length)])
ALTER table tableName ADD INDEX indexName(title(6))

-- 方式三,直接創建索引,語法:CREATE INDEX indexName ON tableName (columnName[(length)])
CREATE INDEX indexName ON tableName (title(6))

唯一索引 unique

唯一索引的值必須唯一,但允許有空值;如果是組合索引,則列值的組合必須唯一。

CREATE TABLE tableName(
  ...,
  -- 方式一:UNIQUE INDEX [indexName] (columnName[(length)])
  -- UNIQUE [indexName] (columnName[(length)])
);

-- 方式二:ALTER table tableName ADD INDEX indexName(columnName[(length)])
-- 方式三:CREATE UNIQUE INDEX indexName ON tableName (columnName[(length)])

主鍵索引 primary key

主鍵索引需要確保索引值必須是唯一的,且不能為NULL。

CREATE TABLE tableName (
  -- AUTO_INCREMENT:自動增長;NOT NULL:非空約束
  `id` int(11) NOT NULL AUTO_INCREMENT ,
  `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
  -- 方式一:創建表的時候指定,主鍵名indexName其實就是【PRIMARY】
  PRIMARY KEY (`id`)
)

-- 方式二:ALTER table tableName ADD PRIMARY KEY(columnName[(length)])
ALTER TABLE tableName ADD PRIMARY key (id);

全文索引 fulltext

-- ALTER TABLE tableName ADD FULLTEXT indexName (columnName[(length)])
-- 給 user 表中的 description 字段添加全文索引
ALTER TABLE user ADD FULLTEXT (description);

刪除索引 drop

-- 刪除主鍵時只需指定 PRIMARY KEY,刪除其他索引時,須指定索引名
DROP INDEX indexName ON tableName;
ALTER TABLE tableName DROP INDEX indexName;
ALTER TABLE tableName DROP PRIMARY KEY;

多列索引

-- ALTER TABLE tableName ADD INDEX indexName (column1, column2, column3)
ALTER TABLE user ADD INDEX name_city_age (name(10),city,age);

顯示索引信息

-- 列出表中的相關的索引信息
SHOW INDEX FROM tableName;

幾個關鍵字

過濾 where

select * from exam where name='張飛';
select * from exam where name like '張%';
select * from exam where math > 90;

-- IN 操作符允許我們在 WHERE 子句中規定多個值
select * from exam where math in(75,76,77);

select * from exam where math between 80 and 100;
select * from exam where math > 70 and chinese > 80;
select name 姓名, math+english+chinese 總分 from exam where math+english+chinese > 230;

排序 order by

ORDER BY 語句用於根據指定的列對結果集進行排序

  • DESC - 按照降序對記錄進行排序
  • ASC - 按照順序(升序)對記錄進行排序(默認)
-- Company在表Orders中為字母,則會以字母順序(升序)顯示公司名稱;后面跟上 DESC 則為降序顯示
SELECT Company, OrderNumber FROM Orders ORDER BY Company
SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC

-- 首先根據Company以降序顯示,然后根據OrderNumber以順序顯示
SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC, OrderNumber ASC

-- 對姓張的學生根據總成績按從高到低的順序輸出
select name 姓名,chinese+math+english 總成績 from exam where name like '張%' order by 總成績 desc;

分組查詢 group by

-- 對訂單表中商品歸類后,顯示每一類商品的總價
select product,sum(price) from orders group by product;

-- 查詢購買了幾類商品,並且每類總價大於100的商品
select product 商品名,sum(price)商品總價 from orders group by product having sum(price)>100;

-- 查詢單價小於100而總價大於150的商品的名稱
select product from orders where price<100 group by product having sum(price)>150;

邏輯運算 and or not

SELECT * FROM Persons WHERE FirstName='Thomas' AND LastName='Carter';
DELETE from meeting where id in (2,3) and user_id in (5,6);
SELECT * FROM Persons WHERE firstname='Thomas' OR lastname='Carter'

-- NOT 操作符總是與其他操作符一起使用,用在要過濾的前面。
SELECT vend_id, prod_name FROM Products WHERE NOT vend_id = 'DLL01' ORDER BY prod_name;

合並結果集 union

合並兩個或多個 SELECT 語句的結果集

-- 列出所有在中國表和美國表的不同的雇員名
SELECT E_Name FROM Employees_China UNION SELECT E_Name FROM Employees_USA

-- 列出 meeting 表中的 pic_url,station 表中的 number_station 別名設置成 pic_url 避免字段不一樣報錯
-- 按更新時間排序
SELECT id,pic_url FROM meeting UNION ALL SELECT id,number_station AS pic_url FROM station ORDER BY update_at;

-- 通過 UNION 語法同時查詢了 products 表 和 comments 表的總記錄數,並且按照 count 排序
SELECT 'product' AS type, count(*) as count FROM `products` union select 'comment' as type, count(*) as count FROM `comments` order by count;

重命名 as

-- 重命名列名或者表名,語法:select columnName as 列昵稱 from tableName as 表昵稱
-- 把Employee表命名為 emp,命名一個表之后,你可以在下面用 emp 代替 Employee
SELECT * FROM Employee AS emp

-- 列出表 Orders 字段 OrderPrice 列最大值,結果集列不顯示 OrderPrice 顯示 LargestOrderPrice
SELECT MAX(OrderPrice) AS LargestOrderPrice FROM Orders

-- 顯示表 users_profile 中的 name 列
SELECT t.name from (SELECT * from users_profile a) AS t;

聚合函數

統計個數 count

-- 語法:SELECT COUNT("字段名") FROM "表格名"
SELECT COUNT (Store_Name) FROM Store WHERE Store_Name IS NOT NULL;

-- 統計一個班級共有多少學生
select count(*) from exam;
select count(*) from exam where math > 70;
select count('什么有效的值都可以') as totals from exam;

最值 max/min

-- MAX 函數返回一列中的最大值,NULL 值不包括在計算中
SELECT MAX(OrderPrice) AS LargestOrderPrice FROM Orders
select max(ifnull(chinese,0) + ifnull(english,0) + ifnull(math,0)) from exam;

求和 sum

-- 將符合條件的記錄的指定列進行求和操作
select sum(math) from exam;
select sum(math),sum(math)/count(*) 平均分 from exam;

-- sum僅對數值起作用,否則會報錯;計算時,只要有null參與計算,整個計算結果都是null;可以用ifnull處理
select sum(ifnull(chinese,0)+ifnull(english,0)+ifnull(math,0)) from exam;

平均值 avg

-- 計算符合條件的記錄的指定列的值的平均值
select avg(math) from exam;
select avg(ifnull(chinese,0) + ifnull(english,0) + ifnull(math,0)) from exam;

多表設計與多表查詢

外鍵約束 foreign key

表是用來保存現實生活中的數據的,而現實生活中數據和數據之間往往具有一定的關系,我們在使用表來存儲數據時,可以明確的聲明表和表之前的依賴關系,命令數據庫來幫我們維護這種關系,像這種約束就叫做外鍵約束

create table dept(
   id int primary key auto_increment,
   name varchar(20)
);

create table emp(
   id int primary key auto_increment,
   name varchar(20),
   dept_id int,
-- 定義外鍵約束:foreign key(本表的列名) references 引用的表名(引用的表中的列名)
   foreign key(dept_id) references dept(id)
);

多表設計

不同場景下的多表設計思路:

  • 一對一:在任意一方保存另一方的主鍵作為外鍵
  • 一對多:在多的一方保存一的一方的主鍵做為外鍵
  • 多對多:創建第三方關系表保存兩張表的主鍵作為外鍵,保存他們對應關系

多表查詢 join

笛卡爾積查詢

將兩張表的記錄進行一個相乘的操作查詢出來的結果就是笛卡爾積查詢

如果左表有 n 條記錄,右表有 m 條記錄,笛卡爾積查詢出有n*m條記錄,其中往往包含了很多錯誤的數據,所以這種查詢方式並不常用。

select * from dept,emp;

內連接查詢 inner

-- 查詢的是左邊表和右邊表都能找到對應記錄的記錄
select * from dept,emp where dept.id = emp.dept_id;
select * from dept inner join emp on dept.id=emp.dept_id;

左/右外連接查詢 left/right

-- 左外連接查詢:在內連接的基礎上,增加左邊表有而右邊表沒有的記錄
select * from dept left join emp on dept.id=emp.dept_id;

-- 右外連接查詢:在內連接的基礎上,增加右邊表有而左邊表沒有的記錄
select * from dept right join emp on dept.id=emp.dept_id;

全外連接 union

-- 全外連接查詢:在內連接的基礎上,增加左邊表有而右邊表沒有的記錄,和右邊表有而左表表沒有的記錄
select * from dept full join emp on dept.id=emp.dept_id;

-- mysql 不支持全外連接,我們可以使用 union 關鍵字模擬全外連接
select * from dept left join emp on dept.id = emp.dept_id
union
select * from dept right join emp on dept.id = emp.dept_id;

多表查詢實例

創建表a

create table a(id int primary key,job varchar(20));
insert into a values(1,'AA'), (2,'BB'), (3,'CC');
select * from a;

創建表b

create table b(id int ,name varchar(20) ,foreign key(id) references a(id));
insert into b values(1,'bqt'), (2,'bqt2'), (2,'bqt3');
select * from b;

PS:
被參照的a(id)必須定義為unique才可以被參照,否則報錯(邏輯錯誤)。
插入數據的id必須在被參照的表中已經存在,否則報錯(邏輯錯誤)。

笛卡爾積查詢

select * from a,b;

內連接查詢

select * from a,b where a.id = b.id;
select * from a inner join b on a.id=b.id;

左外連接查詢

select * from a left join b on a.id=b.id;

右外連接查詢

select * from a right join b on a.id=b.id;

PS:由於右邊表參照左邊表,所以不存在右邊表有而左邊表沒有的記錄。

全外連接查詢

select * from a left  join b on a.id = b.id
union
select * from a right join b on a.id = b.id;

2020-04-07


免責聲明!

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



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