中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

ppt可以做網(wǎng)站嗎合肥網(wǎng)絡(luò)推廣優(yōu)化公司

ppt可以做網(wǎng)站嗎,合肥網(wǎng)絡(luò)推廣優(yōu)化公司,網(wǎng)站建設(shè)方案怎么寫,營銷型網(wǎng)站建設(shè)申請域名myibatis執(zhí)行過程 1讀取MyBatis的配置文件。 mybatis-config.xml為MyBatis的全局配置文件,用于配置數(shù)據(jù)庫連接信息。 2加載映射文件。映射文件即SQL映射文件,該文件中配置了操作數(shù)據(jù)庫的SQL語句,需要在MyBatis配置文件mybatis-config.xml中…

myibatis執(zhí)行過程

1讀取MyBatis的配置文件。

mybatis-config.xml為MyBatis的全局配置文件,用于配置數(shù)據(jù)庫連接信息。

2加載映射文件。映射文件即SQL映射文件,該文件中配置了操作數(shù)據(jù)庫的SQL語句,需要在MyBatis配置文件mybatis-config.xml中加載。mybatis-config.xml 文件可以加載多個映射文件,每個文件對應(yīng)數(shù)據(jù)庫中的一張表。

3構(gòu)造會話工廠。

通過MyBatis的環(huán)境配置信息構(gòu)建會話工廠SqlSessionFactory。

4 創(chuàng)建會話對象。

由會話工廠創(chuàng)建SqlSession對象,該對象中包含了執(zhí)行SQL語句的所有方法。

5 Executor執(zhí)行器。

MyBatis底層定義了一個Executor接口來操作數(shù)據(jù)庫,它將根據(jù)SqlSession傳遞的參數(shù)動態(tài)地生成需要執(zhí)行的SQL語句,同時負責查詢緩存的維護。

6MappedStatement對象。

在Executor接口的執(zhí)行方法中有一個MappedStatement類型的參數(shù),該參數(shù)是對映射信息的封裝,用于存儲要映射的SQL語句的id、參數(shù)等信息。

7 輸入?yún)?shù)映射。

輸入?yún)?shù)類型可以是Map、List等集合類型,也可以是基本數(shù)據(jù)類型和POJO類型。輸入?yún)?shù)映射過程類似于JDBC對preparedStatement對象設(shè)置參數(shù)的過程。

8 輸出結(jié)果映射。

輸出結(jié)果類型可以是Map、List等集合類型,也可以是基本數(shù)據(jù)類型和POJO類型。輸出結(jié)果映射過程類似于JDBC對結(jié)果集的解析過程。

mybatis的優(yōu)缺點有哪些?

1、Mybait的優(yōu)點:

(1)簡單易學,容易上手(相比于Hibernate) 基于SQL編程; (2)JDBC相比,減少了50%以上的代碼量,消除了JDBC大量冗余的代碼,不需要手動開關(guān)連接; (3)很好的與各種數(shù)據(jù)庫兼容(因為MyBatis使用JDBC來連接數(shù)據(jù)庫,所以只要JDBC支持的數(shù)據(jù)庫MyBatis都支持,而JDBC提供了可擴展性,所以只要這個數(shù)據(jù)庫有針對Java的jar包就可以就可以與MyBatis兼容),開發(fā)人員不需要考慮數(shù)據(jù)庫的差異性。 (4)提供了很多第三方插件(分頁插件 / 逆向工程); (5)能夠與Spring很好的集成; (6)MyBatis相當靈活,不會對應(yīng)用程序或者數(shù)據(jù)庫的現(xiàn)有設(shè)計強加任何影響,SQL寫在XML里,從程序代碼中徹底分離,解除sql與程序代碼的耦合,便于統(tǒng)一管理和優(yōu)化,并可重用。 (7)提供XML標簽,支持編寫動態(tài)SQL語句。 (8)提供映射標簽,支持對象與數(shù)據(jù)庫的ORM字段關(guān)系映射。 (9)提供對象關(guān)系映射標簽,支持對象關(guān)系組建維護。 2、MyBatis框架的缺點:

(1)SQL語句的編寫工作量較大,尤其是字段多、關(guān)聯(lián)表多時,更是如此,對開發(fā)人員編寫SQL語句的功底有一定要求。 (2)SQL語句依賴于數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫移植性差,不能隨意更換數(shù)據(jù)庫。

mybatis和hibernate有什么區(qū)別?

Hibernate的優(yōu)點:

1、hibernate是全自動,hibernate完全可以通過對象關(guān)系模型實現(xiàn)對數(shù)據(jù)庫的操作,擁有完整的JavaBean對象與數(shù)據(jù)庫的映射結(jié)構(gòu)來自動生成sql。

2、功能強大,數(shù)據(jù)庫無關(guān)性好,O/R映射能力強,需要寫的代碼很少,開發(fā)速度很快。

3、有更好的二級緩存機制,可以使用第三方緩存。

4、數(shù)據(jù)庫移植性良好。

5、hibernate擁有完整的日志系統(tǒng),hibernate日志系統(tǒng)非常健全,涉及廣泛,包括sql記錄、關(guān)系異常、優(yōu)化警告、緩存提示、臟數(shù)據(jù)警告等

Hibernate的缺點:

1、學習門檻高,精通門檻更高,程序員如何設(shè)計O/R映射,在性能和對象模型之間如何取得平衡,以及怎樣用好Hibernate方面需要的經(jīng)驗和能力都很強才行

2、hibernate的sql很多都是自動生成的,無法直接維護sql;雖然有hql查詢,但功能還是不及sql強大,見到報表等變態(tài)需求時,hql查詢要虛,也就是說hql查詢是有局限的;hibernate雖然也支持原生sql查詢,但開發(fā)模式上卻與orm不同,需要轉(zhuǎn)換思維,因此使用上有些不方便??傊畬憇ql的靈活度上hibernate不及mybatis。

Mybatis的優(yōu)點:

1、易于上手和掌握,提供了數(shù)據(jù)庫查詢的自動對象綁定功能,而且延續(xù)了很好的SQL使用經(jīng)驗,對于沒有那么高的對象模型要求的項目來說,相當完美。

2、sql寫在xml里,便于統(tǒng)一管理和優(yōu)化, 解除sql與程序代碼的耦合。

3、提供映射標簽,支持對象與數(shù)據(jù)庫的orm字段關(guān)系映射

4、 提供對象關(guān)系映射標簽,支持對象關(guān)系組建維護

5、提供xml標簽,支持編寫動態(tài)sql。

6、速度相對于Hibernate的速度較快

Mybatis的缺點:

1、關(guān)聯(lián)表多時,字段多的時候,sql工作量很大。

2、sql依賴于數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫移植性差。

3、由于xml里標簽id必須唯一,導(dǎo)致DAO中方法不支持方法重載。

4、對象關(guān)系映射標簽和字段映射標簽僅僅是對映射關(guān)系的描述,具體實現(xiàn)仍然依賴于sql。

5、DAO層過于簡單,對象組裝的工作量較大。

6、不支持級聯(lián)更新、級聯(lián)刪除。

7、Mybatis的日志除了基本記錄功能外,其它功能薄弱很多。

8、編寫動態(tài)sql時,不方便調(diào)試,尤其邏輯復(fù)雜時。

9、提供的寫動態(tài)sql的xml標簽功能簡單,編寫動態(tài)sql仍然受限,且可讀性低。

mybatis中#{}和${}的區(qū)別是什么?

a、#{}是預(yù)編譯處理,${}是字符串替換。 b、Mybatis 在處理#{}時,會將 sql 中的#{}替換為?號,調(diào)用 PreparedStatement 的 set 方法來賦值; c、Mybatis 在處理${}時,就是把${}替換成變量的值。 d、使用#{}可以有效的防止 SQL 注入,提高系統(tǒng)安全性

簡述一下mybatis插件運行原理及開發(fā)流程?(插件四大天王)

mybatis只支持針對ParameterHandler、ResultSetHandler、StatementHandler、Executor這四種接口的插件,mybatis使用jdk的動態(tài)代理,為需要攔截的接口生成代理對象以實現(xiàn)接口方法攔截功能,每當執(zhí)行這四種接口對象的方法時,就會進入攔截方法,具體就是InvocationHandler的invoke方法,攔截那些你指定需要攔截的方法。

編寫插件:實現(xiàn)Mybatis的Interceptor接口并復(fù)寫intercept方法啊,然后給插件編寫注解,指定要攔截哪一個接口的哪些方法,在配置文件中配置編寫的插件即可。

@Intercepts({@Signature(type = StatementHandler.class,method = "parameterize",args = Statement.class)})

插件開發(fā)流程:

  1. 創(chuàng)建自定義攔截器類,實現(xiàn)org.apache.ibatis.plugin.Interceptor接口,并重寫其中的intercept()plugin()方法。intercept()方法用于定義自定義邏輯,plugin()方法用于生成代理對象。

  2. 在攔截器類上使用@Intercepts注解,尋找需要攔截的方法。

  3. 在MyBatis的配置文件(通常是mybatis-config.xml)中,配置自定義攔截器。

  4. 創(chuàng)建插件類,繼承org.apache.ibatis.plugin.PluginAdapter類,并實現(xiàn)其中的setProperties()方法。

  5. 在插件類上使用@Signature注解,指定要攔截的方法簽名。

  6. 編寫一個類,實現(xiàn)org.apache.ibatis.session.Configuration接口,重寫其中的addInterceptor()方法,在方法中添加自定義插件。

  7. 在MyBatis的配置文件中,使用<configuration>標簽的<settings>子標簽,并指定使用自定義的配置類。

  8. 調(diào)用MyBatis的API進行數(shù)據(jù)庫操作時,插件將被自動執(zhí)行。

mybatis的mapper沒有實現(xiàn)類

在 MyBatis 中,Mapper 接口可以不需要對應(yīng)的實現(xiàn)類,因為 MyBatis 會自動為 Mapper 接口生成代理對象,并實現(xiàn)接口中定義的方法。這種方式稱為 Mapper 接口的動態(tài)代理。

當 Mapper 接口沒有對應(yīng)的實現(xiàn)類時,MyBatis 在運行時會動態(tài)生成一個代理對象,該代理對象會攔截接口方法的調(diào)用,并根據(jù)接口方法的定義將對應(yīng)的 SQL 語句進行執(zhí)行。這樣就實現(xiàn)了 Mapper 接口與 SQL 語句的綁定。

在 Mapper 接口中,通常會使用注解或 XML 文件來定義 SQL 語句。例如,使用注解方式定義 SQL 語句的 Mapper 接口示例:

```java
public interface UserMapper {
? ? @Select("SELECT * FROM users WHERE id = #{id}")
? ? User selectUserById(Long id);
}
```

而使用 XML 文件定義 SQL 語句的 Mapper 接口示例:

```java
public interface UserMapper {
? ? User selectUserById(Long id);
}
```

```xml
<!-- UserMapper.xml -->
<mapper namespace="com.example.UserMapper">
? ? <select id="selectUserById" resultType="com.example.User">
? ? ? ? SELECT * FROM users WHERE id = #{id}
? ? </select>
</mapper>
```

當應(yīng)用程序調(diào)用 Mapper 接口中的方法時,MyBatis 會根據(jù)方法的定義(注解或 XML 文件中的配置)來執(zhí)行對應(yīng)的 SQL 語句,將查詢結(jié)果映射為 Java 對象并返回給調(diào)用方。

總結(jié)來說,即使 Mapper 接口沒有對應(yīng)的實現(xiàn)類,MyBatis 也能通過動態(tài)代理的方式實現(xiàn)接口與 SQL 語句的綁定,使開發(fā)人員可以方便地以接口的方式來操作數(shù)據(jù)庫,提高了開發(fā)效率和代碼的可維護性。

MyBatis 與 Spring 框架整合

在將 MyBatis 與 Spring 框架整合時,需要配置 Spring 的 ApplicationContext,并將 MyBatis 的 SqlSessionFactory 注入到 Spring 的容器中,以便讓 Spring 管理 MyBatis 的 SqlSessionFactory,并能夠進行事務(wù)管理、異常處理等操作。下面是將 MyBatis 與 Spring 整合的一般步驟:

1. **配置 MyBatis 的 SqlSessionFactoryBean:** 在 Spring 的配置文件中配置 MyBatis 的 SqlSessionFactoryBean,用于創(chuàng)建 MyBatis 的 SqlSessionFactory 實例,并配置數(shù)據(jù)源、Mapper 接口掃描等信息。

```xml
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
? ? <property name="dataSource" ref="dataSource" />
? ? <property name="mapperLocations" value="classpath:com/example/mappers/*.xml" />
</bean>
```

2. **配置 MyBatis 的 MapperScannerConfigurer:** 使用 MapperScannerConfigurer 配置自動掃描 Mapper 接口,并將其注冊為 Spring 的 Bean。

```xml
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
? ? <property name="basePackage" value="com.example.mappers" />
</bean>
```

3. **配置事務(wù)管理器和動態(tài)代理**:配置事務(wù)管理器(如 DataSourceTransactionManager)以及 MyBatis 的 Mapper Bean 動態(tài)代理。

```xml
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
? ? <property name="dataSource" ref="dataSource" />
</bean>

<bean class="org.mybatis.spring.mapper.MapperFactoryBean">
? ? <property name="sqlSessionFactory" ref="sqlSessionFactory" />
? ? <property name="mapperInterface" value="com.example.UserMapper" />
</bean>
```

4. **在業(yè)務(wù)邏輯中使用 Mapper 接口:** 在業(yè)務(wù)邏輯的 Spring Bean 中注入 Mapper 接口,然后就可以通過 Mapper 接口來執(zhí)行 SQL 操作。

```java
@Autowired
private UserMapper userMapper;
```

5. **配置數(shù)據(jù)源和其他必要的 Bean:** 還需要配置數(shù)據(jù)源、事務(wù)管理器等其它必要的 Bean,用于 MyBatis 與數(shù)據(jù)庫的交互和事務(wù)管理。

通過以上步驟,將 MyBatis 與 Spring 整合后,就可以在 Spring 的應(yīng)用程序中方便地使用 MyBatis 來操作數(shù)據(jù)庫,實現(xiàn)數(shù)據(jù)訪問層的功能。整合的過程主要是通過配置 Spring 的配置文件來管理 MyBatis 的相關(guān) Bean,并利用 Spring 的依賴注入來獲取需要的組件,從而實現(xiàn) MyBatis 與 Spring 的無縫整合。

MyBatis 緩存

MyBatis 是一個流行的持久層框架,用于對數(shù)據(jù)庫進行操作。MyBatis 提供了一級緩存和二級緩存來優(yōu)化數(shù)據(jù)庫訪問,提高系統(tǒng)性能。

一級緩存: 一級緩存是 MyBatis 中默認開啟的緩存,它指的是 SqlSession 級別的緩存。當查詢完數(shù)據(jù)后,數(shù)據(jù)將會保存在 SqlSession 的緩存中,后續(xù)對同一條數(shù)據(jù)的查詢將不會再訪問數(shù)據(jù)庫,而是直接從緩存中獲取。一級緩存的作用域是當前 SqlSession,在同一個 SqlSession 中進行的多次查詢可以共享一級緩存。

二級緩存: 二級緩存是 MyBatis 的全局緩存,它作用于 SqlSessionFactory 級別,可以被同一個數(shù)據(jù)庫的不同 SqlSession 所共享。這意味著當不同的 SqlSession 執(zhí)行相同的 SQL 查詢時,可以從二級緩存中獲取數(shù)據(jù),而不必再次訪問數(shù)據(jù)庫。需要注意的是,二級緩存是跨 SqlSession 的,如果在一個 SqlSession 中更新了數(shù)據(jù),會清空二級緩存中與該數(shù)據(jù)相關(guān)的數(shù)據(jù),保證緩存的一致性。

啟用二級緩存的步驟包括:

  1. 在 MyBatis 的配置文件中開啟二級緩存:

    <settings><setting name="cacheEnabled" value="true"/>
    </settings>
  2. 針對需要使用二級緩存的映射文件,添加 <cache/> 標簽:

    <mapper namespace="com.example.UserMapper"><cache/><!-- 其他映射配置 -->
    </mapper>

需要注意的是,當配置了二級緩存后,需要在需要共享緩存的實體類中通過 <cache/> 標簽明確指定是否開啟二級緩存,因為默認情況下是關(guān)閉的。并且需要確保相關(guān)的實體類實現(xiàn)了 Serializable 接口。因為二級緩存默認使用 Java 的序列化機制進行對象的序列化和反序列化。

總的來說,一級緩存和二級緩存在 MyBatis 中是用來提升查詢性能的重要機制。一級緩存作用于 SqlSession 級別,適用于短生命周期的對象,而二級緩存作用于 SqlSessionFactory 級別,適用于長生命周期的對象,可以在不同 SqlSession 之間共享緩存,但需要注意數(shù)據(jù)的一致性。

Mybatis是如何進行分頁的?分頁插件的原理是什么?


Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結(jié)果集執(zhí)行的內(nèi)存分頁,而非物理分頁,可以在sql內(nèi)直接書寫帶有物理分頁的參數(shù)來完成物理分頁功能,也可以使用分頁插件來完成物理分頁。

分頁插件的基本原理是使用Mybatis提供的插件接口,實現(xiàn)自定義插件,在插件的攔截方法內(nèi)攔截待執(zhí)行的sql,然后重寫sql,根據(jù)dialect方言,添加對應(yīng)的物理分頁語句和物理分頁參數(shù)。

舉例:select * from student,攔截sql后重寫為:select t.* from (select * from student) t limit 0, 10

MyBatis編程步驟是什么樣的?


1、 創(chuàng)建SqlSessionFactory

2、 通過SqlSessionFactory創(chuàng)建SqlSession

3、 通過sqlsession執(zhí)行數(shù)據(jù)庫操作

4、 調(diào)用session.commit()提交事務(wù)

5、 調(diào)用session.close()關(guān)閉會話
?

Mybatis都有哪些Executor執(zhí)行器?它們之間的區(qū)別是什么?


Mybatis有三種基本的Executor執(zhí)行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor:每執(zhí)行一次update或select,就開啟一個Statement對象,用完立刻關(guān)閉Statement對象。

ReuseExecutor:執(zhí)行update或select,以sql作為key查找Statement對象,存在就使用,不存在就創(chuàng)建,用完后,不關(guān)閉Statement對象,而是放置于Map<String, Statement>內(nèi),供下一次使用。簡言之,就是重復(fù)使用Statement對象。

BatchExecutor:執(zhí)行update(沒有select,JDBC批處理不支持select),將所有sql都添加到批處理中(addBatch()),等待統(tǒng)一執(zhí)行(executeBatch()),它緩存了多個Statement對象,每個Statement對象都是addBatch()完畢后,等待逐一執(zhí)行executeBatch()批處理。與JDBC批處理相同。

作用范圍:Executor的這些特點,都嚴格限制在SqlSession生命周期范圍內(nèi)。

模糊查詢like語句該怎么寫


(1)’%${question}%’ 可能引起SQL注入,不推薦

(2)"%"#{question}"%" 注意:因為#{…}解析成sql語句時候,會在變量外側(cè)自動加單引號’ ',所以這里 % 需要使用雙引號" ",不能使用單引號 ’ ',不然會查不到任何結(jié)果。

(3)CONCAT(’%’,#{question},’%’) 使用CONCAT()函數(shù),推薦

(4)使用bind標簽

<select id="listUserLikeUsername" resultType="com.jourwon.pojo.User">
  <bind name="pattern" value="'%' + username + '%'" />
  select id,sex,age,username,password from person where username LIKE #{pattern}
</select>


在mapper中如何傳遞多個參數(shù)


方法1:順序傳參法

public User selectUser(String name, int deptId);

<select id="selectUser" resultMap="UserResultMap">
? ? select * from user
? ? where user_name = #{0} and dept_id = #{1}
</select>

#{}里面的數(shù)字代表傳入?yún)?shù)的順序。

這種方法不建議使用,sql層表達不直觀,且一旦順序調(diào)整容易出錯。

方法2:@Param注解傳參法

public User selectUser(@Param("userName") String name, int @Param("deptId") deptId);

<select id="selectUser" resultMap="UserResultMap">
? ? select * from user
? ? where user_name = #{userName} and dept_id = #{deptId}
</select>

#{}里面的名稱對應(yīng)的是注解@Param括號里面修飾的名稱。

這種方法在參數(shù)不多的情況還是比較直觀的,推薦使用。

方法3:Map傳參法

public User selectUser(Map<String, Object> params);

<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
? ? select * from user
? ? where user_name = #{userName} and dept_id = #{deptId}
</select>

#{}里面的名稱對應(yīng)的是Map里面的key名稱。

這種方法適合傳遞多個參數(shù),且參數(shù)易變能靈活傳遞的情況。

方法4:Java Bean傳參法

public User selectUser(User user);

<select id="selectUser" parameterType="com.jourwon.pojo.User" resultMap="UserResultMap">
? ? select * from user
? ? where user_name = #{userName} and dept_id = #{deptId}
</select>

#{}里面的名稱對應(yīng)的是User類里面的成員屬性。

這種方法直觀,需要建一個實體類,擴展不容易,需要加屬性,但代碼可讀性強,業(yè)務(wù)邏輯處理方便,推薦使用。

Mybatis如何執(zhí)行批量操作
使用foreach標簽

foreach的主要用在構(gòu)建in條件中,它可以在SQL語句中進行迭代一個集合。foreach標簽的屬性主要有item,index,collection,open,separator,close。

item  表示集合中每一個元素進行迭代時的別名,隨便起的變量名;
index  指定一個名字,用于表示在迭代過程中,每次迭代到的位置,不常用;
open  表示該語句以什么開始,常用“(”;
separator表示在每次進行迭代之間以什么符號作為分隔符,常用“,”;
close  表示以什么結(jié)束,常用“)”。
在使用foreach的時候最關(guān)鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是在不同情況下,該屬性的值是不一樣的,主要有一下3種情況:

如果傳入的是單參數(shù)且參數(shù)類型是一個List的時候,collection屬性值為list
如果傳入的是單參數(shù)且參數(shù)類型是一個array數(shù)組的時候,collection的屬性值為array
如果傳入的參數(shù)是多個的時候,我們就需要把它們封裝成一個Map了,當然單參數(shù)也可以封裝成map,實際上如果你在傳入?yún)?shù)的時候,在MyBatis里面也是會把它封裝成一個Map的,
map的key就是參數(shù)名,所以這個時候collection屬性值就是傳入的List或array對象在自己封裝的map里面的key
具體用法如下:

<!-- 批量保存(foreach插入多條數(shù)據(jù)兩種方法)
? ? ? ?int addEmpsBatch(@Param("emps") List<Employee> emps); -->
<!-- MySQL下批量保存,可以foreach遍歷 mysql支持values(),(),()語法 --> //推薦使用
<insert id="addEmpsBatch">
? ? INSERT INTO emp(ename,gender,email,did)
? ? VALUES
? ? <foreach collection="emps" item="emp" separator=",">
? ? ? ? (#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
? ? </foreach>
</insert>

<!-- 這種方式需要數(shù)據(jù)庫連接屬性allowMutiQueries=true的支持
?如jdbc.url=jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true --> ?
<insert id="addEmpsBatch">
? ? <foreach collection="emps" item="emp" separator=";"> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? INSERT INTO emp(ename,gender,email,did)
? ? ? ? VALUES(#{emp.eName},#{emp.gender},#{emp.email},#{emp.dept.id})
? ? </foreach>
</insert>


在 MyBatis 中進行一對一和一對多的關(guān)聯(lián)查詢

在 MyBatis 中實現(xiàn)一對一和一對多的關(guān)聯(lián)查詢,通常有以下幾種方式:

### 一對一關(guān)聯(lián)查詢的實現(xiàn)方式:
1. **嵌套查詢(Nested Queries):** 在父查詢中通過嵌套查詢子查詢來獲取關(guān)聯(lián)對象的信息。
2. **嵌套結(jié)果(Nested Results):** 在 SQL 查詢語句中通過使用嵌套 Select 語句實現(xiàn)一對一關(guān)聯(lián)查詢。
3. **嵌套映射(Nested Mapping):** 通過在 ResultMap 中定義嵌套的 ResultMap 來實現(xiàn)一對一關(guān)聯(lián)查詢。

下面是一種常見的嵌套查詢方式的操作步驟:

1. 在 SQL Mapper XML 文件中配置:

?

<!-- 查詢訂單信息,并關(guān)聯(lián)查詢用戶信息 -->
<select id="selectOrderWithUser" resultMap="orderUserResultMap">SELECT o.*, u.id as user_id, u.username as user_username, u.email as user_emailFROM orders oINNER JOIN users u ON o.user_id = u.idWHERE o.id = #{orderId}
</select><!-- 定義 ResultMap -->
<resultMap id="orderUserResultMap" type="Order"><id property="id" column="id" /><association property="user" resultMap="userResultMap" />
</resultMap><resultMap id="userResultMap" type="User"><id property="id" column="user_id"/><result property="username" column="user_username" /><result property="email" column="user_email" />
</resultMap>

?2. 在 Mapper 接口中定義方法:

Order selectOrderWithUser(Long orderId);


?

?3. 在 Service 層調(diào)用 Mapper 中定義的方法:

Order order = orderMapper.selectOrderWithUser(orderId);


?

一對多關(guān)聯(lián)查詢的實現(xiàn)方式:
1. **嵌套查詢:** 使用多條 SQL 查詢語句來獲取一對多關(guān)聯(lián)的數(shù)據(jù)。
2. **嵌套結(jié)果:** 在 SQL 查詢語句中使用 Join 等方式,將一對多關(guān)聯(lián)的數(shù)據(jù)合并在查詢結(jié)果中。
3. **嵌套映射:** 通過在 ResultMap 中定義 Collection 來實現(xiàn)一對多關(guān)聯(lián)查詢。

下面是一種常見的嵌套查詢方式的操作步驟:

1. 在 SQL Mapper XML 文件中配置:

<!-- 查詢部門信息,并關(guān)聯(lián)查詢所有員工信息 -->
<select id="selectDepartmentWithEmployees" resultMap="departmentEmployeesResultMap">SELECT d.id as department_id, d.name as department_name,e.id as employee_id, e.name as employee_name, e.email as employee_emailFROM departments dLEFT JOIN employees e ON d.id = e.department_idWHERE d.id = #{departmentId}
</select><!-- 定義 ResultMap -->
<resultMap id="departmentEmployeesResultMap" type="Department"><id property="id" column="department_id" /><result property="name" column="department_name" /><collection property="employees" ofType="Employee"><id property="id" column="employee_id"/><result property="name" column="employee_name"/><result property="email" column="employee_email"/></collection>
</resultMap>


?

?2. 在 Mapper 接口中定義方法:

Department selectDepartmentWithEmployees(Long departmentId);


?

3. 在 Service 層調(diào)用 Mapper 中定義的方法:

Department department = departmentMapper.selectDepartmentWithEmployees(departmentId);


?

通過以上方式,可以實現(xiàn)在 MyBatis 中進行一對一和一對多的關(guān)聯(lián)查詢,具體的方式可以根據(jù)實際業(yè)務(wù)需求和數(shù)據(jù)結(jié)構(gòu)選擇最適合的方式進行操作。
?

Select * 的缺點

1. 不需要的列會增加數(shù)據(jù)傳輸時間和網(wǎng)絡(luò)開銷

用“SELECT * ”數(shù)據(jù)庫需要解析更多的對象、字段、權(quán)限、屬性等相關(guān)內(nèi)容,在 SQL 語句復(fù)雜,硬解析較多的情況下,會對數(shù)據(jù)庫造成沉重的負擔。

增大網(wǎng)絡(luò)開銷;* 有時會誤帶上如log、IconMD5之類的無用且大文本字段,數(shù)據(jù)傳輸size會幾何增漲。如果DB和應(yīng)用程序不在同一臺機器,這種開銷非常明顯

即使 mysql 服務(wù)器和客戶端是在同一臺機器上,使用的協(xié)議還是 tcp,通信也是需要額外的時間。

2. 對于無用的大字段,如 varchar、blob、text,會增加 io 操作

準確來說,長度超過 728 字節(jié)的時候,會先把超出的數(shù)據(jù)序列化到另外一個地方,因此讀取這條記錄會增加一次 io 操作。(MySQL InnoDB)

3. 失去MySQL優(yōu)化器“覆蓋索引”策略優(yōu)化的可能性

SELECT * 杜絕了覆蓋索引的可能性,而基于MySQL優(yōu)化器的“覆蓋索引”策略又是速度極快,效率極高,業(yè)界極為推薦的查詢優(yōu)化方式

select count(*)和select count(1)的區(qū)別

1、 一般情況下,Select Count (*)和Select Count(1)兩著返回結(jié)果是一樣的

2、 假如表沒有主鍵(Primary key), 那么count(1)比count(*)快,

3、 如果有主鍵的話,那主鍵作為count的條件時候count(主鍵)最快

4、 如果你的表只有一個字段的話那count(*)就是最快的

5、count(*) 跟 count(1) 的結(jié)果一樣,都包括對NULL的統(tǒng)計,而count(column) 是不包括NULL的統(tǒng)計

左連接 left Join 右連接,內(nèi)連接

在 MySQL 中,左連接(LEFT JOIN)、右連接(RIGHT JOIN)和內(nèi)連接(INNER JOIN)是 SQL 中常用的連接類型,它們的定義與區(qū)別如下:

### 1. 左連接(LEFT JOIN):

- 左連接是從左表(左邊)返回所有匹配左表的行,并返回右表中與左表匹配的行,如果右表中沒有匹配的行,則顯示為 NULL 值。
- 語法:`SELECT * FROM 左表 LEFT JOIN 右表 ON 左表.列 = 右表.列;`
- 左表中的所有行都會顯示在結(jié)果集中,右表中沒有匹配的行會被填充為 NULL 值。

### 2. 右連接(RIGHT JOIN):

- 右連接是從右表(右邊)返回所有匹配右表的行,并返回左表中與右表匹配的行,如果左表中沒有匹配的行,則顯示為 NULL 值。
- 語法:`SELECT * FROM 左表 RIGHT JOIN 右表 ON 左表.列 = 右表.列;`
- 右表中的所有行都會顯示在結(jié)果集中,左表中沒有匹配的行會被填充為 NULL 值。

### 3. 內(nèi)連接(INNER JOIN):

- 內(nèi)連接是返回匹配兩個表中行的行,并丟棄不匹配的行,即兩個表中連接條件不符合的行會被過濾掉。
- 語法:`SELECT * FROM 表1 INNER JOIN 表2 ON 表1.列 = 表2.列;`
- 只返回兩個表中連接條件符合的行,不匹配的行不會顯示在結(jié)果集中。

### 區(qū)別總結(jié):
- 左連接返回左表中所有行以及與左表匹配的右表行,右連接返回右表中所有行以及與右表匹配的左表行,內(nèi)連接只返回兩個表中連接條件符合的行。
- 三種連接方式都可以通過 `ON` 子句中指定連接條件,根據(jù)實際需求選擇合適的連接方式來獲取所需數(shù)據(jù)。

在實際應(yīng)用中,根據(jù)具體業(yè)務(wù)需求和數(shù)據(jù)關(guān)系選擇合適的連接方式,以獲取正確的結(jié)果集。

數(shù)據(jù)庫的五大范式

具體內(nèi)容如下:

第一范式:無重復(fù)列

即在一行中的每一列僅有唯一的值并且具有原子性

第二范式:任意一個字段都只依賴表中的同一字段,或者說,屬性完全依賴于主鍵

即非主鍵列的活動必須完全依賴整個主鍵,主鍵必須有唯一性的元素

第三范式:屬性不能傳遞依賴于主屬性,或者說,屬性不依賴其他非主屬性

即非主鍵列互不依賴

第四范式:禁止主鍵列和非主鍵列一對多關(guān)系不受約束

第五范式:將表分割成盡可能小的塊,為了排序在表中所有的冗余

MySql的三種日志及作用

這三種日志在 MySQL 數(shù)據(jù)庫中扮演著關(guān)鍵的角色,它們分別支撐著數(shù)據(jù)庫的事務(wù)持久性、數(shù)據(jù)一致性和可靠性。

  1. Redo Log(重做日志):

    • 作用:記錄事務(wù)對數(shù)據(jù)頁所做的修改,在事務(wù)提交前就將相關(guān)的 Redo log 記錄持久化到磁盤。這樣,在事務(wù)提交后即使數(shù)據(jù)頁還未寫入磁盤,數(shù)據(jù)庫也能通過 Redo log 進行數(shù)據(jù)的恢復(fù),保證了事務(wù)的持久性。

    • 數(shù)據(jù)一致性和可靠性:重做日志的存在保證了即使在數(shù)據(jù)庫崩潰或斷電的情況下,提交的事務(wù)對數(shù)據(jù)的修改也不會丟失,從而確保了數(shù)據(jù)的一致性和可靠性。

  1. Undo Log(回滾日志):

    • 作用:記錄事務(wù)執(zhí)行過程中對數(shù)據(jù)的舊值,支持事務(wù)的回滾和讀取操作的多版本并發(fā)控制。當事務(wù)執(zhí)行中需要回滾或讀取之前的版本時,可以通過 Undo log 進行數(shù)據(jù)的恢復(fù)操作。

    • 數(shù)據(jù)一致性和可靠性:Undo log 保證了事務(wù)的原子性和一致性,即使事務(wù)執(zhí)行過程中出現(xiàn)錯誤或需要回滾,也能確保數(shù)據(jù)的一致性和可靠性。

  2. Binlog(二進制日志):

    • 作用:記錄了所有的數(shù)據(jù)庫修改操作,包括對表的插入、更新、刪除等操作,以及對數(shù)據(jù)庫結(jié)構(gòu)的變更。Binlog 主要用于數(shù)據(jù)庫的主從復(fù)制、數(shù)據(jù)恢復(fù)、數(shù)據(jù)遷移等場景。

    • 數(shù)據(jù)一致性和可靠性:通過 Binlog,數(shù)據(jù)庫可以在分布式系統(tǒng)中實現(xiàn)主從復(fù)制,確保不同節(jié)點之間的數(shù)據(jù)一致性和可靠性;同時,通過恢復(fù) Binlog 也能實現(xiàn)對數(shù)據(jù)庫的數(shù)據(jù)恢復(fù)和數(shù)據(jù)遷移,保證了數(shù)據(jù)的可靠性和一致性。

綜合來看,通過 Redo log 的持久化、Undo log 的回滾支持和 Binlog 的記錄和傳播,MySQL 服務(wù)器保證了數(shù)據(jù)的一致性和可靠性。這些日志機制都是數(shù)據(jù)庫引擎和服務(wù)器核心的組成部分,確保了數(shù)據(jù)庫的 ACID 特性,即原子性、一致性、隔離性和持久性。

redo log和binlog區(qū)別

  • redo log是屬于innoDB層面,binlog屬于MySQL Server層面的,這樣在數(shù)據(jù)庫用別的存儲引擎時可以達到一致性的要求。

  • redo log是物理日志,記錄該數(shù)據(jù)頁更新的內(nèi)容;binlog是邏輯日志,記錄的是這個更新語句的原始邏輯

  • redo log是循環(huán)寫,日志空間大小固定;binlog是追加寫,是指一份寫到一定大小的時候會更換下一個文件,不會覆蓋。

  • binlog可以作為恢復(fù)數(shù)據(jù)使用,主從復(fù)制搭建,redo log作為異常宕機或者介質(zhì)故障后的數(shù)據(jù)恢復(fù)使用。

索引的基本原理

1、為什么要有索引? 一般的應(yīng)用系統(tǒng),讀寫比例在10:1左右,而且插入操作和一般的更新操作很少出現(xiàn)性能問題,在生產(chǎn)環(huán)境中,我們遇到最多的,也是最容易出問題的,還是一些復(fù)雜的查詢操作,因此對查詢語句的優(yōu)化顯然是重中之重。說起加速查詢,就不得不提到索引了。 2、什么是索引? 索引在MySQL中也叫是一種“鍵”,是存儲引擎用于快速找到記錄的一種數(shù)據(jù)結(jié)構(gòu)。索引對于良好的性能 非常關(guān)鍵,尤其是當表中的數(shù)據(jù)量越來越大時,索引對于性能的影響愈發(fā)重要。 索引優(yōu)化應(yīng)該是對查詢性能優(yōu)化最有效的手段了。索引能夠輕易將查詢性能提高好幾個數(shù)量級。 索引相當于字典的音序表,如果要查某個字,如果不使用音序表,則需要從幾百頁中逐頁去查。

3、索引的原理

索引的目的在于提高查詢效率,與我們查閱圖書所用的目錄是一個道理:先定位到章,然后定位到該章下的一個小節(jié),然后找到頁數(shù)。相似的例子還有:查字典,查火車車次,飛機航班等

本質(zhì)都是:通過不斷地縮小想要獲取數(shù)據(jù)的范圍來篩選出最終想要的結(jié)果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,我們可以總是用同一種查找方式來鎖定數(shù)據(jù)。

數(shù)據(jù)庫也是一樣,但顯然要復(fù)雜的多,因為不僅面臨著等值查詢,還有范圍查詢(>、<、between、in)、模糊查詢(like)、并集查詢(or)等等。數(shù)據(jù)庫應(yīng)該選擇怎么樣的方式來應(yīng)對所有的問題呢?我們回想字典的例子,能不能把數(shù)據(jù)分成段,然后分段查詢呢?最簡單的如果1000條數(shù)據(jù),1到100分成第一段,101到200分成第二段,201到300分成第三段…這樣查第250條數(shù)據(jù),只要找第三段就可以了,一下子去除了90%的無效數(shù)據(jù)。但如果是1千萬的記錄呢,分成幾段比較好?按照搜索樹的模型,其平均復(fù)雜度是lgN,具有不錯的查詢性能。但這里我們忽略了一個關(guān)鍵的問題,復(fù)雜度模型是基于每次相同的操作成本來考慮的。而數(shù)據(jù)庫實現(xiàn)比較復(fù)雜,一方面數(shù)據(jù)是保存在磁盤上的,另外一方面為了提高性能,每次又可以把部分數(shù)據(jù)讀入內(nèi)存來計算,因為我們知道訪問磁盤的成本大概是訪問內(nèi)存的十萬倍左右,所以簡單的搜索樹難以滿足復(fù)雜的應(yīng)用場景。

4、索引的數(shù)據(jù)結(jié)構(gòu)

MySQL主要用到兩種結(jié)構(gòu):B+ Tree索引和Hash索引 Inodb存儲引擎 默認是 B+Tree索引 Memory 存儲引擎 默認 Hash索引; MySQL中,只有Memory(Memory表只存在內(nèi)存中,斷電會消失,適用于臨時表)存儲引擎顯示支持Hash索引,是Memory表的默認索引類型,盡管Memory表也可以使用B+Tree索引。Hash索引把數(shù)據(jù)以hash形式組織起來,因此當查找某一條記錄的時候,速度非???。但是因為hash結(jié)構(gòu),每個鍵只對應(yīng)一個值,而且是散列的方式分布。所以它并不支持范圍查找和排序等功能。 B+Tree是mysql使用最頻繁的一個索引數(shù)據(jù)結(jié)構(gòu),是InnoDB和MyISAM存儲引擎模式的索引類型。相對Hash索引,B+Tree在查找單條記錄的速度比不上Hash索引,但是因為更適合排序等操作,所以它更受歡迎。畢竟不可能只對數(shù)據(jù)庫進行單條記錄的操作。 對比: hash類型的索引:查詢單條快,范圍查詢慢 btree類型的索引:b+樹,層數(shù)越多,數(shù)據(jù)量指數(shù)級增長(我們就用它,因為innodb默認支持它)

B+ 樹索引結(jié)構(gòu)

在 MySQL 中,B+ 樹(B+ Tree)是一種常用的索引結(jié)構(gòu),用于加速數(shù)據(jù)庫表的數(shù)據(jù)查找操作。下面詳細講解 MySQL 中的 B+ 樹索引結(jié)構(gòu)以及選擇它的原因:

### 1. B+ 樹索引結(jié)構(gòu):

- **結(jié)構(gòu)特點:**
? - B+ 樹是一種平衡多路搜索樹,具有樹形結(jié)構(gòu),每個節(jié)點可以包含多個子節(jié)點。
? - 每個非葉子節(jié)點存儲索引字段和指向子節(jié)點的指針,葉子節(jié)點存儲索引字段和指向數(shù)據(jù)行的指針。
? - 葉子節(jié)點按順序連接形成一個有序鏈表,方便范圍查詢操作。

- **查找過程:**
? - 從根節(jié)點開始,根據(jù)節(jié)點中的索引值進行比較,沿著合適的路徑向下查找,直到找到葉子節(jié)點。
? - 在葉子節(jié)點中進行精確查找或范圍查找,找到對應(yīng)的數(shù)據(jù)行。

### 2. 為什么選擇 B+ 樹索引結(jié)構(gòu):

- **高效的檢索性能:** B+ 樹是一種高效的索引結(jié)構(gòu),其查詢的時間復(fù)雜度為 O(logN),可以快速定位到指定數(shù)據(jù)行,適用于大數(shù)據(jù)量數(shù)據(jù)庫表的索引。

- **有序性和范圍查詢:** B+ 樹的葉子節(jié)點形成有序鏈表,適合范圍查詢操作,能夠快速定位到指定范圍的數(shù)據(jù)行。

- **支持高效的插入和刪除操作:** B+ 樹的平衡性和節(jié)點分裂合并策略可以保持樹的平衡,保證高效的插入和刪除操作。

- **適合磁盤存儲:** B+ 樹的節(jié)點通常比較大,可以減少磁盤 I/O 次數(shù),適合磁盤存儲的數(shù)據(jù)庫系統(tǒng)。

- **支持索引順序遍歷:** B+ 樹的葉子節(jié)點形成有序鏈表,可以支持索引的順序遍歷,提高查詢性能。

- **適合范圍查詢和排序:** B+ 樹的有序性和范圍查詢優(yōu)勢,使其適合在 MySQL 數(shù)據(jù)庫中用于支持范圍查詢、排序操作。

綜上所述,MySQL 選擇 B+ 樹作為索引結(jié)構(gòu)的原因是因為它能夠提供高效的檢索性能、有序性以支持范圍查詢、適合磁盤存儲、支持高效的插入和刪除操作等特點,能夠滿足數(shù)據(jù)庫系統(tǒng)對索引結(jié)構(gòu)的需求,提高數(shù)據(jù)庫表的查詢性能和效率。

索引的最左匹配原則

最左匹配原則是指在復(fù)合索引中,MySQL會按照索引的最左列開始匹配查詢條件,然后逐漸向右匹配。只有當查詢條件中連續(xù)的列滿足了索引的最左前綴時,索引才能被充分利用。以下是一些例子來說明最左匹配原則:

  1. 假設(shè)有一個復(fù)合索引 (column1, column2, column3)

    • 有效的查詢條件示例:WHERE column1 = 'A'

    • 無效的查詢條件示例:WHERE column2 = 'B',因為沒有匹配到索引的最左列 column1

  2. 假設(shè)有一個復(fù)合索引 (column1, column2)。

    • 有效的查詢條件示例:WHERE column1 = 'A'

    • 有效的查詢條件示例:WHERE column1 = 'A' AND column2 = 'B'

    • 無效的查詢條件示例:WHERE column2 = 'B',因為沒有匹配到索引的最左列 column1

  3. 假設(shè)有一個復(fù)合索引 (column1, column2)

    • 有效的查詢條件示例:WHERE column1 > 'A'

    • 無效的查詢條件示例:WHERE column2 > 'B',因為沒有匹配到索引的最左列 column1

  4. 最左前綴匹配原則,非常重要的原則,mysql會一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調(diào)整。 =和in可以亂序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意順序,mysql的查詢優(yōu)化器會幫你優(yōu)化成索引可以識別的形式

總結(jié)起來,最左匹配原則適用于以下情況:

  • 查詢條件從索引的最左列開始,連續(xù)向右匹配索引列。

  • 查詢條件中的列滿足了索引的最左前綴。

如果查詢條件不符合以上兩個條件,那么最左匹配原則將失效,MySQL將無法充分利用復(fù)合索引。

在設(shè)計和優(yōu)化索引時,了解最左匹配原則是很有幫助的。它可以幫助你合理地選擇索引列的順序,以提高查詢性能和索引的利用率。

mysql聚簇和非聚簇索引的區(qū)別是什么?

mysql的索引類型跟存儲引擎是相關(guān)的,innodb存儲引擎數(shù)據(jù)文件跟索引文件全部放在ibd文件中,而myisam的數(shù)據(jù)文件放在myd文件中,索引放在myi文件中,其實區(qū)分聚簇索引和非聚簇索引非常簡單,只要判斷數(shù)據(jù)跟索引是否存儲在一起就可以了。

innodb存儲引擎在進行數(shù)據(jù)插入的時候,數(shù)據(jù)必須要跟索引放在一起,如果有主鍵就使用主鍵,沒有主鍵就使用唯一鍵,沒有唯一鍵就使用6字節(jié)的rowid,因此跟數(shù)據(jù)綁定在一起的就是聚簇索引,而為了避免數(shù)據(jù)冗余存儲,其他的索引的葉子節(jié)點中存儲的都是聚簇索引的key值,因此innodb中既有聚簇索引也有非聚簇索引,而myisam中只有非聚簇索引。

mysql索引結(jié)構(gòu)有哪些,各自的優(yōu)劣是什么?

索引的數(shù)據(jù)結(jié)構(gòu)和具體存儲引擎的實現(xiàn)有關(guān),mysql中使用較多的索引有hash索引,B+樹索引,innodb的索引實現(xiàn)為B+樹,memory存儲引擎為hash索引。

B+樹是一個平衡的多叉樹,從根節(jié)點到每個葉子節(jié)點的高度差值不超過1,而且同層級的二節(jié)點間有指針相關(guān)連接,在B+樹上的常規(guī)檢索,從根節(jié)點到葉子節(jié)點的搜索效率基本相當,不會出現(xiàn)大幅波動,而且基于索引的順序掃描時,也可以利用雙向指針快速左右移動,效率非常高。因為,B+樹索引被廣泛應(yīng)用于數(shù)據(jù)庫、文件系統(tǒng)等場景。

哈希索引就是采用一定的哈希算法,把鍵值換算成新的哈希值,檢索時不需要類似B+樹那樣從根節(jié)點到葉子節(jié)點逐級查找,只需一次哈希算法即可立刻定位到相應(yīng)的位置,速度非??臁?/p>

如果是等值查詢,那么哈希索引明顯有絕對優(yōu)勢,因為只需要經(jīng)過一次算法即可找到相應(yīng)的鍵值,前提是鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然后再根據(jù)鏈表往后掃描,知道找到對應(yīng)的數(shù)據(jù)

如果是范圍查詢檢索,這時候哈徐索引就毫無用武之地了,因為原先是有序的鍵值,經(jīng)過哈希算法后,有可能變成不連續(xù)的了,就沒辦法再利用索引完成范圍查詢檢索

哈希所有也沒辦法利用索引完成排序,以及l(fā)ike這樣的部分模糊查詢

哈希索引也不支持多列聯(lián)合索引的最左匹配規(guī)則

B+樹索引的關(guān)鍵字檢索效率比較平均,不像B樹那樣波動大,在有大量重復(fù)鍵值情況下,哈希索引的效率也是極低的,因此存在哈希碰撞問題。

索引的設(shè)計原則有哪些?

在數(shù)據(jù)庫中,創(chuàng)建索引是提高查詢效率和性能的重要手段之一。以下是一些創(chuàng)建索引的原則:

  1. 選擇合適的列:選擇那些經(jīng)常用于查詢和連接的列來創(chuàng)建索引。通常包括經(jīng)常出現(xiàn)在WHERE、JOIN、ORDER BY和GROUP BY子句中的列。

  2. 避免過度索引:不要為每個列都創(chuàng)建索引,因為索引的維護和存儲會帶來額外的開銷。過多的索引不僅會占用磁盤空間,還可能導(dǎo)致索引失效、降低寫操作的性能等問題。

  3. 考慮列的選擇性:選擇具有較高選擇性(不重復(fù)值較多)的列來創(chuàng)建索引,這樣可以減少索引的大小和搜索的區(qū)間。

  4. 考慮查詢的頻率和重要性:根據(jù)查詢的頻率和重要性來選擇創(chuàng)建索引的列。如果某個查詢非常頻繁且對性能要求較高,那么為該查詢常用的列創(chuàng)建索引是很有必要的。

  5. 綜合考慮查詢和更新的平衡:索引會提高查詢的速度,但會降低更新操作的速度。因此,在創(chuàng)建索引時需要綜合考慮查詢和更新的平衡,選擇適當?shù)乃饕呗浴?/p>

  6. 考慮數(shù)據(jù)量和存儲空間:索引會占用額外的存儲空間,因此在創(chuàng)建索引時需要考慮數(shù)據(jù)量的大小。對于較大的表和數(shù)據(jù)量龐大的表,需要謹慎選擇創(chuàng)建索引的列,以避免過度的存儲開銷。

  7. 定期維護和更新索引:索引的性能和效果是需要定期維護和更新的。當表的數(shù)據(jù)發(fā)生變化時,如插入、更新或刪除操作,需要及時更新索引以保持索引的有效性。

  8. 使用復(fù)合索引:對于經(jīng)常同時查詢多個列的情況,可以考慮創(chuàng)建復(fù)合索引,即包含多個列的聯(lián)合索引。復(fù)合索引可以提高查詢效率,并且可以減少索引的數(shù)量。

除了以上原則外,創(chuàng)建索引還需要根據(jù)具體的數(shù)據(jù)庫系統(tǒng)和查詢需求做進一步的優(yōu)化和調(diào)整。在進行索引設(shè)計時,需要綜合考慮數(shù)據(jù)庫結(jié)構(gòu)、查詢模式、數(shù)據(jù)量等因素,以達到提高查詢性能的目的。

在進行索引設(shè)計的時候,應(yīng)該保證索引字段占用的空間越小越好,這只是一個大的方向,還有一些細節(jié)點需要注意下:

1、適合索引的列是出現(xiàn)在where字句中的列,或者連接子句中指定的列

2、基數(shù)較小的表,索引效果差,沒必要創(chuàng)建索引

3、在選擇索引列的時候,越短越好,可以指定某些列的一部分,沒必要用全部字段的值

4、不要給表中的每一個字段都創(chuàng)建索引,并不是索引越多越好

5、定義有外鍵的數(shù)據(jù)列一定要創(chuàng)建索引

6、更新頻繁的字段不要有索引

7、創(chuàng)建索引的列不要過多,可以創(chuàng)建組合索引,但是組合索引的列的個數(shù)不建議太多

8、大文本、大對象不要創(chuàng)建索引

索引失效的十大原因

索引失效的場景

1、不滿足最左匹配原則

2、索引列上有計算 如:where id+1=2

3、索引列上使用了函數(shù) 如:where SUBSTR(name,1,2)=17

4、字段類型不同,如本來是數(shù)字類型,結(jié)果加上了引號變成了字符串

5、like 左邊加上了%號6、列對比,兩個列在where后面進行比較

7、使用or,如果使用or,前面和后面的列都要加上索引才會生效

8、not in和not exists,如果主鍵索引會走索引,其他不會

9、!= 慎重使用,基本會走全表,Extral中有using where=全表掃描

10、排序列和聯(lián)合索引順序不一致

11、排序列包含非一個索引的列

https://www.cnblogs.com/wushaopei/p/12283647.html

什么是回表查詢?

通俗的講就是,如果索引的列在 select 所需獲得的列中(因為在 mysql 中索引是根據(jù)索引列的值進行排序的,所以索引節(jié)點中存在該列中的部分值)或者根據(jù)一次索引查詢就能獲得記錄就不需要回表,如果 select 所需獲得列中有大量的非索引列,索引就需要到表中找到相應(yīng)的列的信息,這就叫回表。

回表查詢,先定位主鍵值,再定位行記錄,它的性能較掃一遍索引樹更低。

使用聚集索引(主鍵或第一個唯一索引)就不會回表,普通索引就會回表

什么是覆蓋索引?***

通常開發(fā)人員會根據(jù)查詢的where條件來創(chuàng)建合適的索引,但是優(yōu)秀的索引設(shè)計應(yīng)該考慮到整個查詢。其實mysql可以使用索引來直接獲取列的數(shù)據(jù)。如果索引的葉子節(jié)點包含了要查詢的數(shù)據(jù),那么就不用回表查詢了,也就是說這種索引包含(亦稱覆蓋)所有需要查詢的字段的值,我們稱這種索引為覆蓋索引。

1、索引項通常比記錄要小,所以MySQL訪問更少的數(shù)據(jù)。

2、索引都按值得大小存儲,相對于隨機訪問記錄,需要更少的I/O。

3、數(shù)據(jù)引擎能更好的緩存索引,比如MyISAM只緩存索引。

4、覆蓋索引對InnoDB尤其有用,因為InnoDB使用聚集索引組織數(shù)據(jù),如果二級索引包含查詢所需的數(shù)據(jù),就不再需要在聚集索引中查找了。

限制:

1、覆蓋索引也并不適用于任意的索引類型,索引必須存儲列的值。

2、Hash和full-text索引不存儲值,因此MySQL只能使用BTree。

3、不同的存儲引擎實現(xiàn)覆蓋索引都是不同的,并不是所有的存儲引擎都支持覆蓋索引。

4、如果要使用覆蓋索引,一定要注意SELECT列表值取出需要的列,不可以SELECT * ,因為如果將所有字段一起做索引會導(dǎo)致索引文件過大,查詢性能下降。

索引下推

如果沒有索引下推優(yōu)化(或稱ICP優(yōu)化),當進行索引查詢時,首先根據(jù)索引來查找記錄,然后再根據(jù)where條件來過濾記錄;在支持ICP優(yōu)化后,MySQL會在取出索引的同時,判斷是否可以進行where條件過濾再進行索引查詢,也就是說提前執(zhí)行where的部分過濾操作,在某些場景下,可以大大減少回表次數(shù),從而提升整體性能。

mysql鎖的類型有哪些?

基于鎖的屬性分類:共享鎖、排他鎖。

基于鎖的粒度分類:行級鎖(innodb )、表級鎖( innodb 、myisam)、頁級鎖( innodb引擎)、記錄鎖、間隙鎖、臨鍵鎖。

基于鎖的狀態(tài)分類:意向共享鎖、意向排它鎖。

共享鎖(share lock): 共享鎖又稱讀鎖,簡稱 S 鎖;當一個事務(wù)為數(shù)據(jù)加上讀鎖之后,其他事務(wù)只能對該數(shù)據(jù)加讀鎖,而不能對數(shù)據(jù)加寫鎖,直到所有的讀鎖釋放之后其他事務(wù)才能對其進行加持寫鎖。共享鎖的特性主要是為了支持并發(fā)的讀取數(shù)據(jù),讀取數(shù)據(jù)的時候不支持修改,避免出現(xiàn)重復(fù)讀的問題。

排他鎖(exclusive lock):排他鎖又稱寫鎖,簡稱 X 鎖;當一個事務(wù)為數(shù)據(jù)加上寫鎖時,其他請求將不能再為數(shù)據(jù)加任何鎖,直到該鎖釋放之后,其他事務(wù)才能對數(shù)據(jù)進行加鎖。排他鎖的目的是在數(shù)據(jù)修改時候,不允許其他人同時修改,也不允許其他人讀取,避免了出現(xiàn)臟數(shù)據(jù)和臟讀的問題。

表鎖(table lock):表鎖是指上鎖的時候鎖住的是整個表,當下一個事務(wù)訪問該表的時候,必須等前一個事務(wù)釋放了鎖才能進行對表進行訪問;特點:粒度大,加鎖簡單,容易沖突;

行鎖:行鎖是指上鎖的時候鎖住的是表的某一行或多行記錄,其他事務(wù)訪問同一張表時,只有被鎖住的記錄不能訪問,其他的記錄可正常訪問,特點:粒度小,加鎖比表鎖麻煩,不容易沖突,相比表鎖支持的并發(fā)要高

記錄鎖(Record lock):記錄鎖也屬于行鎖中的一種,只不過記錄鎖的范圍只是表中的某一條記錄,記錄鎖是說事務(wù)在加鎖后鎖住的只是表的某一條記錄,加了記錄鎖之后數(shù)據(jù)可以避免數(shù)據(jù)在查詢的時候被修改的重復(fù)讀問題,也避免了在修改的事務(wù)未提交前被其他事務(wù)讀取的臟讀問題

頁鎖:頁級鎖是 MysQL 中鎖定粒度介于行級鎖和表級鎖中間的一種鎖.表級鎖速度快,但沖突多,行級沖突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。特點:開銷和加鎖時間界于表鎖和行鎖之間,會出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般。

間隙鎖:是屬于行鎖的一種,間隙鎖是在事務(wù)加鎖后其鎖住的是表記錄的某一個區(qū)間,當表的相鄰ID之間出現(xiàn)空隙則會形成一個區(qū)間,遵循左開右閉原則。范圍查詢并且查詢未命中記錄,查詢條件必須命中索引、間隙鎖只會出現(xiàn)在REPEATABLE_READ(重復(fù)讀)的事務(wù)級別中。

臨鍵鎖(Next-Key lock):也屬于行鎖的一種,并且它是INNODB的行鎖默認算法,總結(jié)來說它就是記錄鎖和間隙鎖的組合,臨鍵鎖會把查詢出來的記錄鎖住,同時也會把該范圍查詢內(nèi)的所有間隙空間也會鎖住,再之它會把相鄰的下一個區(qū)間也會鎖住。

mysql執(zhí)行計劃怎么看?

在 MySQL 中,可以通過使用 `EXPLAIN` 關(guān)鍵字來查看 SQL 語句的執(zhí)行計劃,幫助優(yōu)化查詢性能。下面是使用 `EXPLAIN` 查看 MySQL 執(zhí)行計劃的方法:

### 1. 基本語法:

```sql
EXPLAIN SELECT * FROM your_table WHERE your_condition;
```

?2. 實際操作步驟:

?a. 執(zhí)行查詢前加上 `EXPLAIN` 關(guān)鍵字:

```sql
EXPLAIN SELECT * FROM your_table WHERE your_condition;
```

b. 查看執(zhí)行計劃結(jié)果:

執(zhí)行以上 SQL 語句后,會返回一張表格,其中包含了關(guān)于查詢執(zhí)行的各種重要信息,例如查詢的優(yōu)化方式、表的讀取順序、使用的索引、行數(shù)估算等。

c. 解讀執(zhí)行計劃信息:

在執(zhí)行計劃結(jié)果中,可以注意以下一些重要的字段信息:

- **id:** 查詢的順序,如果是子查詢會有多個執(zhí)行順序。
- **select_type:** 查詢類型,如 SIMPLE、PRIMARY、DERIVED、SUBQUERY 等。
- **table:** 顯示查詢操作涉及的表。
- **type:** 表示 MySQL 在表中找到所需行的方式,常見的類型有 const、eq_ref、ref、range、index、all 等,通常從最好到最差的順序排列。
- **key:** 顯示 MySQL 決定使用哪個索引來優(yōu)化查詢。
- **rows:** 評估在找到所需行之前要檢查的行數(shù)。
- **Extra:** 包含關(guān)于查詢執(zhí)行的額外信息,可能包括使用了索引、臨時表等信息。

?3. 根據(jù)執(zhí)行計劃優(yōu)化 SQL:

通過查看執(zhí)行計劃,可以了解 MySQL 數(shù)據(jù)庫是如何執(zhí)行你的查詢的,并可以根據(jù)執(zhí)行計劃的信息進行 SQL 語句的調(diào)優(yōu),例如添加合適的索引、優(yōu)化表結(jié)構(gòu)、改變查詢方式等,以提高查詢性能和效率。

通過上述方法,你可以使用 `EXPLAIN` 關(guān)鍵字來查看 MySQL 的執(zhí)行計劃,幫助分析和優(yōu)化查詢語句的執(zhí)行效率。

事務(wù)的基本特性是什么?

事務(wù)四大特征:原子性,一致性,隔離性和持久性。

  1. 原子性(Atomicity) 一個原子事務(wù)要么完整執(zhí)行,要么干脆不執(zhí)行。這意味著,工作單元中的每項任務(wù)都必須正確執(zhí)行。如果有任一任務(wù)執(zhí)行失敗,則整個工作單元或事務(wù)就會被終止。即此前對數(shù)據(jù)所作的任何修改都將被撤銷。如果所有任務(wù)都被成功執(zhí)行,事務(wù)就會被提交,即對數(shù)據(jù)所作的修改將會是永久性的。

  2. 一致性(Consistency) 一致性代表了底層數(shù)據(jù)存儲的完整性。它必須由事務(wù)系統(tǒng)和應(yīng)用開發(fā)人員共同來保證。事務(wù)系統(tǒng)通過保證事務(wù)的原子性,隔離性和持久性來滿足這一要求; 應(yīng)用開發(fā)人員則需要保證數(shù)據(jù)庫有適當?shù)募s束(主鍵,引用完整性等),并且工作單元中所實現(xiàn)的業(yè)務(wù)邏輯不會導(dǎo)致數(shù)據(jù)的不一致(即,數(shù)據(jù)預(yù)期所表達的現(xiàn)實業(yè)務(wù)情況不相一致)。例如,在一次轉(zhuǎn)賬過程中,從某一賬戶中扣除的金額必須與另一賬戶中存入的金額相等。支付寶賬號100 你讀到余額要取,有人向你轉(zhuǎn)100 但是事物沒提交(這時候你讀到的余額應(yīng)該是100,而不是200) 這種就是一致性

  3. 隔離性(Isolation) 隔離性意味著事務(wù)必須在不干擾其他進程或事務(wù)的前提下獨立執(zhí)行。換言之,在事務(wù)或工作單元執(zhí)行完畢之前,其所訪問的數(shù)據(jù)不能受系統(tǒng)其他部分的影響。

  4. 持久性(Durability) 持久性表示在某個事務(wù)的執(zhí)行過程中,對數(shù)據(jù)所作的所有改動都必須在事務(wù)成功結(jié)束前保存至某種物理存儲設(shè)備。這樣可以保證,所作的修改在任何系統(tǒng)癱瘓時不至于丟失。

MySQL的隔離級別有哪些?

MySQL定義了四種隔離級別,包括一些具體規(guī)則,用于限定事務(wù)內(nèi)外哪些改變是可見的,哪些改變是不可見的。低級別的隔離一般支持更高的并發(fā)處理,并且擁有更低的系統(tǒng)開銷。

READ UNCOMMITTED 讀取未提交內(nèi)容 在這個隔離級別,所有事務(wù)都可以“看到”未提交事務(wù)的執(zhí)行結(jié)果。在這種級別上,可能會產(chǎn)生很多問題,除非用戶真的知道自己在做什么,并有很好的理由選擇這樣做。本隔離級別很少用于實際應(yīng)用,因為它的性能也不必其他性能好多少,而別的級別還有其他更多的優(yōu)點。讀取未提交數(shù)據(jù),也被稱為“臟讀”

READ COMMITTED 讀取提交內(nèi)容 大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認隔離級別(但是不是MySQL的默認隔離級別),滿足了隔離的早先簡單定義:一個事務(wù)開始時,只能“看見”已經(jīng)提交事務(wù)所做的改變,一個事務(wù)從開始到提交前,所做的任何數(shù)據(jù)改變都是不可見的,除非已經(jīng)提交。這種隔離級別也支持所謂的“不可重復(fù)讀”。這意味著用戶運行同一個語句兩次,看到的結(jié)果是不同的。

REPEATABLE READ 可重復(fù)讀 MySQL數(shù)據(jù)庫默認的隔離級別。該級別解決了READ UNCOMMITTED隔離級別導(dǎo)致的問題。它保證同一事務(wù)的多個實例在并發(fā)讀取事務(wù)時,會“看到同樣的”數(shù)據(jù)行。不過,這會導(dǎo)致另外一個棘手問題“幻讀”。InnoDB和Falcon存儲引擎通過多版本并發(fā)控制機制解決了幻讀問題。

SERIALIZABLE 可串行化 該級別是最高級別的隔離級。它通過強制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡而言之,SERIALIZABLE是在每個讀的數(shù)據(jù)行上加鎖。在這個級別,可能導(dǎo)致大量的超時Timeout和鎖競爭Lock Contention現(xiàn)象,實際應(yīng)用中很少使用到這個級別,但如果用戶的應(yīng)用為了數(shù)據(jù)的穩(wěn)定性,需要強制減少并發(fā)的話,也可以選擇這種隔離級。

一級封鎖協(xié)議。事務(wù)T在修改數(shù)據(jù)R之前必須先對其加X 鎖 直到事務(wù)結(jié)束才釋放??煞乐箒G失修改 二級封鎖協(xié)議。一級封鎖協(xié)議加上事務(wù)T在讀取數(shù)據(jù)R之前先對其加S鎖,讀完后即可釋放S鎖??煞乐箒G失修改,還可防止讀“臟”數(shù)據(jù) 三級封鎖協(xié)議。一級封鎖協(xié)議加上事務(wù)T在讀取數(shù)據(jù)R之前先對其加S鎖,直到事務(wù)結(jié)束才釋放。可防止丟失修改、防止讀“臟”數(shù)據(jù)與防止數(shù)據(jù)(不可)重復(fù)讀

兩段鎖協(xié)議。可串行化的??赡馨l(fā)生死鎖

  1. 臟讀

臟讀是指一個事務(wù)讀取了未提交事務(wù)執(zhí)行過程中的數(shù)據(jù)。 當一個事務(wù)的操作正在多次修改數(shù)據(jù),而在事務(wù)還未提交的時候,另外一個并發(fā)事務(wù)來讀取了數(shù)據(jù),就會導(dǎo)致讀取到的數(shù)據(jù)并非是最終持久化之后的數(shù)據(jù),這個數(shù)據(jù)就是臟讀的數(shù)據(jù)。

  1. 不可重復(fù)讀

不可重復(fù)讀是指對于數(shù)據(jù)庫中的某個數(shù)據(jù),一個事務(wù)執(zhí)行過程中多次查詢返回不同查詢結(jié)果,這就是在事務(wù)執(zhí)行過程中,數(shù)據(jù)被其他事務(wù)提交修改了。 不可重復(fù)讀同臟讀的區(qū)別在于,臟讀是一個事務(wù)讀取了另一未完成的事務(wù)執(zhí)行過程中的數(shù)據(jù),而不可重復(fù)讀是一個事務(wù)執(zhí)行過程中,另一事務(wù)提交并修改了當前事務(wù)正在讀取的數(shù)據(jù)。

  1. 虛讀(幻讀)

幻讀是事務(wù)非獨立執(zhí)行時發(fā)生的一種現(xiàn)象,例如事務(wù)T1批量對一個表中某一列列值為1的數(shù)據(jù)修改為2的變更,但是在這時,事務(wù)T2對這張表插入了一條列值為1的數(shù)據(jù),并完成提交。此時,如果事務(wù)T1查看剛剛完成操作的數(shù)據(jù),發(fā)現(xiàn)還有一條列值為1的數(shù)據(jù)沒有進行修改,而這條數(shù)據(jù)其實是T2剛剛提交插入的,這就是幻讀。 幻讀和不可重復(fù)讀都是讀取了另一條已經(jīng)提交的事務(wù)(這點同臟讀不同),所不同的是不可重復(fù)讀查詢的都是同一個數(shù)據(jù)項,而幻讀針對的是一批數(shù)據(jù)整體(比如數(shù)據(jù)的個數(shù))。

怎么處理MySQL的慢查詢?

處理 MySQL 的慢查詢可以采取以下幾種方法:

  1. 使用索引優(yōu)化:慢查詢通常是由于缺乏或不正確使用索引導(dǎo)致的。通過分析慢查詢的執(zhí)行計劃,確定應(yīng)該創(chuàng)建哪些索引來加速查詢??梢允褂?EXPLAINEXPLAIN ANALYZE 命令來查看查詢的執(zhí)行計劃,并使用 CREATE INDEX 命令創(chuàng)建適當?shù)乃饕?/p>

  2. 優(yōu)化查詢語句:優(yōu)化查詢語句的編寫可以顯著提升查詢性能。避免使用全表掃描和不必要的連接操作,盡量簡化查詢條件,并使用合適的查詢語句,如使用 INNER JOIN 替代 WHERE 子句中的子查詢。

  3. - 確保編寫高效的 SQL 查詢語句,避免不必要的查詢、使用 `SELECT *`、多余的子查詢等。
    - 盡量避免在 WHERE 子句中對字段進行函數(shù)操作,會影響索引的使用。
    - 使用合適的 JOIN 操作,避免笛卡爾積(Cartesian Product)和不必要的連接。
    - 限制返回結(jié)果集的大小,避免一次性獲取過多數(shù)據(jù)。

  4. 調(diào)整服務(wù)器參數(shù):通過適當設(shè)置 MySQL 服務(wù)器的參數(shù),可以提升數(shù)據(jù)庫的性能。例如,增加緩沖區(qū)大小(如 innodb_buffer_pool_size)、優(yōu)化查詢緩存(如 query_cache_size)和調(diào)整并發(fā)連接數(shù)等。

  5. 切分大表:如果查詢的表非常大,可以考慮將大表切分為更小的表,在查詢時只查詢所需的分片表,可以減輕單個查詢的負載,提高查詢速度。

  6. 定期優(yōu)化和維護數(shù)據(jù)庫:定期對數(shù)據(jù)庫進行優(yōu)化和維護可以提升整體性能。包括定期進行表優(yōu)化、碎片整理、數(shù)據(jù)歸檔和備份等操作,以確保數(shù)據(jù)庫的健康狀態(tài)。

  7. 監(jiān)控和記錄慢查詢:及時發(fā)現(xiàn)和記錄慢查詢是優(yōu)化的起點。通過開啟慢查詢?nèi)罩?#xff08;slow query log)來記錄慢查詢語句,然后根據(jù)日志分析找出消耗時間較長的查詢,優(yōu)化這些查詢可以提高整體性能。

  8. 使用緩存:對于一些頻繁查詢的數(shù)據(jù),可以考慮使用緩存技術(shù),如使用 Redis、Memcached 等緩存服務(wù)器緩存查詢結(jié)果,減少對數(shù)據(jù)庫的訪問次數(shù),提高響應(yīng)速度。

  9. 使用數(shù)據(jù)庫連接池:使用數(shù)據(jù)庫連接池可以減少數(shù)據(jù)庫連接的開銷,提高并發(fā)性能。連接池會管理數(shù)據(jù)庫連接的獲取和釋放,合理配置連接池參數(shù)可以提高數(shù)據(jù)庫的性能和穩(wěn)定性。

通過以上方法,可以逐步優(yōu)化和改進數(shù)據(jù)庫的慢查詢問題,提升數(shù)據(jù)庫的性能和響應(yīng)速度。需要根據(jù)具體的業(yè)務(wù)場景和數(shù)據(jù)庫配置來選擇和調(diào)整優(yōu)化策略。

ACID是靠什么保證的?

原子性由undolog日志來保證,它記錄了需要回滾的日志信息,事務(wù)回滾時撤銷已經(jīng)執(zhí)行成功的sql

一致性是由其他三大特性保證,程序代碼要保證業(yè)務(wù)上的一致性

隔離性是由MVCC來保證

持久性由redolog來保證,mysql修改數(shù)據(jù)的時候會在redolog中記錄一份日志數(shù)據(jù),就算數(shù)據(jù)沒有保存成功,只要日志保存成功了,數(shù)據(jù)仍然不會丟失

什么是MVCC?

1、MVCC

MVCC,全稱Multi-Version Concurrency Control,即多版本并發(fā)控制。MVCC是一種并發(fā)控制的方法,一般在數(shù)據(jù)庫管理系統(tǒng)中,實現(xiàn)對數(shù)據(jù)庫的并發(fā)訪問,在編程語言中實現(xiàn)事務(wù)內(nèi)存。

    MVCC在MySQL InnoDB中的實現(xiàn)主要是為了提高數(shù)據(jù)庫并發(fā)性能,用更好的方式去處理讀寫沖突,做到即使有讀寫沖突時,也能做到不加鎖,非阻塞并發(fā)讀。

2、當前讀

像select lock in share mode(共享鎖), select for update ; update, insert ,delete(排他鎖)這些操作都是一種當前讀,為什么叫當前讀?就是它讀取的是記錄的最新版本,讀取時還要保證其他并發(fā)事務(wù)不能修改當前記錄,會對讀取的記錄進行加鎖。

3、快照讀(提高數(shù)據(jù)庫的并發(fā)查詢能力)

像不加鎖的select操作就是快照讀,即不加鎖的非阻塞讀;快照讀的前提是隔離級別不是串行級別,串行級別下的快照讀會退化成當前讀;之所以出現(xiàn)快照讀的情況,是基于提高并發(fā)性能的考慮,快照讀的實現(xiàn)是基于多版本并發(fā)控制,即MVCC,可以認為MVCC是行鎖的一個變種,但它在很多情況下,避免了加鎖操作,降低了開銷;既然是基于多版本,即快照讀可能讀到的并不一定是數(shù)據(jù)的最新版本,而有可能是之前的歷史版本

4、當前讀、快照讀、MVCC關(guān)系

MVCC多版本并發(fā)控制指的是維持一個數(shù)據(jù)的多個版本,使得讀寫操作沒有沖突,快照讀是MySQL為實現(xiàn)MVCC的一個非阻塞讀功能。MVCC模塊在MySQL中的具體實現(xiàn)是由三個隱式字段,undo日志、read view三個組件來實現(xiàn)的。

MVCC解決的問題是什么?

數(shù)據(jù)庫并發(fā)場景有三種,分別為:

1、讀讀:不存在任何問題,也不需要并發(fā)控制

2、讀寫:有線程安全問題,可能會造成事務(wù)隔離性問題,可能遇到臟讀、幻讀、不可重復(fù)讀

3、寫寫:有線程安全問題,可能存在更新丟失問題

MVCC是一種用來解決讀寫沖突的無鎖并發(fā)控制,也就是為事務(wù)分配單項增長的時間戳,為每個修改保存一個版本,版本與事務(wù)時間戳關(guān)聯(lián),讀操作只讀該事務(wù)開始前的數(shù)據(jù)庫的快照,所以MVCC可以為數(shù)據(jù)庫解決一下問題:

1、在并發(fā)讀寫數(shù)據(jù)庫時,可以做到在讀操作時不用阻塞寫操作,寫操作也不用阻塞讀操作,提高了數(shù)據(jù)庫并發(fā)讀寫的性能

2、解決臟讀、幻讀、不可重復(fù)讀等事務(wù)隔離問題,但是不能解決更新丟失問題

MVCC實現(xiàn)原理是什么?

MVCC(Multi-Version Concurrency Control)是一種數(shù)據(jù)庫并發(fā)控制技術(shù),常用于實現(xiàn)事務(wù)的隔離性,保證事務(wù)之間的并發(fā)執(zhí)行。MVCC 的實現(xiàn)原理主要通過版本控制來實現(xiàn)多個事務(wù)并發(fā)執(zhí)行而不會相互影響,常見于像 MySQL、PostgreSQL 等數(shù)據(jù)庫系統(tǒng)中。

### MVCC 的實現(xiàn)原理如下:

1. **版本控制:** 每次對數(shù)據(jù)庫的數(shù)據(jù)進行更新時,并不直接修改原始數(shù)據(jù),而是創(chuàng)建新的版本(或稱為快照)來保存被修改的數(shù)據(jù)。這樣,每個事務(wù)在讀取數(shù)據(jù)時,都會讀取到一個版本的數(shù)據(jù),而不會受到其他事務(wù)同時修改數(shù)據(jù)的影響。

2. **事務(wù)版本號:** 每個事務(wù)有一個唯一的事務(wù)版本號,用來標識該事務(wù)可以讀取的數(shù)據(jù)版本。事務(wù)在讀取數(shù)據(jù)時,會根據(jù)自己的事務(wù)版本號來確定所讀取數(shù)據(jù)的版本,從而實現(xiàn)事務(wù)之間的隔離性。

3. **數(shù)據(jù)行的版本信息:** 每行數(shù)據(jù)都會包含版本信息,通常有兩種方式來實現(xiàn):
? ?- 一種是在數(shù)據(jù)行中添加版本號字段,用來記錄數(shù)據(jù)的版本信息;
? ?- 另一種是使用時間戳,記錄數(shù)據(jù)被修改的時間。

4. **讀取版本判斷:** 當事務(wù)讀取數(shù)據(jù)時,系統(tǒng)會根據(jù)事務(wù)的版本號和數(shù)據(jù)的版本信息來判斷是否可以讀取該數(shù)據(jù),一般有以下幾種情況:
? ?- 如果數(shù)據(jù)的版本號在事務(wù)開始之前,則可以讀取;
? ?- 如果數(shù)據(jù)的版本號在事務(wù)開始之后,但是數(shù)據(jù)的更新事務(wù)未提交,則根據(jù)事務(wù)隔離級別確定是否可以讀取。

5. **寫操作處理:** 當事務(wù)對數(shù)據(jù)進行更新時,系統(tǒng)會創(chuàng)建一個新的版本來保存修改后的數(shù)據(jù),同時保留原始數(shù)據(jù)的版本。其他事務(wù)在讀取數(shù)據(jù)時,可以根據(jù)版本控制機制來讀取到合適的數(shù)據(jù)版本。

通過 MVCC 技術(shù),數(shù)據(jù)庫系統(tǒng)可以實現(xiàn)高并發(fā)性和事務(wù)隔離性,同時保證數(shù)據(jù)的一致性。不同的數(shù)據(jù)庫系統(tǒng)可能會有不同的實現(xiàn)細節(jié),但 MVCC 的核心思想是基于版本控制來實現(xiàn)并發(fā)控制。

RC(讀提交內(nèi)容)、RR(可重復(fù)讀)級別下的InnoDB快照讀有什么不同

因為Read View生成時機的不同,從而造成RC、RR級別下快照讀的結(jié)果的不同

1、在RR級別下的某個事務(wù)的對某條記錄的第一次快照讀會創(chuàng)建一個快照即Read View,將當前系統(tǒng)活躍的其他事務(wù)記錄起來,此后在調(diào)用快照讀的時候,還是使用的是同一個Read View,所以只要當前事務(wù)在其他事務(wù)提交更新之前使用過快照讀,那么之后的快照讀使用的都是同一個Read View,所以對之后的修改不可見

2、在RR級別下,快照讀生成Read View時,Read View會記錄此時所有其他活動和事務(wù)的快照,這些事務(wù)的修改對于當前事務(wù)都是不可見的,而早于Read View創(chuàng)建的事務(wù)所做的修改均是可見

3、在RC級別下,事務(wù)中,每次快照讀都會新生成一個快照和Read View,這就是我們在RC級別下的事務(wù)中可以看到別的事務(wù)提交的更新的原因。

總結(jié):在RC隔離級別下,是每個快照讀都會生成并獲取最新的Read View,而在RR隔離級別下,則是同一個事務(wù)中的第一個快照讀才會創(chuàng)建Read View,之后的快照讀獲取的都是同一個Read View.

什么是mysql的主從復(fù)制?

MySQL 主從復(fù)制是指數(shù)據(jù)可以從一個MySQL數(shù)據(jù)庫服務(wù)器主節(jié)點復(fù)制到一個或多個從節(jié)點。MySQL 默認采用異步復(fù)制方式,這樣從節(jié)點不用一直訪問主服務(wù)器來更新自己的數(shù)據(jù),數(shù)據(jù)的更新可以在遠程連接上進行,從節(jié)點可以復(fù)制主數(shù)據(jù)庫中的所有數(shù)據(jù)庫或者特定的數(shù)據(jù)庫,或者特定的表。

mysql為什么需要主從同步?

1、在業(yè)務(wù)復(fù)雜的系統(tǒng)中,有這么一個情景,有一句sql語句需要鎖表,導(dǎo)致暫時不能使用讀的服務(wù),那么就很影響運行中的業(yè)務(wù),使用主從復(fù)制,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現(xiàn)了鎖表的情景,通過讀從庫也可以保證業(yè)務(wù)的正常運作。

2、做數(shù)據(jù)的熱備

3、架構(gòu)的擴展。業(yè)務(wù)量越來越大,I/O訪問頻率過高,單機無法滿足,此時做多庫的存儲,降低磁盤I/O訪問的頻率,提高單個機器的I/O性能。

mysql復(fù)制原理是什么?

(1)master服務(wù)器將數(shù)據(jù)的改變記錄二進制binlog日志,當master上的數(shù)據(jù)發(fā)生改變時,則將其改變寫入二進制日志中;

(2)slave服務(wù)器會在一定時間間隔內(nèi)對master二進制日志進行探測其是否發(fā)生改變,如果發(fā)生改變,則開始一個I/OThread請求master二進制事件

(3)同時主節(jié)點為每個I/O線程啟動一個dump線程,用于向其發(fā)送二進制事件,并保存至從節(jié)點本地的中繼日志中,從節(jié)點將啟動SQL線程從中繼日志中讀取二進制日志,在本地重放,使得其數(shù)據(jù)和主節(jié)點的保持一致,最后I/OThread和SQLThread將進入睡眠狀態(tài),等待下一次被喚醒。

也就是說:

  • 從庫會生成兩個線程,一個I/O線程,一個SQL線程;

  • I/O線程會去請求主庫的binlog,并將得到的binlog寫到本地的relay-log(中繼日志)文件中;

  • 主庫會生成一個log dump線程,用來給從庫I/O線程傳binlog;

  • SQL線程,會讀取relay log文件中的日志,并解析成sql語句逐一執(zhí)行;

注意:

1--master將操作語句記錄到binlog日志中,然后授予slave遠程連接的權(quán)限(master一定要開啟binlog二進制日志功能;通常為了數(shù)據(jù)安全考慮,slave也開啟binlog功能)

。 2--slave開啟兩個線程:IO線程和SQL線程。其中:IO線程負責讀取master的binlog內(nèi)容到中繼日志relay log里;SQL線程負責從relay log日志里讀出binlog內(nèi)容,并更新到slave的數(shù)據(jù)庫里,這樣就能保證slave數(shù)據(jù)和master數(shù)據(jù)保持一致了。

3--Mysql復(fù)制至少需要兩個Mysql的服務(wù),當然Mysql服務(wù)可以分布在不同的服務(wù)器上,也可以在一臺服務(wù)器上啟動多個服務(wù)。

4--Mysql復(fù)制最好確保master和slave服務(wù)器上的Mysql版本相同(如果不能滿足版本一致,那么要保證master主節(jié)點的版本低于slave從節(jié)點的版本) 5--master和slave兩節(jié)點間時間需同步

具體步驟:

1、從庫通過手工執(zhí)行change master to 語句連接主庫,提供了連接的用戶一切條件(user 、password、port、ip),并且讓從庫知道,二進制日志的起點位置(file名 position 號); start slave

2、從庫的IO線程和主庫的dump線程建立連接。

3、從庫根據(jù)change master to 語句提供的file名和position號,IO線程向主庫發(fā)起binlog的請求。

4、主庫dump線程根據(jù)從庫的請求,將本地binlog以events的方式發(fā)給從庫IO線程。

5、從庫IO線程接收binlog events,并存放到本地relay-log中,傳送過來的信息,會記錄到master.info中

6、從庫SQL線程應(yīng)用relay-log,并且把應(yīng)用過的記錄到relay-log.info中,默認情況下,已經(jīng)應(yīng)用過的relay 會自動被清理purge

簡述Myisam和Innodb的區(qū)別?

MyISAM和InnoDB是MySQL數(shù)據(jù)庫中常見的兩種存儲引擎,它們在性能、功能和特性上有一些區(qū)別。以下是它們的主要區(qū)別:

  1. 事務(wù)支持: MyISAM不支持事務(wù),而InnoDB支持事務(wù)。事務(wù)是一系列數(shù)據(jù)庫操作的邏輯單元,可以保證數(shù)據(jù)的一致性和完整性。對于需要嚴格事務(wù)支持的應(yīng)用,如高并發(fā)的OLTP(聯(lián)機事務(wù)處理)系統(tǒng),InnoDB更加適合。

  2. 并發(fā)控制: MyISAM使用表級鎖定,即當一個線程對表執(zhí)行寫操作時,其他線程無法對該表進行寫操作,但可以進行讀操作。而InnoDB使用行級鎖定,允許并發(fā)事務(wù)讀寫不同的行,提供更好的并發(fā)性能。

  3. 數(shù)據(jù)完整性: MyISAM不提供外鍵約束,也不支持事務(wù)的回滾和崩潰恢復(fù)功能。而InnoDB支持外鍵約束,可以保證數(shù)據(jù)的一致性和完整性,并提供了崩潰恢復(fù)和回滾機制。

  4. 索引類型: MyISAM只支持表級鎖定,對于大量的讀操作和少量的寫操作性能較好。InnoDB使用B+樹索引,支持行級鎖定,對于大量的讀寫操作性能較好。

  5. 崩潰恢復(fù): MyISAM在崩潰后需要執(zhí)行修復(fù)操作來恢復(fù)數(shù)據(jù)一致性,修復(fù)過程相對較慢。而InnoDB通過事務(wù)的日志和redolog來實現(xiàn)快速崩潰恢復(fù)。

總的來說,MyISAM對于讀操作較多的應(yīng)用場景和小型網(wǎng)站更適合,而InnoDB適用于需要事務(wù)支持、并發(fā)性要求高以及數(shù)據(jù)完整性的應(yīng)用,特別是對于大型的OLTP系統(tǒng)。在選擇存儲引擎時,需要根據(jù)應(yīng)用的特點和需求進行綜合考慮。

InnoDB存儲引擎: 主要面向OLTP(Online Transaction Processing,在線事務(wù)處理)方面的應(yīng)用,是第一個完整支持ACID事務(wù)的存儲引擎(BDB第一個支持事務(wù)的存儲引擎,已經(jīng)停止開發(fā))。 特點:

1 支持行鎖 2 支持外鍵 3 支持自動增加列AUTO_INCREMENT屬性 4 支持事務(wù) 5 支持MVCC模式的讀寫 6 讀的效率低于MYISAM 7.寫的效率高優(yōu)于MYISAM 8.適合頻繁修改以及設(shè)計到安全性較高的應(yīng)用 9.清空整個表的時候,Innodb是一行一行的刪除,

MyISAM存儲引擎: 是MySQL官方提供的存儲引擎,主要面向OLAP(Online Analytical Processing,在線分析處理)方面的應(yīng)用。

特點:

1 獨立于操作系統(tǒng),當建立一個MyISAM存儲引擎的表時,就會在本地磁盤建立三個文件,例如我建立tb_demo表,那么會生成以下三個文件tb_demo.frm,tb_demo.MYD,tb_demo.MYI 2 不支持事務(wù), 3 支持表鎖和全文索引 4 MyISAM存儲引擎表由MYD和MYI組成,MYD用來存放數(shù)據(jù)文件,MYI用來存放索引文件。MySQL數(shù)據(jù)庫只緩存其索引文件,數(shù)據(jù)文件的緩存交給操作系統(tǒng)本身來完成; 5 MySQL5.0版本開始,MyISAM默認支持256T的單表數(shù)據(jù); 6.選擇密集型的表:MYISAM存儲引擎在篩選大量數(shù)據(jù)時非常迅速,這是他最突出的優(yōu)點 7.讀的效率優(yōu)于InnoDB 8.寫的效率低于InnoDB 9.適合查詢以及插入為主的應(yīng)用 10.清空整個表的時候,MYISAM則會新建表

簡述mysql中索引類型有哪些,以及對數(shù)據(jù)庫的性能的影響?

普通索引:允許被索引的數(shù)據(jù)列包含重復(fù)的值

唯一索引:可以保證數(shù)據(jù)記錄的唯一性

主鍵索引:是一種特殊的唯一索引,在一張表中只能定義一個主鍵索引,主鍵用于唯一標識一條記錄,使用關(guān)鍵字primary key來創(chuàng)建

聯(lián)合索引:索引可以覆蓋多個數(shù)據(jù)列

全文索引:通過建立倒排索引,可以極大的提升檢索效率,解決判斷字段是否包含的問題,是目前搜索引擎使用的一種關(guān)鍵技術(shù)

索引可以極大地提高數(shù)據(jù)的查詢速度

通過使用索引,可以在查詢的過程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能

但是會降低插入、刪除、更新表的速度,因為在執(zhí)行這些寫操作的時候,還要操作索引文件

索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個索引還要占一定的物理空間,如果要簡歷聚簇索引,那么需要的空間就會更大,如果非聚簇索引很多,一旦聚簇索引改變,那么所有非聚簇索引都會跟著變

mysql聚簇和非聚簇索引的區(qū)別

都是B+樹的數(shù)據(jù)結(jié)構(gòu) 聚簇索引:將數(shù)據(jù)存儲與索引放到了一塊、并且是按照一定的順序組織的,找到索引也就找到了數(shù) 據(jù),數(shù)據(jù)的物理存放順序與索引順序是一致的,即:只要索引是相鄰的,那么對應(yīng)的數(shù)據(jù)一定也是 相鄰地存放在磁盤上的 非聚簇索引:葉子節(jié)點不存儲數(shù)據(jù)、存儲的是數(shù)據(jù)行地址,也就是說根據(jù)索引查找到數(shù)據(jù)行的位置 再取磁盤查找數(shù)據(jù),這個就有點類似一本樹的目錄,比如我們要找第三章第一節(jié),那我們先在這個 目錄里面找,找到對應(yīng)的頁碼后再去對應(yīng)的頁碼看文章。

http://m.risenshineclean.com/news/65863.html

相關(guān)文章:

  • 城關(guān)區(qū)建設(shè)局網(wǎng)站自媒體營銷方式有哪些
  • 西安做網(wǎng)站優(yōu)化教育培訓(xùn)機構(gòu)十大排名
  • 網(wǎng)展企業(yè)網(wǎng)站系統(tǒng) 免費沈陽網(wǎng)站推廣優(yōu)化
  • 濟源做網(wǎng)站公司bt螞蟻磁力搜索天堂
  • 學院網(wǎng)站建設(shè)工作總結(jié)網(wǎng)絡(luò)銷售是做什么的
  • 企業(yè)網(wǎng)站建設(shè)多長時間seo網(wǎng)站推廣專員招聘
  • 商務(wù)部網(wǎng)站建設(shè)情況匯報360搜索引擎推廣
  • 網(wǎng)站建設(shè)受眾軟文營銷案例分析
  • 商務(wù)網(wǎng)站開發(fā)設(shè)計搜什么關(guān)鍵詞能搜到好片
  • wordpress如何修改評論北京seo網(wǎng)站優(yōu)化培訓(xùn)
  • 東莞做網(wǎng)站優(yōu)化哪家好app開發(fā)自學教程
  • 福州市建設(shè)廳網(wǎng)站谷歌搜索指數(shù)查詢
  • 怎么做免費網(wǎng)站如何讓百度收錄資源最全的網(wǎng)盤搜索引擎
  • 國內(nèi)網(wǎng)站建設(shè)費用聯(lián)盟谷粉搜索谷歌搜索
  • 網(wǎng)站的表單關(guān)鍵字優(yōu)化用什么系統(tǒng)
  • 宣城市網(wǎng)站建設(shè)平臺推廣營銷
  • 網(wǎng)站開發(fā)工程師應(yīng)聘書范文1000有沒有永久免費crm
  • wordpress文章批量編輯器官網(wǎng)seo是什么意思
  • 門網(wǎng)站制作百度一下首頁登錄入口
  • 單位做網(wǎng)站需要準備什么女教師遭網(wǎng)課入侵直播錄屏曝光i
  • 能看的網(wǎng)站給我一個唄免費推客推廣平臺
  • python做流量網(wǎng)站分析網(wǎng)站
  • c語言做項目網(wǎng)站百度關(guān)鍵詞挖掘查詢工具
  • 小女孩做網(wǎng)站勞動局免費培訓(xùn)電工
  • 網(wǎng)站建設(shè)需要注意哪些問題商務(wù)軟文寫作
  • 網(wǎng)站怎么做有創(chuàng)意搜索引擎營銷策略有哪些
  • 鎮(zhèn)江唐唐網(wǎng)絡(luò)科技有限公司老鬼seo
  • 網(wǎng)站用圖怎么做文件小質(zhì)量高推廣自己產(chǎn)品的文案
  • 柳市最好的網(wǎng)站建設(shè)公司拉新推廣怎么做代理
  • 某市政府信息網(wǎng)站建設(shè)方案廈門人才網(wǎng)最新招聘信息網(wǎng)