概念杂记--到底啥是啥?(数据库篇)

1.聚集索引(clustered index)

聚集索引(Clustered Index)是数据库中一种常见的索引类型,它定义了表中数据的物理存储顺序。在聚集索引中,数据行按照索引键的顺序进行排序,并且表中的数据实际上是按照聚集索引的顺序存储的。
以下是聚集索引的一些特点和定义要点:

  • 1、数据行的物理存储顺序:聚集索引决定了表中数据行的物理存储顺序,这意味着具有相邻索引键的行在物理上也是相邻存储的。
  • 2、主键索引通常是聚集索引:在大多数关系型数据库管理系统(RDBMS)中,默认的主键索引就是聚集索引。如果表没有显式定义主键,则某些数据库系统可能会选择一个唯一索引作为聚集索引。
  • 3、数据访问的效率:由于聚集索引中的数据行按照索引键的顺序存储,因此对于使用索引键进行查找或范围查询的操作,聚集索引可以提供较高的查询效率。
  • 4、表只能有一个聚集索引:每个表只能有一个聚集索引,这是因为数据行只能按照一种方式进行排序和存储)

2.非聚集索引(Non-clustered index)

非聚集索引(Non-clustered Index)是数据库中另一种常见的索引类型,与聚集索引相对。与聚集索引不同,非聚集索引的索引键值不决定数据行的物理存储顺序。相反,它们创建一个独立的数据结构,其中包含索引键和指向实际数据行的指针。
以下是非聚集索引的一些定义要点:

  • 1、数据行的物理存储顺序:与聚集索引不同,非聚集索引并不决定数据行的物理存储顺序。它们仅提供了一个独立的数据结构,用于快速查找索引键。
  • 2、索引键和指针:非聚集索引由索引键和指向实际数据行的指针组成。索引键是用于快速定位和排序的值,而指针指向数据行的物理位置。
  • 3、 多个非聚集索引:对于一个表,可以创建多个非聚集索引,每个非聚集索引都可以基于不同的列或列组合。
  • 4、查询效率:非聚集索引可以提供快速的查询效率,特别是当查询需要检索特定列或进行范围查询时,非聚集索引可以减少数据访问的成本。
  • 5、更新和维护开销:与聚集索引相比,非聚集索引在数据更新和插入操作时的开销较小。然而,对于频繁的更新操作,维护多个非聚集索引可能会导致一定的性能影响。

3.聚集索引和非聚集索引区别?

非聚集索引和聚集索引在数据库中具有以下区别:

  • 1、物理排序顺序:聚集索引决定了表中数据行的物理存储顺序,而非聚集索引没有这个作用。聚集索引的数据行按照索引键的顺序进行排序,并且表中的数据实际上是按照聚集索引的顺序存储的。非聚集索引则是创建一个独立的数据结构,其中包含索引键和指向实际数据行的指针。
  • 2、数据访问方式:使用聚集索引进行查询时,数据库可以直接按照索引的顺序快速访问数据行。而非聚集索引则需要通过索引键值查找到对应的指针,然后再根据指针找到实际的数据行。因此,聚集索引通常可以提供更快的数据访问速度。
  • 3、存储方式:聚集索引决定了数据行的物理存储方式,因此一个表只能有一个聚集索引。而非聚集索引则是独立于数据行的存储结构,一个表可以有多个非聚集索引。
  • 4、更新开销:对于聚集索引,当数据行发生更新操作时,可能需要重新排序和移动数据行的位置,这可能导致额外的开销。而非聚集索引的更新开销相对较小,因为它们不影响实际数据行的物理存储顺序。
  • 5、主键索引:在大多数关系型数据库管理系统(RDBMS)中,默认的主键索引通常是聚集索引。如果表没有显式定义主键,则某些数据库系统可能会选择一个唯一索引作为聚集索引。

综上所述,非聚集索引和聚集索引在数据的物理存储方式数据访问方式更新开销等方面存在明显的区别。在设计和选择索引时,需要考虑具体的查询需求、数据访问模式和更新频率,以确定使用哪种索引类型或它们的组合来优化数据库的性能。

4.覆盖索引(covering index)

覆盖索引(Covering Index)是一种特殊的索引,它包含了查询涉及的所有列,而不仅仅是索引列本身。通过创建覆盖索引,查询可以直接从索引中获取所需的数据,而无需回到原始数据行,从而提高查询性能。
以下是覆盖索引的一些要点:

  • 1、包含索引列以及查询涉及的其他列:覆盖索引包含了查询所需的所有列,包括索引列以及查询涉及的其他列。这样,查询可以直接从索引中获取所需的数据,而无需访问原始数据行。
  • 2、减少访问磁盘的次数:通过使用覆盖索引,数据库可以减少访问磁盘的次数。因为覆盖索引包含了查询所需的所有列,所以数据库可以直接从索引中读取数据,而不需要额外的磁盘访问来获取缺失的列。
  • 3、提高查询性能:由于覆盖索引可以减少磁盘访问次数,从而提高查询的性能。这对于复杂的查询或需要访问大量数据的查询尤为重要。
  • 4、空间和维护开销:覆盖索引需要占用更多的存储空间,因为它包含了更多的列。此外,由于覆盖索引需要维护额外的列,因此在数据更新时可能会增加一些维护开销。
  • 5、选择适当的列和查询:为了获得最大的性能收益,选择适当的列和查询来创建覆盖索引非常重要。覆盖索引在某些查询模式和特定的列选择上可能更加有效。

需要注意的是,并非所有的查询都适合使用覆盖索引。在设计和创建覆盖索引时,需要综合考虑查询的性能需求、查询模式、数据访问模式以及索引的空间和维护开销。

简单来说就是索引中包含索要需要查询的内容,这样可以直接从索引中获取数据,而不需要回表查询。但是这样势必会造成额外的空间和维护开销。

5.复合索引 (Composite Index)

复合索引(Composite Index)是由多个列组成的索引,它可以涵盖多个列的查询条件。复合索引允许在一个索引中定义多个列的组合,以便在查询中同时利用这些列进行索引扫描和匹配。

复合索引的特点和使用包括以下几个方面:

    1. 列的顺序:复合索引中的列可以按照特定的顺序进行定义。通常,将最常用于查询条件的列放在索引的最左侧,以便最大程度地利用索引进行查询优化。查询中涉及的列可以是复合索引的一部分,而不需要涉及所有列。
    1. 查询优化:复合索引可以提供更精确的查询性能,特别是当查询需要根据多个列进行过滤或排序时。通过使用复合索引,数据库引擎可以更准确地定位满足查询条件的数据行,减少不必要的扫描和比较操作,从而提高查询效率。
    1. 索引覆盖:当复合索引涵盖了查询所需的所有列时,称之为索引覆盖(Index Covering)。索引覆盖可以进一步提高查询性能,因为查询可以完全从索引中获取所需的数据,无需访问原始数据行。
    1. 设计考虑:在设计复合索引时,需要综合考虑查询模式、数据访问模式和列的选择。选择适当的列和顺序可以提高查询性能,但过多或不必要的列可能会增加索引的大小和维护成本。

6.索引最左匹配原则

索引最左匹配原则(Index Leftmost Prefix Rule)是指在使用复合索引(Composite Index)时,索引的左侧列将优先用于查询条件的匹配。当查询中使用了复合索引的一部分列作为查询条件时,数据库引擎可以利用这个索引来加速查询,但只能从最左侧的列开始进行匹配。
以下是索引最左匹配原则的一些要点:

    1. 复合索引:复合索引是由多个列组成的索引,它可以涵盖多个列的查询条件。例如,一个复合索引可以是 (col1, col2, col3)。
    1. 最左匹配:索引最左匹配原则意味着在查询时,只有从索引的最左侧列开始连续匹配,才能利用复合索引进行加速。换句话说,查询条件中的列必须是复合索引中最左侧的列,才能使查询受益于索引。
    1. 匹配顺序:如果查询条件中同时使用了复合索引的多个列,但不是从最左侧列开始,那么索引可能无法有效利用,查询性能可能会下降。因此,在设计查询条件时,应优先考虑使用最左侧列。
    1. 索引覆盖:当查询中的列与复合索引的所有列完全匹配时,称之为索引覆盖(Index Covering)。索引覆盖可以进一步提高查询性能,因为查询可以完全从索引中获取所需的数据,无需访问原始数据行。

需要注意的是,索引最左匹配原则只适用于复合索引,对于单列索引没有影响。在设计复合索引时,应根据查询模式、数据访问模式和列的选择来决定索引的顺序,以最大程度地利用索引并提高查询性能。

7. 幻读

幻读指的是在一个事务中执行了一次查询,然后又执行了相同的查询,但在第二次查询中却返回了不同的结果集,因为在两次查询之间有其他事务对数据进行了插入或删除操作。

幻读的产生原因是使用了范围锁(Range Lock)或间隙锁(Gap Lock)的并发控制机制。当一个事务执行查询时,数据库系统会对查询的范围或间隙进行锁定,以防止其他事务对这些数据进行插入或删除操作。但是,当另一个事务在这个范围或间隙内插入新的数据时,原来的事务再次执行相同的查询时,会看到新插入的数据,导致幻读的发生。

为了解决幻读的问题,数据库系统提供了多种并发控制机制,如锁机制、多版本并发控制(MVCC)、快照隔离级别等。其中,使用锁机制可以通过更严格的锁定策略,如行级锁或表级锁,来避免幻读的发生。而使用 MVCC 或快照隔离级别则通过记录数据的历史版本或快照来实现读一致性,从而避免了幻读的问题。

总之,幻读是并发控制中的一个问题,指在一个事务中多次执行相同的查询,但在不同的查询之间看到了不同的数据行。为了解决幻读问题,数据库系统提供了多种并发控制机制来保证读一致性和数据的正确性。

7.1 锁机制如何防止幻读?

锁机制可以通过使用更严格的锁定策略来防止幻读。在防止幻读的过程中,主要使用的是行级锁或间隙锁。

    1. 行级锁(Row-Level Locking):
      行级锁是在事务对某一行数据进行读或写操作时,对该行数据进行的锁定。在防止幻读时,当一个事务对某一行数据进行读操作时,它会获取该行的共享锁(Shared Lock),防止其他事务对该行进行写操作。这样,其他事务就无法插入或删除与该行相关的数据,从而避免了幻读的发生。
    1. 间隙锁(Gap Lock):
      间隙锁是在事务对某一范围或间隙进行查询时,对该范围或间隙进行的锁定。在防止幻读时,当一个事务对某一范围或间隙进行查询时,它会获取该范围或间隙的间隙锁,阻止其他事务在该范围或间隙内进行插入操作。这样,其他事务就无法插入新的数据行,从而避免了幻读的发生。

通过使用行级锁和间隙锁,数据库系统可以防止幻读的发生。当一个事务执行查询操作时,它会对查询的数据行或范围进行锁定,以防止其他事务对这些数据行进行插入或删除操作。这样,无论其他事务如何修改数据,原始事务在执行后续的查询操作时,都能够看到一致的数据行,避免了幻读的问题。

需要注意的是,锁机制可以解决幻读问题,但也会引入锁竞争和性能开销。因此,在使用锁机制时,需要根据具体的应用场景和并发访问需求进行权衡和调整,以达到合理的并发性和性能表现。

7.2 多版本并发控制如何防止幻读?

多版本并发控制(MVCC,Multi-Version Concurrency Control)是一种并发控制机制,通过记录数据的历史版本来实现读一致性和避免幻读的问题。

在 MVCC 中,每个事务在开始时会获得一个事务 ID,事务执行期间,它只能看到在其开始之前已经提交的数据版本。当一个事务执行查询时,数据库系统会根据事务的 ID 来确定所能看到的数据版本,从而保证读取的数据是一致的。

MVCC 通过为每个数据行维护多个版本来实现并发控制和避免幻读。具体来说,每个数据行都会有一个或多个历史版本,每个版本都包含了该数据行在某个事务提交时的数据快照。当一个事务开始时,它只能看到在该事务开始之前已经提交的数据版本。这样,即使其他事务在该事务执行期间对数据进行了修改或插入操作,该事务仍然可以看到一致的数据版本,避免了幻读的问题。

MVCC 的实现方式可以有多种策略,其中一种常见的方式是使用版本号(Version Number)或时间戳(Timestamp)来标识数据版本。每个数据行的版本都会有一个唯一的版本号或时间戳,事务的开始时间也会有一个对应的版本号或时间戳。通过比较事务的开始时间和数据版本的版本号或时间戳,数据库系统可以确定每个事务能够看到的数据版本范围,从而保证读一致性和避免幻读。

需要注意的是,MVCC 可能会引入一些额外的存储开销,因为每个数据行需要维护多个历史版本。此外,MVCC 在实际应用中的实现方式可能有所差异,具体取决于数据库系统的设计和实现。

总之,多版本并发控制(MVCC)通过记录数据的历史版本来实现读一致性和避免幻读的问题。每个事务只能看到在其开始之前已经提交的数据版本,从而保证了读取的数据是一致的。MVCC 是一种常见且有效的并发控制机制,在许多数据库系统中得到了广泛应用。

7.3 快照隔离级别如何防止幻读?

快照隔离级别(Snapshot Isolation Level)是数据库事务隔离级别的一种,它通过使用数据库的快照(Snapshot)来实现读一致性和防止幻读。

在快照隔离级别下,每个事务在开始时会创建一个自己的数据库快照,该快照是事务开始时数据库中所有数据的一个静态副本。在事务执行期间,事务只能看到其开始时的快照中的数据,并且对其他事务提交的修改是不可见的。这样,即使其他事务在事务执行期间对数据进行了修改或插入操作,该事务仍然可以看到一致的数据,从而避免了幻读。

快照隔离级别的实现方式可以有多种策略,其中一种常见的方式是使用多版本并发控制(MVCC)机制。在这种情况下,事务开始时会创建一个快照,快照中包含了事务开始时数据库中所有数据的一个静态副本,每个数据行也会有多个历史版本。在事务执行期间,事务只能看到其开始时的快照中的数据版本,其他事务提交的修改对其是不可见的。这样,即使其他事务在事务执行期间对数据进行了修改或插入操作,该事务仍然可以看到一致的数据版本,避免了幻读。

需要注意的是,快照隔离级别可以提供读一致性,但对于写操作来说,可能存在冲突和并发控制的问题。因此,在使用快照隔离级别时,需要考虑并发控制机制,如锁机制、乐观并发控制(Optimistic Concurrency Control)等,来处理写操作的冲突和保证数据的正确性。

总之,快照隔离级别通过使用事务开始时的数据库快照来实现读一致性和防止幻读。每个事务只能看到其开始时的快照中的数据,对其他事务提交的修改是不可见的。快照隔离级别是一种常见的事务隔离级别,它在实现读一致性和避免幻读方面具有一定的优势。

8.脏读

脏读(Dirty Read)是指在并发环境下,一个事务读取了另一个事务尚未提交的数据。这意味着事务在读取到的数据可能是临时的、未经验证的或者最终无效的。

脏读可能会导致数据不一致性和错误的结果。当一个事务读取到另一个事务未提交的数据时,如果这个事务最终回滚或者修改了数据,那么读取到的数据就是无效的,从而导致了脏读。

脏读的发生通常是因为在某个事务中进行了写操作(修改或删除),但是这个事务还没有提交,而另一个事务在此时读取了这个未提交的数据。这种情况下,读取到的数据可能并不是数据库中的最新数据,也可能是不一致的。

为了避免脏读,数据库系统通常采用了事务隔离级别的概念。事务隔离级别规定了事务之间的可见性和并发访问的规则。通常,数据库提供了多个事务隔离级别,如读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。

在较高的隔离级别下,如可重复读或串行化,数据库系统会使用锁机制或多版本并发控制(MVCC)来防止脏读的发生。这样,一个事务只能读取到另一个事务已经提交的数据,而不会读取到未提交的数据。但是,较高的隔离级别可能会引入额外的性能开销,因此在实际应用中需要根据具体情况进行权衡。

总之,脏读是并发环境下的一个问题,指的是一个事务读取到另一个事务尚未提交的数据。为了避免脏读,可以使用事务隔离级别和并发控制机制来确保数据的一致性和正确性。

9.事物隔离级别

9.1 读未提交 (Read Uncommitted)

读未提交(Read Uncommitted)是数据库事务的最低隔离级别之一,也被称为“脏读”级别。在读未提交隔离级别下,事务可以读取其他事务尚未提交的数据,可能会导致脏读问题。

在读未提交隔离级别下,事务不会对数据行进行任何锁定或并发控制,所以其他事务对数据的修改会立即对当前事务可见。这意味着一个事务可以读取到其他事务尚未提交的数据,甚至读取到其他事务已经修改或删除的数据。

读未提交隔离级别的特点是允许事务读取到其他事务未提交的数据,这样可以获得更高的并发性能,但同时也会带来一些问题。脏读是读未提交隔离级别的主要问题,因为读取到的数据可能是不一致的、临时的或无效的。如果其他事务在当前事务读取数据的同时对数据进行了修改或删除操作,那么当前事务读取到的数据可能是无效的。

9.2 读已提交 (Read Committed)

读已提交(Read Committed)是数据库事务的一种隔离级别,它提供了较好的读取一致性,避免了脏读问题。在读已提交隔离级别下,事务只能读取到已经提交的数据,而不能读取到其他事务尚未提交的数据。
在读已提交隔离级别下,当一个事务读取数据时,其他事务对该数据的修改是不可见的,直到修改事务提交。这保证了事务读取的数据是一致的、已经通过验证的数据。

为了实现读已提交隔离级别,数据库系统通常使用锁机制或者多版本并发控制(MVCC)。在读已提交隔离级别下,当一个事务读取数据时,数据库会为被读取的数据行加上共享锁(Read Lock),以阻止其他事务对该数据行进行修改。这样,其他事务只能等待读取事务释放共享锁后才能对该数据行进行修改,保证了数据的一致性。

读已提交隔离级别通常是许多数据库系统的默认隔离级别,它提供了较好的读取一致性,避免了脏读的问题。但是,读已提交隔离级别仍然可能发生不可重复读和幻读的问题。不可重复读是指同一个事务在不同时间点多次读取同一数据时,得到不同的结果。幻读是指在同一个事务内多次查询时,得到不同的结果,因为其他事务在查询期间插入了新的数据。

为了解决不可重复读和幻读问题,可以使用更高级别的隔离级别,如可重复读(Repeatable Read)或串行化(Serializable)。这些隔离级别通过更严格的并发控制机制来保证数据的一致性和可靠性,但可能会牺牲一定的并发性能。

9.3 可重复读 (Repeatable Read)

可重复读(Repeatable Read)是数据库事务的隔离级别之一,它提供了更高的隔离性,确保在事务执行期间读取的数据保持一致,即使其他事务对数据进行了修改。

在可重复读隔离级别下,一个事务在开始时创建了一个事务快照(Transaction Snapshot),该快照包含了事务开始时数据库中所有数据的一个静态副本。在事务执行期间,该事务只能看到其开始时的快照中的数据,并且对其他事务提交的修改是不可见的。

具体来说,可重复读隔离级别通过使用锁机制和多版本并发控制(MVCC)来实现数据的一致性和避免脏读、不可重复读和幻读等问题。在可重复读隔离级别下,当一个事务读取数据时,数据库会为被读取的数据行加上共享锁(Read Lock),防止其他事务对该数据行进行修改。这样,其他事务只能等待该事务释放共享锁后才能对该数据行进行修改,从而保证了数据的一致性。

另外,可重复读隔离级别还使用了多版本并发控制(MVCC)机制,为每个数据行维护多个历史版本,使得在事务执行期间,读取的数据都是一致的。其他事务在该事务执行期间对数据进行的修改不会对该事务的读取结果产生影响。

需要注意的是,在可重复读隔离级别下,其他事务对数据的修改是不可见的,但是该事务对自己进行的修改是可见的。因此,即使其他事务对数据进行了修改,该事务在执行期间读取到的数据仍然保持一致。

总之,可重复读是数据库事务的一种隔离级别,它通过事务快照、锁机制和多版本并发控制来实现数据的一致性和避免脏读、不可重复读和幻读等问题。在可重复读隔离级别下,事务读取的数据保持一致,即使其他事务对数据进行了修改。

9.4 序列化 (Serializable)

串行化(Serializable)是数据库事务的最高隔离级别,也是最严格的隔离级别之一。在串行化隔离级别下,事务按照顺序一个接一个地执行,相当于将并发执行的事务串行化执行,确保了最高的数据一致性和可靠性。

在串行化隔离级别下,每个事务在读取和修改数据时会对相应的数据行加上排他锁(Exclusive Lock),这个锁会阻塞其他事务对同一数据行的读取和修改操作,直到当前事务提交或回滚。这样,串行化隔离级别可以避免脏读、不可重复读和幻读等问题的发生,因为每个事务只能看到其他事务已经提交的数据。

串行化隔离级别提供了最高级别的数据一致性和可靠性,因为它完全保证了事务之间的隔离性。然而,串行化隔离级别也带来了一定的性能开销,因为它限制了并发执行的能力。由于只有一个事务可以同时执行,其他事务需要等待当前事务完成后才能执行,可能会导致性能下降。
在实际应用中,通常只有在对数据一致性要求极高的场景下才会使用串行化隔离级别。对于大部分应用来说,可重复读(Repeatable Read)或读已提交(Read Committed)等隔离级别已经能够提供足够的数据一致性和性能平衡。

总之,串行化是数据库事务的最高隔离级别,它保证了最高的数据一致性和可靠性。在串行化隔离级别下,事务按照顺序一个接一个地执行,相当于将并发执行的事务串行化执行。然而,串行化隔离级别也带来了性能开销,因为它限制了并发执行的能力。

10. 常见数据库事物隔离级别

常见数据库系统的默认事务隔离级别可以有所不同,以下是一些常见数据库系统的默认事务隔离级别:

    1. MySQL:MySQL的默认事务隔离级别是可重复读(Repeatable Read)。这意味着在同一个事务中,多次读取同一个数据会得到相同的结果,即使其他事务对该数据进行了修改。
    1. PostgreSQL:PostgreSQL的默认事务隔离级别也是可重复读(Repeatable Read)。它提供了读取一致性,并使用多版本并发控制(MVCC)来避免脏读、不可重复读和幻读等问题。
    1. Oracle:Oracle数据库的默认事务隔离级别是读已提交(Read Committed)。在读已提交隔离级别下,事务只能读取已经提交的数据,并且可以避免脏读问题。
    1. SQL Server:SQL Server的默认事务隔离级别也是读已提交(Read Committed)。它提供了读取一致性,并使用锁机制来确保数据的一致性。

需要注意的是,数据库系统的默认事务隔离级别可以在创建数据库或会话时进行配置,也可以通过修改数据库设置或事务隔离级别的语句来更改默认隔离级别。因此,实际使用中可能会根据具体需求进行调整。在开发应用时,建议明确指定所需的隔离级别,以确保数据的一致性和可靠性。

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值