mysql學習筆記+MacOs
Mac安裝
安裝HomeBrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
HomeBrew安裝MySql
#搜索版本
brew search mysql
#安裝MySQL
brew install [email protected]
#設置開機啓動
ln -sfv /usr/local/opt/[email protected]/*.plist ~/Library/LaunchAgents
#初始化操作,設置數據庫密碼,是否允許遠程登錄等等
mysql_secure_installation
#啓動數據庫
mysql.server start
#登錄
mysql -uroot -p
#關閉數據庫
mysql.server start
#可以查看提示來完成安裝運行
brew info [email protected]
error
#添加環境變量
echo 'export PATH="/usr/local/opt/[email protected]/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
#可以重啓一下數據庫
ERROR 1045 (28000): Access denied for user 'root'@'localhost'
MySQL使用
創建數據庫
create database niyadb;
show databases;
use niyadb;
drop database niyadb;
創建表
create table instructor;
show tables;
#查看錶的結構
mysql> desc instructor;
+-----------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------+------+-----+---------+-------+
| ID | char(5) | NO | | NULL | |
| name | char(254) | NO | | NULL | |
| dept_name | char(254) | NO | | NULL | |
| salary | int(11) | NO | | NULL | |
+-----------+-----------+------+-----+---------+-------+
4 rows in set (0.01 sec)
#查看創建表的sql語句
show create table instructors;
#刪除表
drop table instructor;
#新增一列
alter table instructor
add column birth
varchar(256)
not null;
#修改列
alter table instructor
change column birth new_name
varchar(256)
not null;
#刪除列
alter table instructor
drop column birth;
插入行
insert into instructor values('10101','Srin','Comp','650');
查詢
基本查詢
#查詢所有數據
mysql> select * from instructor;
+-------+--------+-----------+--------+
| ID | name | dept_name | salary |
+-------+--------+-----------+--------+
| 10101 | Srin | Comp | 650 |
| 12121 | Wu | Finance | 900 |
| 15151 | Mozart | Music | 400 |
+-------+--------+-----------+--------+
3 rows in set (0.00 sec)
#測試數據庫連接
select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
按條件查詢
mysql> select * from instructor where salary>700;
+-------+------+-----------+--------+
| ID | name | dept_name | salary |
+-------+------+-----------+--------+
| 12121 | Wu | Finance | 900 |
+-------+------+-----------+--------+
1 row in set (0.00 sec)
常用的條件表達式
=, >, >=, <, <= ,<>(不相等),LIKE(相似)
mysql> select * from instructor where name like '%i%';
+-------+------+-----------+--------+
| ID | name | dept_name | salary |
+-------+------+-----------+--------+
| 10101 | Srin | Comp | 650 |
+-------+------+-----------+--------+
1 row in set (0.00 sec)
投影查詢
#可以指定輸出的列,可以修改列的順序
mysql> select name,id from instructor;
+--------+-------+
| name | id |
+--------+-------+
| Srin | 10101 |
| Wu | 12121 |
| Mozart | 15151 |
+--------+-------+
3 rows in set (0.00 sec)
#給name列起一個別名
mysql> select id,name new_name from instructor;
+-------+----------+
| id | new_name |
+-------+----------+
| 10101 | Srin |
| 12121 | Wu |
| 15151 | Mozart |
+-------+----------+
3 rows in set (0.00 sec)
排序
mysql> select * from instructor order by salary;
+-------+--------+-----------+--------+
| ID | name | dept_name | salary |
+-------+--------+-----------+--------+
| 15151 | Mozart | Music | 400 |
| 10101 | Srin | Comp | 650 |
| 12121 | Wu | Finance | 900 |
+-------+--------+-----------+--------+
3 rows in set (0.00 sec)
#倒序輸出
mysql> select * from instructor order by salary DESC;
+-------+--------+-----------+--------+
| ID | name | dept_name | salary |
+-------+--------+-----------+--------+
| 12121 | Wu | Finance | 900 |
| 10101 | Srin | Comp | 650 |
| 15151 | Mozart | Music | 400 |
+-------+--------+-----------+--------+
3 rows in set (0.00 sec)
#按多列排序,先按salary倒序排序,相同的行按dept_name排序
mysql> select * from instructor order by salary DESC,dept_name;
#帶where子句,order by要放在後面
mysql> select * from instructor where salary>600 order by salary DESC;
+-------+------+-----------+--------+
| ID | name | dept_name | salary |
+-------+------+-----------+--------+
| 12121 | Wu | Finance | 900 |
| 10101 | Srin | Comp | 650 |
| 17171 | Fang | History | 650 |
+-------+------+-----------+--------+
3 rows in set (0.00 sec)
分頁查詢
#每頁3條記錄,從索引0開始取
mysql> select * from instructor
-> order by salary
-> limit 3 offset 0;
+-------+--------+-----------+--------+
| ID | name | dept_name | salary |
+-------+--------+-----------+--------+
| 15151 | Mozart | Music | 400 |
| 10101 | Srin | Comp | 650 |
| 17171 | Fang | History | 650 |
+-------+--------+-----------+--------+
3 rows in set (0.00 sec)
#第2頁,從索引3開始取
mysql> select * from instructor order by salary limit 3 offset 3;
+-------+------+-----------+--------+
| ID | name | dept_name | salary |
+-------+------+-----------+--------+
| 12121 | Wu | Finance | 900 |
+-------+------+-----------+--------+
1 row in set (0.00 sec)
#上面的語句可以簡寫成
mysql> select * from instructor order by salary limit 3, 3;
聚合查詢
#將查詢結果展示的列名設置別名count
mysql> select count(*) count from instructor;
+-------+
| count |
+-------+
| 4 |
+-------+
1 row in set (0.00 sec)
#可以使用where條件統計
聚合函數
SUM(only 數值), AVG(only 數值, MAX, MIN
mysql> select avg(salary) avg from instructor;
+----------+
| avg |
+----------+
| 650.0000 |
+----------+
1 row in set (0.00 sec)
#也可以用條件子句where
分組聚合
#按salary分組並計數
mysql> select salary, count(*) count from instructor group by salary;
+--------+-------+
| salary | count |
+--------+-------+
| 400 | 1 |
| 650 | 2 |
| 900 | 1 |
+--------+-------+
3 rows in set (0.00 sec)
多表查詢
#給每個表設置一個簡單的別名,行兩兩拼在一起,列數相乘
mysql> select s.id,s.name,c.dept_name from instructor s,course c;
+-------+--------+-----------+
| id | name | dept_name |
+-------+--------+-----------+
| 10101 | Srin | Finance |
| 12121 | Wu | Finance |
| 15151 | Mozart | Finance |
| 17171 | Fang | Finance |
| 10101 | Srin | Finance |
| 12121 | Wu | Finance |
| 15151 | Mozart | Finance |
| 17171 | Fang | Finance |
| 10101 | Srin | Finance |
| 12121 | Wu | Finance |
| 15151 | Mozart | Finance |
| 17171 | Fang | Finance |
| 10101 | Srin | Comp |
| 12121 | Wu | Comp |
| 15151 | Mozart | Comp |
| 17171 | Fang | Comp |
| 10101 | Srin | Music |
| 12121 | Wu | Music |
| 15151 | Mozart | Music |
| 17171 | Fang | Music |
+-------+--------+-----------+
20 rows in set (0.00 sec)
#後面同樣可以跟where子句
連接查詢
mysql> select * from instructor s
mysql> inner join course c
mysql> on s.dept_name=c.dept_name;
+-------+--------+-----------+--------+-----------+------------------+-----------+---------+
| ID | name | dept_name | salary | course_id | title | dept_name | credits |
+-------+--------+-----------+--------+-----------+------------------+-----------+---------+
| 12121 | Wu | Finance | 900 | BOI-101 | Intro to Finance | Finance | 4 |
| 12121 | Wu | Finance | 900 | BOI-301 | Genetics | Finance | 4 |
| 12121 | Wu | Finance | 900 | BOI-399 | Computional | Finance | 3 |
| 10101 | Srin | Comp | 650 | CS-101 | Game Design | Comp | 3 |
| 15151 | Mozart | Music | 400 | MU-199 | World Music | Music | 3 |
+-------+--------+-----------+--------+-----------+------------------+-----------+---------+
inner join | 內連接,交集 |
---|---|
left outer join | 左連接,左表爲基準,右表中不存在行填充NULL |
right outer join | 右連接,右表爲基準,左表中不存在行填充NULL |
full outer join | 全連接,並集 |
寫法:
1、確定主表from 表1;
2、需要連接的表 join 表2;
3、連接條件 on<條件……>;
4、可選添加子句。
修改數據
insert
#colume省略默認爲全部字段
#可以一次插入多條值,中間以逗號分隔
insert into tablename (colume1,colume2)
values(value1,value2);
update
update tablename
set colume1=value1,colume2=value2
where colume=value;
delete
#刪除整行
delete from instructor;
#按條件刪除
delete from instructor where id=1;
退出
exit;
實用sql語句
#插入或者替換:查詢是否存在,存在-刪除+插入,不存在-插入
#使用replace可以查詢時刪除,而不是先查詢完再刪除
relpace into tablename values();
#插入或更新
insert into tablename
values()
on duplicate key update column1=value1,column2=value2;
#插入或忽略
insert ignore into tablename (column1,...) values(value1,...);
#快照
#複製一份當前表的數據到一個新表,想當於舊錶的查詢結果保存到了一個新的表裏
create table new_table select * from tablename where id=1;
#寫入查詢結果集
mysql> select * from new_instructor;
+-------+-----------+
| ID | dept_name |
+-------+-----------+
| 10101 | Comp |
| 12121 | Finance |
| 17171 | History |
+-------+-----------+
3 rows in set (0.00 sec)
mysql> insert into new_instructor (id,dept_name) select ID,dept_name from instructor;
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from new_instructor;
+-------+-----------+
| ID | dept_name |
+-------+-----------+
| 10101 | Comp |
| 12121 | Finance |
| 17171 | History |
| 10101 | Comp |
| 12121 | Finance |
| 15151 | Music |
| 17171 | History |
+-------+-----------+
7 rows in set (0.00 sec)
事務 — 四種隔離級別
Read Uncommitted
問題:髒讀
一個事務可以獨當另一個事務更新但是未提交的數據,如果另一個事務回滾,那麼當前事務讀到的就是髒數據
讀不阻塞讀寫,寫阻塞寫不阻塞讀
行級鎖
Read Committed
問題:不可重複讀
一個事務多次讀取同一數據,如果中間有另一個事務修改了數據,那兩次讀的數據可能不一致
讀不阻塞讀寫,寫阻塞讀寫
行級鎖
Repeatable Read
問題:幻讀
讀記錄,記錄爲空,更新記錄時可以成功,再次讀有結果
讀阻塞寫不阻塞讀,寫阻塞讀寫
行級鎖
Serializable
最嚴格的的隔離級別
事務是串行執行(上面出現的三個問題都是因爲並行執行產生的),但是性能會急劇下降
默認隔離級別,MySQL中使用InnoDB默認隔離級別爲Repeatable Read
表級鎖
相關鎖
悲觀鎖
總是假設最壞的情況,每次去拿數據的時候都認爲別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖(共享資源每次只給一個線程使用,其它線程阻塞,用完後再把資源轉讓給其它線程)。傳統的關係型數據庫裏邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖
總是假設最好的情況,每次去拿數據的時候都認爲別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號機制和CAS算法實現。
樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫提供的類似於write_condition機制,其實都是提供的樂觀鎖。
行級鎖
共享鎖
讀鎖,只讀不寫,之上可加讀鎖
行級鎖
排它鎖
寫鎖,可讀可寫,不可加讀寫鎖
樂觀鎖之版本號與CAS算法
版本號機制
增加version字段,當前提交的version與數據庫當前version進行比較,大於即可提交,否則被駁回
CAS算法
compare and swap,無鎖算法,即不使用鎖的情況下實現多線程之間的變量同步,也叫非阻塞同步
需要讀寫的內存值V與A進行比較,加自旋鎖來更新V的值