首页 > 问答 > 关键词  > MySQL最新资讯  > 正文

为什么MySQL默认隔离级别是RR

2020-07-02 11:35 · 稿源:数据库干货铺

曾多次听到“MySQL为什么选择RR为默认隔离级别”的问题,其实这是个历史遗留问题,当前以及解决,但是MySQL的各个版本沿用了原有习惯。历史版本中的问题是什么,本次就通过简单的测试来说明一下。

1、 准备工作

1.1 部署主从

部署一套主从架构的集群,创建过程较简单,可以参考历史文章部署MySQL主从复制搭建部署一主一从即可。

1.2 创建测试表及数据

在主库中创建表及测试数据

mysql>createtableusers(idintprimarykeyauto_increment,user_namevarchar(20),c_idtinyint(4),c_notevarchar(50),keyc_id(c_id))engine=innodb;
QueryOK,0rowsaffected(0.01sec)
mysql>insertintousersvalues(1,'刘备',2,null),(2,'曹操',1,null),(3,'孙权',3,null),(4,'关羽',2,null),(5,'司马懿',1,null);
QueryOK,5rowsaffected(0.00sec)
Records:5Duplicates:0Warnings:0mysql>createtableclass(c_idintprimarykey,c_namevarchar(1),c_notevarchar(50))engine=innodb;
QueryOK,0rowsaffected(0.00sec)
mysql>insertintoclassvalues(1,'魏',null),(2,'蜀',null),(3,'吴',null),(4,'晋','');
QueryOK,4rowsaffected(0.00sec)
Records:4Duplicates:0Warnings:0

2、 RR隔离级别

MySQL默认的隔离级别为 RR(Repeatable Read),在此隔离级别下,对比binlog格式为ROW、STATEMENT是否会造成主从数据不一致

2.1 ROW格式

其实不用测试大家也应该对RR级别下ROW格式的binlog有信心,但是,万事皆需实践检验。

步骤说明如下:

  • 步骤1 - 分别查看两个会话中的事务隔离级别及binlog格式(隔离级别均为RR,binlog为ROW格式)
  • 步骤2 - SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 5 条记录均更新,并将c_note内容更新为 t1
  • 步骤3- SESSION B 开启事务,准备删除class表中 c_id等于 2 的记录,此时无法更新,处于阻塞状态,因为在RR级别下需要保证重复读。达到所等待超时时间后将会报错。
  • 步骤4- SESSION A 提交事务(此步骤也可以在步骤 3 时操作,结果不一样,后续步骤中将采用此方式)
  • 步骤5- SESSION B 重启事务,再次删除class表中 c_id等于 2 的记录,此时提交可以成功了,成功删除了一条记录
  • 步骤6- SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 3 条记录更新成功,并将c_note内容更新为 t2,有 2 条记录因为c_id不存在与class表中,因此不会更新
  • 步骤7- 分别在SESSON A和SESSION B查看users表中的内容,结果一致
  • 步骤8- 在从库查看users表中的内容,数据与主库一致

具体步骤如下:

步骤SESSION A

SESSION B

1

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.00 sec)

mysql>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.00 sec)

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.00 sec)

mysql>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.01 sec)

2

mysql>set autocommit=0;

mysql>update users set c_note='t1' where c_id in (select c_id from class);

Query OK, 5 rows affected (0.00 sec)

Rows matched: 5 Changed: 5 Warnings: 0

3

mysql>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql>delete from class where c_id=2;

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

4

mysql>commit;

Query OK, 0 rows affected (0.00 sec)

5

mysql>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

mysql>delete from class where c_id=2;

Query OK, 1 row affected (0.00 sec)

mysql>commit;

Query OK, 0 rows affected (0.00 sec)

6

mysql>update users set c_note='t2' where c_id in (select c_id from class);

Query OK, 3 rows affected (0.00 sec)

Rows matched: 3 Changed: 3 Warnings: 0

mysql>commit;

Query OK, 0 rows affected (0.00 sec)

7

mysql>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

mysql>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

8

在从库查看数据

root@testdb:3307 12:02:20>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

2.2 STATEMENT格式

为了和之前的步骤一致,先初始化数据

root@testdb:330612:14:27>truncatetableusers;
QueryOK,0rowsaffected(0.08sec)
root@testdb:330612:14:29>truncatetableclass;
QueryOK,0rowsaffected(0.04sec)
root@testdb:330612:14:50>insertintousersvalues(1,'刘备',2,null),(2,'曹操',1,null),(3,'孙权',3,null),(4,'关羽',2,null),(5,'司马懿',1,null);
QueryOK,5rowsaffected(0.00sec)
Records:5Duplicates:0Warnings:0root@testdb:330612:15:10>insertintoclassvalues(1,'魏',null),(2,'蜀',null),(3,'吴',null),(4,'晋','');
QueryOK,4rowsaffected(0.00sec)
Records:4Duplicates:0Warnings:0

再将binlog日志格式改为STATAMENT格式(全局及会话级都改一下,或者修改全局变量后重新登录也行,当然 只改会话级别的也可以测试),然后 再次进行测试。

步骤说明如下:

  • 步骤1 - 分别查看两个会话中的事务隔离级别及binlog格式(隔离级别均为RR,binlog为STATENENT格式)
  • 步骤2 - SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 5 条记录均更新,并将c_note内容更新为 t1
  • 步骤3- SESSION B 开启事务,准备删除class表中 c_id等于 2 的记录,此时无法更新,处于阻塞状态,立即进行步骤4
  • 步骤4- SESSION A 在SESSION B执行commit的动作,则SESSION B的删除操作可以执行通过,但注意class表的数据两个SESSION中查看到的是不一样的
  • 步骤5- 此时SESSION B执行commit,否则后面session A 更新数据时也会阻塞。此时如果SESSION A不执行commit,查看class表的结果也是不一样的,如步骤中的情况
  • 步骤6- SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 3 条记录更新成功,并将c_note内容更新为 t2,另外 2 条记录虽然本此时查看class表中存在对应的c_id,但是不会更新,此时提交事务,然后再次查看class的内容,结果和SESSION B 查看的结果一致了(幻读)
  • 步骤7- 在从库查看users、class表中的内容,数据与主库一致
步 骤SESSION ASESSION B
1

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.01 sec)

mysql>show variables like '%binlog_format%';

+---------------+-----------+

| Variable_name | Value |

+---------------+-----------+

| binlog_format | STATEMENT |

+---------------+-----------+

1 row in set (0.01 sec)

mysql>show variables like '%iso%';

+-----------------------+-----------------+

| Variable_name | Value |

+-----------------------+-----------------+

| transaction_isolation | REPEATABLE-READ |

| tx_isolation | REPEATABLE-READ |

+-----------------------+-----------------+

2 rows in set (0.01 sec)

mysql>show variables like '%binlog_format%';

+---------------+-----------+

| Variable_name | Value |

+---------------+-----------+

| binlog_format | STATEMENT |

+---------------+-----------+

1 row in set (0.01 sec)

2

root@testdb:3306 12:37:04>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:37:17>update users set c_note='t1' where c_id in (select c_id from class);

Query OK, 5 rows affected, 1 warning (0.00 sec)

Rows matched: 5 Changed: 5 Warnings: 1

3

root@testdb:3306 12:28:25>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:38:06>delete from class where c_id=2;

Query OK, 1 row affected (4.74 sec)

4

root@testdb:3306 12:38:09>commit;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:38:13>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t1 |

| 3 | 孙 权 | 3 | t1 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t1 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3306 12:39:07>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 2 | 蜀 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

4 rows in set (0.00 sec)

5

root@testdb:3306 12:38:13>commit;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:39:56>select * from class ;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

6

root@testdb:3306 12:52:23>update users set c_note='t2' where c_id in (select c_id from class);

Query OK, 3 rows affected, 1 warning (0.00 sec)

Rows matched: 3 Changed: 3 Warnings: 1

root@testdb:3306 12:52:45>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 2 | 蜀 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

4 rows in set (0.00 sec)

root@testdb:3306 12:52:49>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.01 sec)

root@testdb:3306 12:53:03>commit;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 12:53:06>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3306 12:53:11>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

7

查看从库数据

root@testdb:3307 12:44:22>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.01 sec)

root@testdb:3307 12:57:07>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

也就是此时主从结果也是一致的,原因在于,binlog里存储的语句顺序如下:

binlog里的顺序语句内容
1

update users set c_note='t1' where c_id in (select c_id from class);

2delete from class where c_id=2;
3update users set c_note='t2' where c_id in (select c_id from class);

与主库执行的顺序是一致的,因此,主从的结果是一致的。

3、 RC隔离级别

3.1 ROW格式

为了和之前的步骤一致,先初始化数据

root@testdb:330612:14:27>truncatetableusers;
QueryOK,0rowsaffected(0.08sec)
root@testdb:330612:14:29>truncatetableclass;
QueryOK,0rowsaffected(0.04sec)
root@testdb:330612:14:50>insertintousersvalues(1,'刘备',2,null),(2,'曹操',1,null),(3,'孙权',3,null),(4,'关羽',2,null),(5,'司马懿',1,null);
QueryOK,5rowsaffected(0.00sec)
Records:5Duplicates:0Warnings:0root@testdb:330612:15:10>insertintoclassvalues(1,'魏',null),(2,'蜀',null),(3,'吴',null),(4,'晋','');
QueryOK,4rowsaffected(0.00sec)
Records:4Duplicates:0Warnings:0

再将binlog日志格式改为STATAMENT格式(全局及会话级都改一下,或者修改全局变量后重新登录也行,当然 只改会话级别的也可以测试),然后 再次进行测试。

步骤说明如下:

  • 步骤1 - 分别查看两个会话中的事务隔离级别及binlog格式(隔离级别均为RC,binlog为ROW格式)
  • 步骤2 - SESSION A 开启事务,更新users 表中c_id字段存在于class表中的记录,结果为 5 条记录均更新,并将c_note内容更新为 t1
  • 步骤3- SESSION B 开启事务,准备删除class表中 c_id等于 2 的记录,此时不会像RR事务隔离级别那样处于阻塞状态,而是可以直接执行通过
  • 步骤4- 此时SESSION A查看class数据还是删除前的,因为session B 暂未提交
  • 步骤5- SESSION B 提交事务,
  • 步骤6- 更新users 表中c_id字段存在于class表中的记录,结果为 3 条记录更新成功,并将c_note内容更新为 t2
  • 步骤7- 在从库查看users、class表中的内容,数据与主库一致
步 骤SESSION ASESSION B
1

root@testdb:3306 01:25:24>show variables like '%iso%';

+-----------------------+----------------+

| Variable_name | Value |

+-----------------------+----------------+

| transaction_isolation | READ-COMMITTED |

| tx_isolation | READ-COMMITTED |

+-----------------------+----------------+

2 rows in set (0.01 sec)

root@testdb:3306 01:25:36>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.01 sec)

root@testdb:3306 01:24:57>show variables like '%iso%';

+-----------------------+----------------+

| Variable_name | Value |

+-----------------------+----------------+

| transaction_isolation | READ-COMMITTED |

| tx_isolation | READ-COMMITTED |

+-----------------------+----------------+

2 rows in set (0.01 sec)

root@testdb:3306 01:25:39>show variables like '%binlog_format%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| binlog_format | ROW |

+---------------+-------+

1 row in set (0.00 sec)

2

root@testdb:3306 01:27:55>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 01:28:27>update users set c_note='t1' where c_id in (select c_id from class);

Query OK, 5 rows affected (0.00 sec)

Rows matched: 5 Changed: 5 Warnings: 0

3

root@testdb:3306 01:26:07>set autocommit=0;

Query OK, 0 rows affected (0.00 sec)

root@testdb:3306 01:28:37>delete from class where c_id=2;

Query OK, 1 row affected (0.00 sec)

4

root@testdb:3306 01:28:27>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 2 | 蜀 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

4 rows in set (0.00 sec)

5

root@testdb:3306 01:28:41>commit;

Query OK, 0 rows affected (0.00 sec)

6

root@testdb:3306 01:28:59>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.01 sec)

root@testdb:3306 01:29:13>update users set c_note='t2' where c_id in (select c_id from class);

Query OK, 3 rows affected (0.00 sec)

Rows matched: 3 Changed: 3 Warnings: 0

root@testdb:3306 01:29:26>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

root@testdb:3306 01:29:31>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3306 01:29:38>commit;

7

查看从库数据

root@testdb:3307 01:40:32>select * from users;

+----+-----------+------+--------+

| id | user_name | c_id | c_note |

+----+-----------+------+--------+

| 1 | 刘备 | 2 | t1 |

| 2 | 曹操 | 1 | t2 |

| 3 | 孙 权 | 3 | t2 |

| 4 | 关羽 | 2 | t1 |

| 5 | 司马懿 | 1 | t2 |

+----+-----------+------+--------+

5 rows in set (0.00 sec)

root@testdb:3307 01:40:35>select * from class;

+------+--------+--------+

| c_id | c_name | c_note |

+------+--------+--------+

| 1 | 魏 | NULL |

| 3 | 吴 | NULL |

| 4 | 晋 | |

+------+--------+--------+

3 rows in set (0.00 sec)

也就是此时主从结果也是一致的。

3.2 STATEMENT格式

因为当前版本已经不支持RC+STATEMENT组合下数据的操作,否则将报如下错误:

Cannotexecutestatement:impossibletowritetobinarylogsinceBINLOG_FORMAT=STATEMENTandatleastonetableusesastorageenginelimitedtorow-basedlogging.InnoDBislimitedtorow-loggingwhentransactionisolationlevelisREADCOMMITTEDorREADUNCOMMITTED.

因此单纯根据步骤讲解

步骤SESSION ASESSION B
1

mysql>set autocommit=0;

mysql>update users set c_note='t1' where c_id in (select c_id from class);

2

mysql>set autocommit=0;

mysql>delete from class where c_id=2;

mysql>commit;

3mysql>update users set c_note='t2' where c_id in (select c_id from class);
4commit;

因为binlog是按照commit时间的顺序保存,因此上述步骤在binlog里会以如下顺序存储:

binlog里的顺序语句内容
1

delete from class where c_id=2;

2update users set c_note='t1' where c_id in (select c_id from class);
3update users set c_note='t2' where c_id in (select c_id from class);

从库通过binlog应用后,最终的结果将导致主库的数据不一样(具体案例后续安装低版本后演示)。

因而,此种场景下很容易导致数据不一样。

4、总结

通过上述的实践,可以发现在RR级别下,binlog为任何格式均不会造成主从数据不一致的情况出现,但是当低版本MySQL使用RC+STATEMENT组合时(MySQL5.1. 5 前只有statement格式)将会导致主从数据不一致。当前这个历史遗漏问题以及解决,大家可以将其设置为RC+ROW组合的方式(例如ORACLE等数据库隔离级别就是RC),而不是必须使用RR(会带来更多的锁等待),具体可以视情况选择。

本文转载自微信公众号【数据库干货铺】。

举报

  • 相关推荐
  • 大家在看
  • EasyMedia:AI驱动,快速将YouTube视频转化为社交媒体内容。

    EasyMedia是一个利用人工智能技术,帮助用户将YouTube视频内容快速转化为适合不同社交媒体平台的帖子、推文等。它支持Facebook、Instagram、Twitter、LinkedIn等多个平台,能够根据平台特点自动调整内容格式,提高内容的吸引力和传播力。产品背景在于帮助用户节省内容创作时间,同时增加其在数字世界中的影响力。

  • Kuluko:将想法变成有声书

    Kuluko是一款AI驱动的有声书生成器,它允许用户通过简单的提示或个性化的设置来创作属于自己的有声书。它提供了两种模式:简易模式和高级模式,以满足不同用户的需求。简易模式下,用户只需输入一个提示,AI即可生成完整的小说。高级模式则允许用户自定义故事的各个方面,包括角色、类型、背景、故事时间、叙述者声音等。Kuluko将故事转化为长达4小时的有声书,用户可以立即开始收听。此外,Kuluko还具有个人和公共图书馆功能,用户可以选择私密享受或与他人分享。

  • fastn:无代码AI驱动的集成平台

    fastn是一个无代码、AI驱动的集成平台,旨在帮助开发者通过单一、统一的API连接和编排多个数据源。它通过AI代理创建API,支持即时API组合,无需编码即可实现数据流的连接。fastn的主要优点包括降低成本、加速开发和上市时间、提高可靠性和安全性。它通过实时数据编排、统一数据访问和监控与故障排除等功能,帮助企业构建互联生态系统。

  • Wasps:AI代码审查工具,快速理解代码库并修复问题。

    Wasps是一个集成在VSCode中的AI代码审查插件,通过深度分析和理解代码库,能够快速识别并修复代码中的错误和漏洞。它为开发者提供即时反馈,推荐潜在问题和改进建议,帮助提高代码质量和开发效率。

  • LLM Optimize:专业网站审计,提升AI推荐排名

    LLM Optimize 是一套工具,旨在帮助用户优化网站,使其在AI聊天机器人和生成引擎(如ChatGPT和Google的AI Overview)中排名更高。该工具通过专业的网站审计,提供可操作的建议,帮助用户在这些生成引擎中获得更好的展示效果。其重要性在于,随着AI技术的不断发展,传统的SEO策略正在逐渐被LLM(Large Language Models,大型语言模型)优化所取代。LLM Optimize通过分析网站内容和竞争对手的策略,提供定制化的优化方案,帮助用户在AI驱动的搜索结果中获得更高的曝光率。

  • Meme Search:通过文本搜索快速找到完美表情包

    Meme Search是一款通过视觉内容和文本索引表情包的应用程序,它能够让用户通过文本搜索快速找到所需的表情包。该应用使用自然语言处理技术,将图片中的文本描述自动生成并作为向量索引存储,从而实现快速检索。Meme Search的开源特性和创新的搜索方式,使其成为提升表情包搜索效率的有力工具。

  • PDFJourney:快速且经济的PDF创建方式

    PDFJourney 是一个旨在为用户提供快速且经济的PDF创建服务的网站。它通过简化用户界面和操作流程,使得用户能够轻松地创建PDF文件。该产品的主要优点在于其高效的渲染速度和低廉的成本,这对于需要频繁处理文档的用户来说是一个巨大的优势。PDFJourney 是 GPT4 的微调版本,它致力于通过技术手段降低文档处理的复杂性和成本,从而提升用户的工作效率。

  • AnyParser:准确、私密且可配置的文档检索LLM

    AnyParser Playground 是一个基于网页的解决方案,旨在帮助用户从PDF和图像文件中提取信息。它通过使用机器学习技术,能够处理文件的前10页,为用户提供数据的全面洞察。该平台不存储用户数据,保证了数据的隐私和安全性。

  • Reimagic.ai:将照片转化为非凡肖像的革命性应用

    Reimagic.ai是一款革命性的移动应用程序,可以将您的照片转化为非凡的肖像。它具备即时背景转换、无缝融合、多样化使用场景、用户友好界面等功能,适用于人像、宠物和产品摄影,使每张快照都成为杰作。

  • Xspiral:新一代3D可视化设计平台,让创意触手可及。

    Xspiral是一个结合了2D和3D设计的混合平台,通过AI技术增强,提供实时渲染、无需下载、协作功能。它允许用户快速创建、设计、管理、预览、分享和发布3D作品。Xspiral支持使用智能写作功能,如一键重写、总结、扩展和快速思维导图,以及创建和管理交互式3D工作流应用,包括文档、思维导图、流程图等。它还支持在3D空间中进行UI/UX设计,为初学者和专业人士提供了轻松创建3D设计的可能。

  • 如果相机:用AI帮你看见各种「如果」背后自己可能的样子

    如果相机是一款利用人工智能技术,帮助用户探索不同生活选择下自己可能的样子的网站。通过AI技术,用户可以体验到不同的生活方式、外貌变化等,从而发现更多的可能性。该产品的主要优点在于其创新性和趣味性,能够激发用户的想象力和探索欲。

  • Relingo:智能双语翻译,助力词汇记忆

    Relingo是一款专注于提升用户英语词汇记忆能力的教育类APP。它通过在用户阅读和观看视频时自动高亮生词并提供翻译,帮助用户在感兴趣的内容中轻松积累单词。产品支持多种语言,包括中文、英文、日文等,覆盖了全文翻译、视频双语字幕、PDF阅读等多种场景,使用户在沉浸式翻译中提升语言能力。

  • AI Photo Filter:AI滤镜,一键转换照片风格

    AI Photo Filter是一个在线服务,使用人工智能技术将用户上传的照片转换成多种艺术风格,如动漫、粘土、3D、像素艺术等。它适用于初学者和专业人士,只需简单点击即可使用。该技术的主要优点包括操作简便、风格多样、效果生动,能够满足不同用户对照片美化和创意表达的需求。

  • ideaShell:AI语音思维笔记,捕捉灵感,提升行动力。

    ideaShell是一款结合人工智能技术的语音思维笔记应用,旨在帮助用户通过语音快速捕捉灵感和想法,并通过AI技术进行反思和行动规划。它通过自动组织、格式化、添加标签和标题,帮助用户将想法转化为行动,同时支持将草稿导入到其他应用程序如Notion、Craft、Docs和Reminder中进行最终创作和后续行动。

  • 无忧智慧公文:智能公文辅助系统,提升办公效率。

    无忧智慧公文是专为政府机关、大型央企、国企办公人员定制的办公辅助系统,依托大数据、人工智能(AI)与自然语言处理技术(NLP),提供辅助写作、智能审核和智能排版功能,帮助用户安全、智能、高效地完成公文工作。

  • 无忧智能审核系统:依托AI与NLP的文本自动查错与智能纠错系统。

    无忧智能审核系统是一款基于大数据、人工智能(AI)和自然语言处理技术(NLP)的文本自动查错与智能纠错系统。它通过深度学习能够全面校对多种文本错误类型,有效提升人工检校效率,消除审校盲区,提升内容安全和文本质量。系统支持多种部署方式,包括嵌入版、整站审核和接口版,能够满足不同行业和场景的需求。

  • MacOS Agent:MacOS的简化助手

    MacOS Agent 是一个基于大型语言模型(LLM)的简单、轻量级解决方案,利用Dify这个AI应用开发平台。该助手使用户,甚至儿童,能够通过自然语言命令轻松控制MacOS,就像与技术专家交谈一样简单。它不仅类似于Siri,还通过支持多轮对话增强了功能,允许用户在任务中保持上下文和连续性。例如,你可以要求助手提供一些文本,然后请求它将该文本转换为Excel或Word文件。

  • Vercel AI SDK:构建AI驱动产品的开发工具包

    Vercel AI SDK是由Next.js的创造者推出的工具包,旨在帮助开发者构建AI驱动的产品。它提供了统一的API来访问多个AI提供商,支持生成音乐播放器、动态生成用户界面等。该SDK兼容多种框架,如React、Next、Vue等,能够通过Vercel Functions提供即时反馈。

  • DeepSeek-V2-Chat-0628:一款先进的对话生成模型

    DeepSeek-V2-Chat-0628 是 DeepSeek-V2 系列的改进版本,专为对话生成任务设计。它在 LMSYS Chatbot Arena Leaderboard 上表现出色,整体排名第11,特别是在编程任务和挑战性提示中表现出色。该模型在多个评估指标上均有显著提升,如 HumanEval、MATH、BBH、IFEval 和 Arena-Hard 等。此外,其在“系统”领域的指令遵循能力也经过优化,显著提升了用户体验。

  • Goldfish:视频理解的先进模型

    Goldfish 是一种为理解任意长度视频而设计的方法论。它通过高效的检索机制,首先收集与指令相关的前k个视频片段,然后提供所需的响应。这种设计使得Goldfish能够有效处理任意长的视频序列,适用于电影或电视剧等场景。为了促进检索过程,开发了MiniGPT4-Video,该模型为视频片段生成详细的描述。Goldfish在长视频基准测试中取得了41.78%的准确率,超过了之前的方法14.94%。此外,MiniGPT4-Video在短视频理解中也表现出色,分别在MSVD、MSRVTT、TGIF和TVQA短视频基准测试中超过了现有最佳方法3.23%、2.03%、16.5%和23.59%。这些结果表明,Goldfish模型在长视频和短视频理解方面都有显著改进。

今日大家都在搜的词:

热文

  • 3 天
  • 7天