重新學習MySQL數據庫1:無廢話MySQL入門
重新學習Mysql數據庫1:無廢話MySQL入門
開始使用
我下面所有的SQL語句是基於MySQL 5.6+運行。
MySQL 為關系型數據庫(Relational Database Management System),一個關系型數據庫由一個或數個表格組成, 如圖所示的一個表格:
-
表頭(header)
: 每一列的名稱; -
列(col)
: 具有相同數據類型的數據的集合; -
行(row)
: 每一行用來描述某個人/物的具體信息; -
值(value)
: 行的具體信息, 每個值必須與該列的數據類型相同; -
鍵(key)
: 表中用來識別某個特定的人物的方法, 鍵的值在當前列中具有唯一性。
登錄MySQL
mysql -h 127.0.0.1 -u 用戶名 -p
?
?
?
mysql -D 所選擇的數據庫名 -h 主機名 -u 用戶名 -p
?
?
?
mysql> exit # 退出 使用 “quit;” 或 “\q;” 一樣的效果
?
?
?
mysql> status; # 顯示當前mysql的version的各種信息
?
?
?
mysql> select version(); # 顯示當前mysql的version信息
?
?
?
mysql> show global variables like ‘port‘; # 查看MySQL端口號
創建數據庫
對於表的操作需要先進入庫use 庫名;
-- 創建一個名為 samp_db 的數據庫,數據庫字符編碼指定為 gbk
?
?
?
create database [if no exists]samp_db character set gbk;
?
?
?
drop database samp_db; -- 刪除 庫名為samp_db的庫
?
?
?
show databases; -- 顯示數據庫列表。
?
?
?
use samp_db; -- 選擇創建的數據庫samp_db
?
?
?
show tables; -- 顯示samp_db下面所有的表名字
?
?
?
describe 表名; -- 顯示數據表的結構
?
?
?
delete from 表名; -- 清空表中記錄
創建數據庫表
使用 create table 語句可完成對表的創建, create table 的常見形式: 語法:create table 表名稱(列聲明);
CREATE TABLE `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
:對表或者字段說明;
增刪改查
SELECT
SELECT 語句用於從表中選取數據。 語法:
SELECT 列名稱 FROM 表名稱
語法:SELECT * FROM 表名稱
子查詢
(鑲嵌在其它語句內部的Select語句)
標量子查詢(單行子查詢)
列子查詢(多行子查詢)
?
行子查詢(多行多列)
?
表子查詢(多行多列)
?
用途:
?
select 後面
?
from 後面
?
where 或者 having後面(主要)union 聯合查詢(將多次查詢的結果聯合在一起)
查詢語句 1 unoin [all]
?
查詢語句2 unoin [all]
?
......
?
註意:查詢語句的字段要一致,不加all會去重
-- 表station取個別名叫s,表station中不包含 字段id=13或者14 的,並且id不等於4的 查詢出來,只顯示id
?
?
?
SELECT s.id from station s WHERE id in (13,14) and user_id not in (4);
?
?
?
-- 從表 Persons 選取 LastName 列的數據
?
?
?
SELECT LastName FROM Persons
?
?
-- 結果集中會自動去重復數據
?
SELECT DISTINCT Company FROM Orders
?
-- 表 Persons 字段 Id_P 等於 Orders 字段 Id_P 的值,
?
?
-- 結果集顯示 Persons表的 LastName、FirstName字段,Orders表的OrderNo字段
?
?
SELECT p.LastName, p.FirstName, o.OrderNo FROM Persons p, Orders o WHERE p.Id_P = o.Id_P
?
?
?
?
-- gbk 和 utf8 中英文混合排序最簡單的辦法
?
?
?
-- 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;
UPDATE
Update 語句用於修改表中的數據。 語法:
UPDATE 表名稱 SET 列名稱 = 新值 ,列名稱=新值 WHERE 列名稱 = 某值
-- update語句設置字段值為另一個結果取出來的字段
?
?
?
update user set name = (select name from user1 where user1 .id = 1 )
?
?
?
where id = (select id from user2 where user2 .name=‘小蘇‘);
?
?
?
-- 更新表 orders 中 id=1 的那一行數據更新它的 title 字段
?
?
?
UPDATE `orders` set title=‘這裏是標題‘ WHERE id=1;
INSERT
INSERT INTO 語句用於向表格中插入新的行。 語法:
INSERT INTO 表名稱 VALUES (值1, 值2,....)
語法:INSERT INTO 表名稱 (列1, 列2,...) VALUES (值1, 值2,....)
-- 向表 Persons 插入一條字段 LastName = JSLite 字段 Address = shanghai
?
?
?
INSERT INTO Persons (LastName, Address) VALUES (‘JSLite‘, ‘shanghai‘);
?
?
?
-- 向表 meeting 插入 字段 a=1 和字段 b=2
?
?
?
INSERT INTO meeting SET a=1,b=2;
?
?
?
-- SQL實現將一個表的數據插入到另外一個表的代碼
?
?
?
-- 如果只希望導入指定字段,可以用這種方法:
?
?
?
-- INSERT INTO 目標表 (字段1, 字段2, ...) SELECT 字段1, 字段2, ... FROM 來源表;
?
?
?
INSERT INTO orders (user_account_id, title) SELECT m.user_id, m.title FROM meeting m where m.id=1;
DELETE
DELETE 語句用於刪除表中的行。 語法:
DELETE FROM 表名稱 WHERE 列名稱 = 值
-- 在不刪除table_name表的情況下刪除所有的行,清空表。 DELETE FROM table_name -- 或者 DELETE * FROM table_name -- 刪除 Person表字段 LastName = ‘JSLite‘ DELETE FROM Person WHERE LastName = ‘JSLite‘ -- 刪除 表meeting id 為2和3的兩條數據 DELETE from meeting where id in (2,3);
WHERE
WHERE 子句用於規定選擇的標準。 語法:
SELECT 列名稱 FROM 表名稱 WHERE 列 運算符 值
-- 從表 Persons 中選出 Year 字段大於 1965 的數據 SELECT * FROM Persons WHERE Year>1965
AND 和 OR
AND - 如果第一個條件和第二個條件都成立; OR - 如果第一個條件和第二個條件中只要有一個成立;
AND
-- 刪除 meeting 表字段 -- id=2 並且 user_id=5 的數據 和 -- id=3 並且 user_id=6 的數據 DELETE from meeting where id in (2,3) and user_id in (5,6); -- 使用 AND 來顯示所有姓為 "Carter" 並且名為 "Thomas" 的人: SELECT * FROM Persons WHERE FirstName=‘Thomas‘ AND LastName=‘Carter‘;
OR
-- 使用 OR 來顯示所有姓為 "Carter" 或者名為 "Thomas" 的人: SELECT * FROM Persons WHERE firstname=‘Thomas‘ OR lastname=‘Carter‘
ORDER BY
語句默認按照升序對記錄進行排序。
ORDER BY
- 語句用於根據指定的列對結果集進行排序。DESC
- 按照降序對記錄進行排序。ASC
- 按照順序對記錄進行排序。
-- Company在表Orders中為字母,則會以字母順序顯示公司名稱 SELECT Company, OrderNumber FROM Orders ORDER BY Company -- 後面跟上 DESC 則為降序顯示 SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC -- Company以降序顯示公司名稱,並OrderNumber以順序顯示 SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC, OrderNumber ASC
IN
IN - 操作符允許我們在 WHERE 子句中規定多個值。 IN - 操作符用來指定範圍,範圍中的每一條,都進行匹配。IN取值規律,由逗號分割,全部放置括號中。 語法:
SELECT "字段名"FROM "表格名"WHERE "字段名" IN (‘值一‘, ‘值二‘, ...);
-- 從表 Persons 選取 字段 LastName 等於 Adams、Carter SELECT * FROM Persons WHERE LastName IN (‘Adams‘,‘Carter‘)
NOT
NOT - 操作符總是與其他操作符一起使用,用在要過濾的前面。
SELECT vend_id, prod_name FROM Products WHERE NOT vend_id = ‘DLL01‘ ORDER BYprod_name;
UNION
UNION - 操作符用於合並兩個或多個 SELECT 語句的結果集。
-- 列出所有在中國表(Employees_China)和美國(Employees_USA)的不同的雇員名 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;
AS
as - 可理解為:用作、當成,作為;別名 一般是重命名列名或者表名。 語法:
select column_1 as 列1,column_2 as 列2 from table as 表
SELECT * FROM Employee AS emp -- 這句意思是查找所有Employee 表裏面的數據,並把Employee表格命名為 emp。 -- 當你命名一個表之後,你可以在下面用 emp 代替 Employee. -- 例如 SELECT * FROM emp. SELECT MAX(OrderPrice) AS LargestOrderPrice FROM Orders -- 列出表 Orders 字段 OrderPrice 列最大值, -- 結果集列不顯示 OrderPrice 顯示 LargestOrderPrice -- 顯示表 users_profile 中的 name 列 SELECT t.name from (SELECT * from users_profile a) AS t; -- 表 user_accounts 命名別名 ua,表 users_profile 命名別名 up -- 滿足條件 表 user_accounts 字段 id 等於 表 users_profile 字段 user_id -- 結果集只顯示mobile、name兩列 SELECT ua.mobile,up.name FROM user_accounts as ua INNER JOIN users_profile as up ON ua.id = up.user_id;
JOIN
用於根據兩個或多個表中的列之間的關系,從這些表中查詢數據。
-
JOIN
: 如果表中有至少一個匹配,則返回行 -
INNER JOIN
:在表中存在至少一個匹配時,INNER JOIN 關鍵字返回行。 -
LEFT JOIN
: 即使右表中沒有匹配,也從左表返回所有的行 -
RIGHT JOIN
: 即使左表中沒有匹配,也從右表返回所有的行 -
FULL JOIN
: 只要其中一個表中存在匹配,就返回行
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons INNER JOIN Orders ON Persons.Id_P = Orders.Id_P ORDER BY Persons.LastName;
SQL 函數
COUNT
COUNT 讓我們能夠數出在表格中有多少筆資料被選出來。 語法:
SELECT COUNT("字段名") FROM "表格名";
-- 表 Store_Information 有幾筆 store_name 欄不是空白的資料。 -- "IS NOT NULL" 是 "這個欄位不是空白" 的意思。 SELECT COUNT (Store_Name) FROM Store_Information WHERE Store_Name IS NOT NULL; -- 獲取 Persons 表的總數 SELECT COUNT(1) AS totals FROM Persons; -- 獲取表 station 字段 user_id 相同的總數 select user_id, count(*) as totals from station group by user_id; 1. count(1) and count(*) 當表的數據量大些時,對表作分析之後,使用count(1)還要比使用count(*)用時多了! 從執行計劃來看,count(1)和count(*)的效果是一樣的。 但是在表做過分析之後,count(1)會比count(*)的用時少些(1w以內數據量),不過差不了多少。 如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。 因為count(*),自動會優化指定到那一個字段。所以沒必要去count(1),用count(*),sql會幫你完成優化的 因此:count(1)和count(*)基本沒有差別! 2. count(1) and count(字段) 兩者的主要區別是 (1) count(1) 會統計表中的所有的記錄數,包含字段為null 的記錄。 (2) count(字段) 會統計該字段在表中出現的次數,忽略字段為null 的情況。即不統計字段為null 的記錄。 轉自:http://www.cnblogs.com/Dhouse/p/6734837.html count(*) 和 count(1)和count(列名)區別 執行效果上: count(*)包括了所有的列,相當於行數,在統計結果的時候,不會忽略列值為NULL count(1)包括了忽略所有列,用1代表代碼行,在統計結果的時候,不會忽略列值為NULL count(列名)只包括列名那一列,在統計結果的時候,會忽略列值為空(這裏的空不是只空字符串或者0,而是表示null)的計數,即某個字段值為NULL時,不統計。 執行效率上: 列名為主鍵,count(列名)會比count(1)快 列名不為主鍵,count(1)會比count(列名)快 如果表多個列並且沒有主鍵,則 count(1) 的執行效率優於 count(*) 如果有主鍵,則 select count(主鍵)的執行效率是最優的 如果表只有一個字段,則 select count(*)最優。
MAX
MAX 函數返回一列中的最大值。NULL 值不包括在計算中。 語法:
SELECT MAX("字段名") FROM "表格名"
-- 列出表 Orders 字段 OrderPrice 列最大值, -- 結果集列不顯示 OrderPrice 顯示 LargestOrderPrice SELECT MAX(OrderPrice) AS LargestOrderPrice FROM Orders
MIN
常見函數
字符型函數: concat()|substr()截取子串|upper()|lower()|repace()|length()|trim()去掉前後空格|lpad()左填充|rpad()右填充
數值型函數:round()四舍五入|floor()向下取整,(-5.9)為-6|ceil()向上取整|mod()取模|rand()隨機(0~1)之間的數
日期函數: now()|year(‘date‘)|moth()|day()|date-formate()將日期轉換成字符|datediff(‘date1‘,‘date2‘)返回2個日期相差的天數
觸發器
語法: create trigger <觸發器名稱> { before | after} # 之前或者之後出發 insert | update | delete # 指明了激活觸發程序的語句的類型 on <表名> # 操作哪張表 for each row # 觸發器的執行間隔,for each row 通知觸發器每隔一行執行一次動作,而不是對整個表執行一次。 <觸發器SQL語句>
DELIMITER $ -- 自定義結束符號 CREATE TRIGGER set_userdate BEFORE INSERT on `message` for EACH ROW BEGIN UPDATE `user_accounts` SET status=1 WHERE openid=NEW.openid; END $DELIMITER ; -- 恢復結束符號
OLD和NEW不區分大小寫
-
NEW 用NEW.col_name,沒有舊行。在DELETE觸發程序中,僅能使用OLD.col_name,沒有新行。
-
OLD 用OLD.col_name來引用更新前的某一行的列
變量
1.系統變量
(全局變量|會話變量)默認session 查看系統變量 show [global|session(默認)] variables like ‘‘ select @@[global|session].變量名 設置變量名 set [global|session].變量名 = 值 set 變量名 = 值
2.自定義變量
(用戶變量|局部變量) 用戶變量:可放在begin end 裏面或者外面 聲明並賦值: set @變量名=值
select @變量名:=值
查詢: select @變量名
將從表中的數據插入到用戶變量中去 select * from into @變量 from 表; 局部變量:只能放在begin end中,而且只能放在第一句
視圖
作用:不是保存數據,只是為了保存執行的sql代碼,起到解釋的作用;簡化了代碼,提高sql的重用性
創建視圖
1.create view 視圖名 as 查詢語句
創建或者修改
create or replace view 視圖名 as 查詢語句
修改視圖
alter view 視圖名 as 查詢語句
刪除視圖
drop view 視圖1,視圖2
查看視圖
desc 視圖名
存儲過程
創建存儲過程
delimiter 結束標記(需要先身明) create procedure 存儲過程名(in 參數名 參數類型| out 參數名 參數類型|inout 參數名 參數類型 ) begin
sql 語句1; select 字段 into out參數名 from 表名 where 字段=參數名; sql語句2;
end
調用: call 存儲過程名(實際參數)
調用帶out的參數時候 delimiter 結束標記=> call(in xxx,@name) =>select @name #4.創建帶inout模式參數的存儲過程 create procedure pc3(inout m int,inout n int) begin set m=m*2; set n=n*2; end
set @m=10; set @n=20; call pc3(@m,@n); select @m,@n;
刪除存儲過程
drop procedure 存儲過程名
查看存儲過程名
show create procedure 存儲過程名
函數
創建函數
delimiter 結束標記 create function 函數名(參數名 參數類型 ) returns 返回類型 begin //初始化參數 set @name=‘name‘ select 字段 into @name from 表 where id=參數 ; return @name end 結束標記
調用函數
select 函數名(實參值)結束標記 CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE BEGIN DECLARE sal DOUBLE ; SELECT AVG(salary) INTO sal FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE d.department_name=deptName; RETURN sal; END $ SELECT myf3(‘IT‘)$ --調用函數
刪除函數
drop function 函數名
查看函數
show create function 函數名
添加索引
普通索引(INDEX)
語法:ALTER TABLE
表名字
ADD INDEX 索引名字 (字段名字
)
-- –直接創建索引 CREATE INDEX index_user ON user(title) -- –修改表結構的方式添加索引 ALTER TABLE table_name ADD INDEX index_name (column(length)) -- 給 user 表中的 name字段 添加普通索引(INDEX) ALTER TABLE `table` ADD INDEX index_name (columnName(length)) -- –創建表的時候同時創建索引 CREATE TABLE `table` ( `id` int(11) NOT NULL AUTO_INCREMENT , `title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL , `time` int(10) NULL DEFAULT NULL , PRIMARY KEY (`id`), INDEX index_name (title(length)) ) -- –刪除索引 DROP INDEX index_name ON table
主鍵索引(PRIMARY key)
語法:ALTER TABLE
表名字
ADD PRIMARY KEY (字段名字
)
-- 給 user 表中的 id字段 添加主鍵索引(PRIMARY key) ALTER TABLE `user` ADD PRIMARY key (id);
唯一索引(UNIQUE)
語法:ALTER TABLE
表名字
ADD UNIQUE (字段名字
)
-- 給 user 表中的 creattime 字段添加唯一索引(UNIQUE) ALTER TABLE `user` ADD UNIQUE (creattime);
全文索引(FULLTEXT)
語法:ALTER TABLE
表名字
ADD FULLTEXT (字段名字
)
-- 給 user 表中的 description 字段添加全文索引(FULLTEXT) ALTER TABLE `user` ADD FULLTEXT (description);
添加多列索引(復合索引)
語法:
ALTER TABLE table_name
ADD INDEX index_name ( column1
, column2
, column3
)
-- 給 user 表中的 name、city、age 字段添加名字為name_city_age的普通索引(INDEX) ALTER TABLE user ADD INDEX name_city_age (name(10),city,age);
建立索引的時機
在WHERE
和JOIN
中出現的列需要建立索引,但也不完全如此:
-
MySQL只對
<
,<=
,=
,>
,>=
,BETWEEN
,IN
使用索引 -
某些時候的
LIKE
也會使用索引。 -
在
LIKE
以通配符%和_開頭作查詢時,MySQL不會使用索引。
-- 此時就需要對city和age建立索引, -- 由於mytable表的userame也出現在了JOIN子句中,也有對它建立索引的必要。 SELECT t.Name FROM mytable t LEFT JOIN mytable m ON t.Name=m.username WHERE m.age=20 AND m.city=‘上海‘; SELECT * FROM mytable WHERE username like‘admin%‘; -- 而下句就不會使用: SELECT * FROM mytable WHEREt Name like‘%admin‘; -- 因此,在使用LIKE時應註意以上的區別。
索引的註意事項
-
索引不會包含有NULL值的列
-
使用短索引
-
不要在列上進行運算 索引會失效
-
like的使用
創建後表的修改
添加列
語法:
alter table 表名 add 列名 列數據類型 [after 插入位置];
示例:
-- 在表students的最後追加列 address: alter table students add address char(60); -- 在名為 age 的列後插入列 birthday: alter table students add birthday date after age; -- 在名為 number_people 的列後插入列 weeks: alter table students add column `weeks` varchar(5) not null default "" after `number_people`;
修改列
語法:
alter table 表名 change 列名稱 列新名稱 新數據類型;
-- 將表 tel 列改名為 telphone: alter table students change tel telphone char(13) default "-"; -- 將 name 列的數據類型改為 char(16): alter table students change name name char(16) not null; -- 修改 COMMENT 前面必須得有類型屬性 alter table students change name name char(16) COMMENT ‘這裏是名字‘; -- 修改列屬性的時候 建議使用modify,不需要重建表 -- change用於修改列名字,這個需要重建表 alter table meeting modify `weeks` varchar(20) NOT NULL DEFAULT "" COMMENT "開放日期 周一到周日:0~6,間隔用英文逗號隔開";
刪除列
語法:
alter table 表名 drop 列名稱;
-- 刪除表students中的 birthday 列: alter table students drop birthday;
重命名表
語法:
alter table 表名 rename 新表名;
-- 重命名 students 表為 workmates:
?
?
?
alter table students rename workmates;
清空表數據
方法一:
delete from 表名;
方法二:truncate from "表名";
-
DELETE:
-
TRUNCATE:
1. DDL語言;2. 無法回退;3. 默認所有的表內容都刪除;4. 刪除速度比delete快。
-- 清空表為 workmates 裏面的數據,不刪除表。
?
?
delete from workmates;
?
?
-- 刪除workmates表中的所有數據,且無法恢復
?
?
truncate from workmates;
刪除整張表
語法:
drop table 表名;
-- 刪除 workmates 表:
?
drop table workmates;
刪除整個數據庫
語法:
drop database 數據庫名;
-- 刪除 samp_db 數據庫:
?
drop database samp_db;
重新學習MySQL數據庫1:無廢話MySQL入門