MySQL是一個(gè)關(guān)系型數(shù)據(jù)庫管理系統(tǒng),由瑞典MySQL AB公司開發(fā),屬于Oracle旗下產(chǎn)品,是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)之一。
十年的昌邑網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整昌邑建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“昌邑網(wǎng)站設(shè)計(jì)”,“昌邑網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
端口是3306。
表很多時(shí),使用linux腳本,需要根據(jù)需要修改一下:
和創(chuàng)建一樣,可以加上 if exists
可兩篇文章:
如:
用于在已有的表中添加、刪除或修改列。
添加 ADD
或
默認(rèn)是添加到最后,但可以指定位置。 FIRST :添加最前
AFTER 字段名 :添加指定字段之后
例子:
刪除 DROP
修改 MODIFY 主要修改原列的類型或約束條件 同樣可以用 FIRST 和 AFTER 字段名 ,代表的是修改到哪里。
修改字段名 CHANGE
可以把表2的數(shù)據(jù)復(fù)制到表1中,但 不能復(fù)制約束性條件 。
單行
多行,注意 只有一個(gè)VALUES :
不寫 (行1, 行2...) 這一部分的話,默認(rèn)一一對(duì)應(yīng)
除了以上方法外,還可以用SET為每一行附上相應(yīng)的值。
假如沒有篩選的話,就給全部都修改了。可以用 WHERE 篩選。
假如 沒有篩選的話,就給全部刪除了 。相當(dāng)于清空。
清空
先把表刪除,然后再建一個(gè)。與 DELETE FROM 相比, TRUNCATE 的效率更快,因?yàn)? DELETE FROM 是把記錄逐條刪除的。
查詢執(zhí)行的順序
FROM -- WHERE -- SELECT -- GROUP BY -- HAVING -- ORDER BY -- LIMIT
注意
當(dāng)數(shù)據(jù)很大,上百萬的時(shí)候,使用LIMIT ... OFFSET ..的方式進(jìn)行分頁十分浪費(fèi)資源且耗時(shí)長。最好是結(jié)合WHERE使用,如:
REGEXP 使用正則表達(dá)進(jìn)行匹配。 查詢時(shí),需要搭配WHERE或HAVING使用 。
兩個(gè)表之間有交集且要用到兩個(gè)表的數(shù)據(jù)時(shí),可以使用內(nèi)連接查詢。
LEFT JOIN 關(guān)鍵字從左表(table1)返回所有的行,即使右表(table2)中沒有匹配。如果右表中沒有匹配,則結(jié)果為 NULL。
用法:
RIGHT JOIN 關(guān)鍵字從右表(table2)返回所有的行,即使左表(table1)中沒有匹配。如果左表中沒有匹配,則結(jié)果為 NULL。 把LEFT JOIN的表1、表2調(diào)換順序,就是REGHT JOIN 。
FULL OUTER JOIN 關(guān)鍵字只要左表(table1)和右表(table2)其中一個(gè)表中存在匹配,則返回行. 相當(dāng)于結(jié)合了 LEFT JOIN 和 RIGHT JOIN 的結(jié)果。
但 MySQL中不支持 FULL OUTER JOIN 。
即SELECT嵌套。
IN 一個(gè)查詢結(jié)果作為另一個(gè)查詢的條件。 如:
EXISTS 用于判斷查詢子句是否有記錄,如果有一條或多條記錄存在返回 True,否則返回 False。True時(shí)執(zhí)行。 如:
索引的本質(zhì)是一種排好序的數(shù)據(jù)結(jié)構(gòu)。利用索引可以提高查詢速度。
常見的索引有:
MySQL通過外鍵約束來保證表與表之間的數(shù)據(jù)的完整性和準(zhǔn)確性。 外鍵的使用條件:
外鍵的好處:可以使得兩張表關(guān)聯(lián),保證數(shù)據(jù)的一致性和實(shí)現(xiàn)一些級(jí)聯(lián)操作。
對(duì)已有的兩個(gè)表增加外鍵 比如:主表為A,子表為B,外鍵為aid,外鍵約束名字為a_fk_b
為子表添加一個(gè)字段,當(dāng)做外鍵
為子表添加外鍵約束條件
假如刪除記錄報(bào)錯(cuò): [Err] 1451 -Cannot deleteorupdatea parent row: aforeignkeyconstraintfails (...)
這是因?yàn)镸ySQL中設(shè)置了foreign key關(guān)聯(lián),造成無法更新或刪除數(shù)據(jù)。可以通過設(shè)置 FOREIGN_KEY_CHECKS 變量來避免這種情況。 第一步:禁用外鍵約束,我們可以使用: SETFOREIGN_KEY_CHECKS=0; 第二步:刪除數(shù)據(jù) 第三步:?jiǎn)?dòng)外鍵約束,我們可以使用: SETFOREIGN_KEY_CHECKS=1; 查看當(dāng)前FOREIGN_KEY_CHECKS的值,可用如下命令: SELECT @@FOREIGN_KEY_CHECKS;
使用 UNION 來組合兩個(gè)查詢,如果第一個(gè)查詢返回 M 行,第二個(gè)查詢返回 N 行,那么組合查詢的結(jié)果一般為 M+N 行。
每個(gè)查詢必須包含相同的列、表達(dá)式和聚集函數(shù)。
默認(rèn)會(huì)去除相同行,如果需要 保留 相同行,使用 UNION ALL 。
只能包含一個(gè) ORDER BY 子句,并且必須位于語句的最后 。
內(nèi)置函數(shù)很多, 見: MySQL 函數(shù)
我們一般使用 START TRANSACTION 或 BEGIN 開啟事務(wù), COMMIT 提交事務(wù)中的命令, SAVEPOINT : 相當(dāng)于設(shè)置一個(gè)還原點(diǎn), ROLLBACK TO : 回滾到某個(gè)還原點(diǎn)下
一般的使用格式如下:
開啟事務(wù)時(shí), 默認(rèn)加鎖
根據(jù)類型可分為共享鎖(SHARED LOCK)和排他鎖(EXCLUSIVE LOCK)或者叫讀鎖(READ LOCK)和寫鎖(WRITE LOCK)。
根據(jù)粒度劃分又分表鎖和行鎖。表鎖由數(shù)據(jù)庫服務(wù)器實(shí)現(xiàn),行鎖由存儲(chǔ)引擎實(shí)現(xiàn)。
除此之外,我們可以顯示加鎖
加鎖時(shí), 如果沒有索引,會(huì)鎖表,如果加了索引,就會(huì)鎖行
InnoDB默認(rèn)支持行鎖,獲取鎖是分步的,并不是一次性獲取所有的鎖,因此在鎖競(jìng)爭(zhēng)的時(shí)候就會(huì)出現(xiàn)死鎖的情況
解決方法:
即ACID特性:
由于并發(fā)事務(wù)會(huì)引發(fā)上面這些問題, 我們可以設(shè)置事務(wù)的隔離級(jí)別解決上面的問題.
MySQL的默認(rèn)隔離級(jí)別(可重復(fù)讀)
查看當(dāng)前會(huì)話隔離級(jí)別
方式1
方式2
設(shè)置隔離級(jí)別
主從集群的示意圖如下:
主要涉及三個(gè)線程: binlog 線程、 I/O 線程和 SQL 線程。
同步流程:
由于MySQL主從集群只會(huì)從主節(jié)點(diǎn)同步到從節(jié)點(diǎn), 不會(huì)反過來同步, 所以需要讀寫分離
讀寫分離需要在業(yè)務(wù)層面實(shí)現(xiàn) , 寫數(shù)據(jù)只能在主節(jié)點(diǎn)上完成, 而讀數(shù)據(jù)可以在主節(jié)點(diǎn)或從節(jié)點(diǎn)上完成
索引是幫助MySQL高效獲取數(shù)據(jù)的排好序的數(shù)據(jù)結(jié)構(gòu)
MySQL的索引有
推薦兩個(gè)在線工具:
簡(jiǎn)單來說, B樹是在紅黑樹(一個(gè)平衡二叉樹)的基礎(chǔ)上將一個(gè)節(jié)點(diǎn)存放多個(gè)值, 實(shí)現(xiàn)的, 降低了樹的高度, 每個(gè)節(jié)點(diǎn)都存放索引及對(duì)應(yīng)數(shù)據(jù)指針, 同一層的節(jié)點(diǎn)是遞增的
而B+樹在B樹的基礎(chǔ)上進(jìn)行優(yōu)化, 非葉子節(jié)點(diǎn)存放 子節(jié)點(diǎn)的開始的索引, 葉子節(jié)點(diǎn)存放索引和數(shù)據(jù)的指針, 且葉子節(jié)點(diǎn)之間有雙向的指針
如下示意圖:
不同的引擎, 主鍵索引存放的數(shù)據(jù)也不一樣, 比如常見的 MyISAM 和 InnoDB
MyISAM 的B+樹葉子節(jié)點(diǎn)存放表數(shù)據(jù)的指針, InnoDB 的B+樹葉子節(jié)點(diǎn)存放處主鍵外的數(shù)據(jù)
其他的:
即多個(gè)列組成一個(gè)索引, 語法:
由于聯(lián)合索引的B+樹的結(jié)構(gòu), 根據(jù)列建立, 所以我們的查找條件也要根據(jù)索引列的順序( where column1=x, column2=y,columnN... ), 否則會(huì)全表掃描
如果你對(duì)列進(jìn)行了 (+,-,*,/,!) , 那么都將不會(huì)走索引。
OR 引起的索引失效
OR 導(dǎo)致索引是在特定情況下的,并不是所有的 OR 都是使索引失效,如果OR連接的是 同 一個(gè)字段,那么索引 不會(huì)失效 , 反之索引失效 。
這個(gè)我相信大家都明白,模糊搜索如果你前綴也進(jìn)行模糊搜索,那么不會(huì)走索引。
這兩種用法,也將使索引失效。另 IN 會(huì)走索引,但是當(dāng)IN的取值范圍較大時(shí)會(huì)導(dǎo)致索引失效,走全表掃描, 見: MySQL中使用IN會(huì)不會(huì)走索引
不走索引。
走索引。
所以設(shè)計(jì)表的時(shí)候, 建議不可為空, 而是將默認(rèn)值設(shè)置為 "" ( NOT NULL DEFAULT "" )
什么是事務(wù)? \x0d\x0a\x0d\x0a事務(wù)是邏輯上的一組操作,組成這組操作的各個(gè)單元,要不全都成功要不全都失敗,這個(gè)特性就是事務(wù) \x0d\x0a\x0d\x0a注意:mysql數(shù)據(jù)支持事務(wù),但是要求必須是innoDB存儲(chǔ)引擎 \x0d\x0a\x0d\x0a解決這個(gè)問題: \x0d\x0a\x0d\x0amysql的事務(wù)解決這個(gè)問題,因?yàn)閙ysql的事務(wù)特性,要求這組操作,要不全都成功,要不全都失敗,這樣就避免了某個(gè)操作成功某個(gè)操作失敗。利于數(shù)據(jù)的安全 \x0d\x0a\x0d\x0a如何使用: \x0d\x0a\x0d\x0a(1)在執(zhí)行sql語句之前,我們要開啟事務(wù) start transaction; \x0d\x0a\x0d\x0a(2)正常執(zhí)行我們的sql語句 \x0d\x0a\x0d\x0a(3)當(dāng)sql語句執(zhí)行完畢,存在兩種情況: \x0d\x0a\x0d\x0a1,全都成功,我們要將sql語句對(duì)數(shù)據(jù)庫造成的影響提交到數(shù)據(jù)庫中,committ \x0d\x0a\x0d\x0a2,某些sql語句失敗,我們執(zhí)行rollback(回滾),將對(duì)數(shù)據(jù)庫操作趕緊撤銷 \x0d\x0a\x0d\x0a(注意:mysql數(shù)據(jù)支持事務(wù),但是要求必須是innoDB存儲(chǔ)引擎) \x0d\x0amysql create table bank(name varchar(20),money decimal(5,1))engine=innodb defau \x0d\x0alt charset=utf8; \x0d\x0a\x0d\x0amysql inset into bank values('shaotuo',1000),('laohu',5000); \x0d\x0a\x0d\x0amysql select*from bank; \x0d\x0a+---------+--------+ \x0d\x0a| name | money | \x0d\x0a+---------+--------+ \x0d\x0a| shaotuo | 1000.0 | \x0d\x0a| laohu | 5000.0 | \x0d\x0a+---------+--------+ \x0d\x0a\x0d\x0a------沒有成功“回滾”執(zhí)行rollback \x0d\x0amysql start transaction; //開啟事務(wù) \x0d\x0aQuery OK, 0 rows affected (0.00 sec) \x0d\x0a\x0d\x0amysql update bank set money=money+500 where name='shaotuo'; \x0d\x0aQuery OK, 1 row affected (0.00 sec) \x0d\x0aRows matched: 1 Changed: 1 Warnings: 0 \x0d\x0a\x0d\x0amysql update bank set moey=money-500 where name='laohu'; \x0d\x0aERROR 1054 (42S22): Unknown column 'moey' in 'field list' \x0d\x0amysql rollback; //只要有一個(gè)不成功,執(zhí)行rollback操作 \x0d\x0aQuery OK, 0 rows affected (0.01 sec) \x0d\x0a\x0d\x0amysql select*from bank; \x0d\x0a+---------+--------+ \x0d\x0a| name | money | \x0d\x0a+---------+--------+ \x0d\x0a| shaotuo | 1000.0 | \x0d\x0a| laohu | 5000.0 | \x0d\x0a+---------+--------+ \x0d\x0a------成功之后 進(jìn)行commit操作 \x0d\x0amysql start transaction; //開啟事務(wù) \x0d\x0aQuery OK, 0 rows affected (0.00 sec) \x0d\x0a\x0d\x0amysql update bank set money=money+500 where name='shaotuo'; \x0d\x0aQuery OK, 1 row affected (0.01 sec) \x0d\x0aRows matched: 1 Changed: 1 Warnings: 0 \x0d\x0a\x0d\x0amysql update bank set money=money-500 where name='laohu'; \x0d\x0aQuery OK, 1 row affected (0.00 sec) \x0d\x0aRows matched: 1 Changed: 1 Warnings: 0 \x0d\x0a\x0d\x0amysql commit; //兩個(gè)都成功后執(zhí)行commit(只要不執(zhí)行commit,sql語句不會(huì)對(duì)真實(shí)的數(shù)據(jù)庫造成影響) \x0d\x0aQuery OK, 0 rows affected (0.05 sec) \x0d\x0a\x0d\x0amysql select*from bank; \x0d\x0a+---------+--------+ \x0d\x0a| name | money | \x0d\x0a+---------+--------+ \x0d\x0a| shaotuo | 1500.0 | \x0d\x0a| laohu | 4500.0 | \x0d\x0a+---------+--------+
看你是什么事務(wù),jdbc事務(wù),還是分布式事務(wù),還是容器事務(wù)
1,編程式事務(wù)管理(jdbc的事務(wù)是綁定在connection上的)
Connection conn = null;
try
{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@host:1521:SID","username","password");
conn.setAutoCommit(false); //取消自動(dòng)提交
PreparedStatement ps = conn.prepareCall("update something");
ResultSet rs = ps.executeQuery();
conn.commit(); //手動(dòng)提交
}
catch (Exception e)
{
conn.rollback();
e.printStackTrace();
}
finally
{
conn.close();
}
2,聲明式事務(wù)
先在工程的application.xml配置文件中添加如下代碼,開啟事務(wù)
!-- 聲明式事務(wù)控制配置 --
tx:annotation-driven transaction-manager="txManager"/
bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
property name="datasource" ref="bassDataSource"/property
/bean
然后在你需要開啟事務(wù)的接口前面添加注解
@Transactional(rollbackFor = IOException.class)
public void add(String name) throws IOException
{
System.out.println("可以再類里和方法里面添加事務(wù)注解0~0");
throw new IOException();
}
直接調(diào)用接口方法就好
分布式事務(wù)處理(mysql貌似在5.X之后才支持) 的話,
1.可以直接使用spring+atomikos框架進(jìn)行管理
參考:
就不貼測(cè)試代碼了,自己看著配置吧
2,使用JTA(Java Transaction API)進(jìn)行分布式事務(wù)管理(測(cè)試代碼如下)
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
//分布式事務(wù)處理
public class transferAccount
{
@SuppressWarnings("null")
public void testTransferAccount()
{
UserTransaction userts = null;
Connection connA = null;
PreparedStatement psA = null;
InitialContext context = null;
Connection connB = null;
PreparedStatement psB = null;
try
{
//獲得事務(wù)管理對(duì)象
userts = (UserTransaction) context.lookup("java:comp/UserTransaction");
//獲取兩個(gè)數(shù)據(jù)庫
connA = getDataSourceA().getConnection();
connB = getDataSourceB().getConnection();
//開啟事務(wù)
userts.begin();
//sql語句
psA = connA.prepareStatement("我加1");
psB = connB.prepareStatement("我減1");
//執(zhí)行sql
psA.executeUpdate();
psB.executeUpdate();
//事務(wù)提交
userts.commit();
} catch (Exception e)
{
try
{
userts.rollback();
} catch (IllegalStateException | SecurityException
| SystemException e1)
{
e1.printStackTrace();
}
e.printStackTrace();
}
finally
{
try
{
psA.close();
psB.close();
connA.close();
connB.close();
} catch (SQLException e)
{
e.printStackTrace();
}
}
}
public DataSource getDataSourceA()
{
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("mysql");
dataSource.setServerName("server");
dataSource.setPortNumber(1433);
dataSource.setUser("test");
dataSource.setPassword("test");
return dataSource;
}
public DataSource getDataSourceB()
{
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("mysql");
dataSource.setServerName("server");
dataSource.setPortNumber(1435);
dataSource.setUser("test1");
dataSource.setPassword("test1");
return dataSource;
}
}
先用CD命令進(jìn)到mysql的BIN目錄然后 mysql -uroot -p再輸入ROOT的密碼就行了就可以了
分享標(biāo)題:mysql怎么在開啟事務(wù) mysql開啟事務(wù)后,會(huì)不會(huì)鎖表
轉(zhuǎn)載來源:http://www.chinadenli.net/article24/dddogce.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、標(biāo)簽優(yōu)化、網(wǎng)站收錄、App設(shè)計(jì)、關(guān)鍵詞優(yōu)化、服務(wù)器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)