MySQL的必须了解的知识

Kotlin原生AI Agent框架Koog:为JVM开发者打造类型安全、企业级智能体开发方案 AI Agent作为当前人工智能应用开发的核心范式,通过赋予大语言模型(LLM)自主规划、工具调用和环境交互能力,正在重塑软件智能化进程。其技术原理基于智能体架构,通过提示工程、函数调用和记忆机制,将LLM从单纯的文本生成器转变为能够执行复杂任务的工作流引擎。这一技术价值在于显著降低了构建智能应用的开发门槛,同时保持了高度的灵活性和可扩展性。在实际应用场景中,AI Agent广泛落地于智能客服、代码助手、数据分析自动化等领域,成为连接大模型能力与具体业务需求的关键桥梁。本文聚焦的Koog框架,正是针对JVM 阅读详情

本文来源于微信公众号 :程序员闪充宝,科技缪缪

首先谈一下规范MySQL的必要性

  1. 规范背景与目的
    MySQL数据库与 Oracle、 SQL Server 等数据库相比,有其内核上的优势与劣势。我们在使用MySQL数据库的时候需要遵循一定规范,扬长避短。本规范旨在帮助或指导RD、QA、OP等技术人员做出适合线上业务的数据库设计。在数据库变更和处理流程、数据库表设计、SQL编写等方面予以规范,从而为公司业务系统稳定、健康地运行提供保障。

  2. 设计规范
    2.1 数据库设计
    以下所有规范会按照【高危】、【强制】、【建议】三个级别进行标注,遵守优先级从高到低。

对于不满足【高危】和【强制】两个级别的设计,DBA会强制打回要求修改。

2.1.1 库名
【强制】库的名称必须控制在32个字符以内,相关模块的表名与表名之间尽量提现join的关系,如user表和user_login表。
【强制】库的名称格式:业务系统名称_子系统名,同一模块使用的表名尽量使用统一前缀。
【强制】一般分库名称命名格式是库通配名_编号,编号从0开始递增,比如wenda_001以时间进行分库的名称格式是“库通配名_时间”
【强制】创建数据库时必须显式指定字符集,并且字符集只能是utf8或者utf8mb4。创建数据库SQL举例:create database db1 default character set utf8;。
2.1.2 表结构
【强制】表和列的名称必须控制在32个字符以内,表名只能使用字母、数字和下划线,一律小写。
【强制】表名要求模块名强相关,如师资系统采用”sz”作为前缀,渠道系统采用”qd”作为前缀等。
【强制】创建表时必须显式指定字符集为utf8或utf8mb4。
【强制】创建表时必须显式指定表存储引擎类型,如无特殊需求,一律为InnoDB。当需要使用除InnoDB/MyISAM/Memory以外的存储引擎时,必须通过DBA审核才能在生产环境中使用。因为Innodb表支持事务、行锁、宕机恢复、MVCC等关系型数据库重要特性,为业界使用最多的MySQL存储引擎。而这是其他大多数存储引擎不具备的,因此首推InnoDB。
【强制】建表必须有comment
【建议】建表时关于主键:(1)强制要求主键为id,类型为int或bigint,且为auto_increment(2)标识表里每一行主体的字段不要设为主键,建议设为其他字段如user_id,order_id等,并建立unique key索引(可参考cdb.teacher表设计)。因为如果设为主键且主键值为随机插入,则会导致innodb内部page分裂和大量随机I/O,性能下降。
【建议】核心表(如用户表,金钱相关的表)必须有行数据的创建时间字段create_time和最后更新时间字段update_time,便于查问题。
【建议】表中所有字段必须都是NOT NULL属性,业务可以根据需要定义DEFAULT值。因为使用NULL值会存在每一行都会占用额外存储空间、数据迁移容易出错、聚合函数计算结果偏差等问题。
【建议】建议对表里的blob、text等大字段,垂直拆分到其他表里,仅在需要读这些对象的时候才去select。
【建议】反范式设计:把经常需要join查询的字段,在其他表里冗余一份。如user_name属性在user_account,user_login_log等表里冗余一份,减少join查询。
【强制】中间表用于保留中间结果集,名称必须以tmp_开头。备份表用于备份或抓取源表快照,名称必须以bak_开头。中间表和备份表定期清理。
【强制】对于超过100W行的大表进行alter table,必须经过DBA审核,并在业务低峰期执行。因为alter table会产生表锁,期间阻塞对于该表的所有写入,对于业务可能会产生极大影响。
2.1.3 列数据类型优化
【建议】表中的自增列(auto_increment属性),推荐使用bigint类型。因为无符号int存储范围为-2147483648~2147483647(大约21亿左右),溢出后会导致报错。
【建议】业务中选择性很少的状态status、类型type等字段推荐使用tinytint或者smallint类型节省存储空间。
【建议】业务中IP地址字段推荐使用int类型,不推荐用char(15)。因为int只占4字节,可以用如下函数相互转换,而char(15)占用至少15字节。一旦表数据行数到了1亿,那么要多用1.1G存储空间。SQL:select inet_aton(‘192.168.2.12’); select inet_ntoa(3232236044); PHP: ip2long(‘192.168.2.12’); long2ip(3530427185);
【建议】不推荐使用enum,set。因为它们浪费空间,且枚举值写死了,变更不方便。推荐使用tinyint或smallint。
【建议】不推荐使用blob,text等类型。它们都比较浪费硬盘和内存空间。在加载表数据时,会读取大字段到内存里从而浪费内存空间,影响系统性能。建议和PM、RD沟通,是否真的需要这么大字段。Innodb中当一行记录超过8098字节时,会将该记录中选取最长的一个字段将其768字节放在原始page里,该字段余下内容放在overflow-page里。不幸的是在compact行格式下,原始page和overflow-page都会加载。
【建议】存储金钱的字段,建议用int,程序端乘以100和除以100进行存取。因为int占用4字节,而double占用8字节,空间浪费。
【建议】文本数据尽量用varchar存储。因为varchar是变长存储,比char更省空间。MySQL server层规定一行所有文本最多存65535字节,因此在utf8字符集下最多存21844个字符,超过会自动转换为mediumtext字段。而text在utf8字符集下最多存21844个字符,mediumtext最多存224/3个字符,longtext最多存232个字符。一般建议用varchar类型,字符数不要超过2700。
【建议】时间类型尽量选取timestamp。因为datetime占用8字节,timestamp仅占用4字节,但是范围为1970-01-01 00:00:01到2038-01-01 00:00:00。更为高阶的方法,选用int来存储时间,使用SQL函数unix_timestamp()和from_unixtime()来进行转换。
2.1.4 索引设计
【强制】InnoDB表必须主键为id int/bigint auto_increment,且主键值禁止被更新。
【建议】主键的名称以“pk_”开头,唯一键以“uk_”或“uq_”开头,普通索引以“idx_”开头,一律使用小写格式,以表名/字段的名称或缩写作为后缀。
【强制】InnoDB和MyISAM存储引擎表,索引类型必须为BTREE;MEMORY表可以根据需要选择HASH或者BTREE类型索引。
【强制】单个索引中每个索引记录的长度不能超过64KB。
【建议】单个表上的索引个数不能超过7个。
【建议】在建立索引时,多考虑建立联合索引,并把区分度最高的字段放在最前面。如列userid的区分度可由select count(distinct userid)计算出来。
【建议】在多表join的SQL里,保证被驱动表的连接列上有索引,这样join执行效率最高。
【建议】建表或加索引时,保证表里互相不存在冗余索引。对于MySQL来说,如果表里已经存在key(a,b),则key(a)为冗余索引,需要删除。
2.1.5 分库分表、分区表
【强制】分区表的分区字段(partition-key)必须有索引,或者是组合索引的首列。
【强制】单个分区表中的分区(包括子分区)个数不能超过1024。
【强制】上线前RD或者DBA必须指定分区表的创建、清理策略。
【强制】访问分区表的SQL必须包含分区键。
【建议】单个分区文件不超过2G,总大小不超过50G。建议总分区数不超过20个。
【强制】对于分区表执行alter table操作,必须在业务低峰期执行。
【强制】采用分库策略的,库的数量不能超过1024
【强制】采用分表策略的,表的数量不能超过4096
【建议】单个分表不超过500W行,ibd文件大小不超过2G,这样才能让数据分布式变得性能更佳。
【建议】水平分表尽量用取模方式,日志、报表类数据建议采用日期进行分表。
2.1.6 字符集
【强制】数据库本身库、表、列所有字符集必须保持一致,为utf8或utf8mb4。
【强制】前端程序字符集或者环境变量中的字符集,与数据库、表的字符集必须一致,统一为utf8。
2.1.7 程序层DAO设计建议
【建议】新的代码不要用model,推荐使用手动拼SQL+绑定变量传入参数的方式。因为model虽然可以使用面向对象的方式操作db,但是其使用不当很容易造成生成的SQL非常复杂,且model层自己做的强制类型转换性能较差,最终导致数据库性能下降。
【建议】前端程序连接MySQL或者redis,必须要有连接超时和失败重连机制,且失败重试必须有间隔时间。
【建议】前端程序报错里尽量能够提示MySQL或redis原生态的报错信息,便于排查错误。
【建议】对于有连接池的前端程序,必须根据业务需要配置初始、最小、最大连接数,超时时间以及连接回收机制,否则会耗尽数据库连接资源,造成线上事故。
【建议】对于log或history类型的表,随时间增长容易越来越大,因此上线前RD或者DBA必须建立表数据清理或归档方案。
【建议】在应用程序设计阶段,RD必须考虑并规避数据库中主从延迟对于业务的影响。尽量避免从库短时延迟(20秒以内)对业务造成影响,建议强制一致性的读开启事务走主库,或更新后过一段时间再去读从库。
【建议】多个并发业务逻辑访问同一块数据(innodb表)时,会在数据库端产生行锁甚至表锁导致并发下降,因此建议更新类SQL尽量基于主键去更新。
【建议】业务逻辑之间加锁顺序尽量保持一致,否则会导致死锁。
【建议】对于单表读写比大于10:1的数据行或单个列,可以将热点数据放在缓存里(如mecache或redis),加快访问速度,降低MySQL压力。
2.1.8 一个规范的建表语句示例
一个较为规范的建表语句为:

CREATE TABLE user (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(11) NOT NULL COMMENT ‘用户id’
  `username` varchar(45) NOT NULL COMMENT '真实姓名',
  `email` varchar(30) NOT NULL COMMENT ‘用户邮箱’,
  `nickname` varchar(45) NOT NULL COMMENT '昵称',
  `avatar` int(11) NOT NULL COMMENT '头像',
  `birthday` date NOT NULL COMMENT '生日',
  `sex` tinyint(4) DEFAULT '0' COMMENT '性别',
  `short_introduce` varchar(150) DEFAULT NULL COMMENT '一句话介绍自己,最多50个汉字',
  `user_resume` varchar(300) NOT NULL COMMENT '用户提交的简历存放地址',
  `user_register_ip` int NOT NULL COMMENT ‘用户注册时的源ip’,
  `create_time` timestamp NOT NULL COMMENT ‘用户记录创建的时间’,
  `update_time` timestamp NOT NULL COMMENT ‘用户资料修改的时间’,
  `user_review_status` tinyint NOT NULL COMMENT ‘用户资料审核状态,1为通过,2为审核中,3为未通过,4为还未提交审核’,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_user_id` (`user_id`),
  KEY `idx_username`(`username`),
  KEY `idx_create_time`(`create_time`,`user_review_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='网站用户基本信息';

2.2 SQL编写
2.2.1 DML语句
【强制】SELECT语句必须指定具体字段名称,禁止写成*。因为select *会将不该读的数据也从MySQL里读出来,造成网卡压力。且表字段一旦更新,但model层没有来得及更新的话,系统会报错。
【强制】insert语句指定具体字段名称,不要写成insert into t1 values(…),道理同上。
【建议】insert into…values(XX),(XX),(XX)…。这里XX的值不要超过5000个。值过多虽然上线很很快,但会引起主从同步延迟。
【建议】SELECT语句不要使用UNION,推荐使用UNION ALL,并且UNION子句个数限制在5个以内。因为union all不需要去重,节省数据库资源,提高性能。
【建议】in值列表限制在500以内。例如select… where userid in(….500个以内…),这么做是为了减少底层扫描,减轻数据库压力从而加速查询。
【建议】事务里批量更新数据需要控制数量,进行必要的sleep,做到少量多次。
【强制】事务涉及的表必须全部是innodb表。否则一旦失败不会全部回滚,且易造成主从库同步终端。
【强制】写入和事务发往主库,只读SQL发往从库。
【强制】除静态表或小表(100行以内),DML语句必须有where条件,且使用索引查找。
【强制】生产环境禁止使用hint,如sql_no_cache,force index,ignore key,straight join等。因为hint是用来强制SQL按照某个执行计划来执行,但随着数据量变化我们无法保证自己当初的预判是正确的,因此我们要相信MySQL优化器!
【强制】where条件里等号左右字段类型必须一致,否则无法利用索引。
【建议】SELECT|UPDATE|DELETE|REPLACE要有WHERE子句,且WHERE子句的条件必需使用索引查找。
【强制】生产数据库中强烈不推荐大表上发生全表扫描,但对于100行以下的静态表可以全表扫描。查询数据量不要超过表行数的25%,否则不会利用索引。
【强制】WHERE 子句中禁止只使用全模糊的LIKE条件进行查找,必须有其他等值或范围查询条件,否则无法利用索引。
【建议】索引列不要使用函数或表达式,否则无法利用索引。如where length(name)='Admin’或where user_id+2=10023。
【建议】减少使用or语句,可将or语句优化为union,然后在各个where条件上建立索引。如where a=1 or b=2优化为where a=1… union …where b=2, key(a),key(b)。
【建议】分页查询,当limit起点较高时,可先用过滤条件进行过滤。如select a,b,c from t1 limit 10000,20;优化为: select a,b,c from t1 where id>10000 limit 20;。
2.2.2 多表连接
【强制】禁止跨db的join语句。因为这样可以减少模块间耦合,为数据库拆分奠定坚实基础。
【强制】禁止在业务的更新类SQL语句中使用join,比如update t1 join t2…。
【建议】不建议使用子查询,建议将子查询SQL拆开结合程序多次查询,或使用join来代替子查询。
【建议】线上环境,多表join不要超过3个表。
【建议】多表连接查询推荐使用别名,且SELECT列表中要用别名引用字段,数据库.表格式,如select a from db1.table1 alias1 where …。
【建议】在多表join中,尽量选取结果集较小的表作为驱动表,来join其他表。
2.2.3 事务
【建议】事务中INSERT|UPDATE|DELETE|REPLACE语句操作的行数控制在2000以内,以及WHERE子句中IN列表的传参个数控制在500以内。
【建议】批量操作数据时,需要控制事务处理间隔时间,进行必要的sleep,一般建议值5-10秒。
【建议】对于有auto_increment属性字段的表的插入操作,并发需要控制在200以内。
【强制】程序设计必须考虑“数据库事务隔离级别”带来的影响,包括脏读、不可重复读和幻读。线上建议事务隔离级别为repeatable-read。
【建议】事务里包含SQL不超过5个(支付业务除外)。因为过长的事务会导致锁数据较久,MySQL内部缓存、连接消耗过多等雪崩问题。
【建议】事务里更新语句尽量基于主键或unique key,如update … where id=XX; 否则会产生间隙锁,内部扩大锁定范围,导致系统性能下降,产生死锁。
【建议】尽量把一些典型外部调用移出事务,如调用webservice,访问文件存储等,从而避免事务过长。
【建议】对于MySQL主从延迟严格敏感的select语句,请开启事务强制访问主库。
2.2.4 排序和分组
【建议】减少使用order by,和业务沟通能不排序就不排序,或将排序放到程序端去做。order by、group by、distinct这些语句较为耗费CPU,数据库的CPU资源是极其宝贵的。
【建议】order by、group by、distinct这些SQL尽量利用索引直接检索出排序好的数据。如where a=1 order by可以利用key(a,b)。
【建议】包含了order by、group by、distinct这些查询的语句,where条件过滤出来的结果集请保持在1000行以内,否则SQL会很慢。
2.2.5 线上禁止使用的SQL语句
【高危】禁用update|delete t1 … where a=XX limit XX; 这种带limit的更新语句。因为会导致主从不一致,导致数据错乱。建议加上order by PK。
【高危】禁止使用关联子查询,如update t1 set … where name in(select name from user where…);效率极其低下。
【强制】禁用procedure、function、trigger、views、event、外键约束。因为他们消耗数据库资源,降低数据库实例可扩展性。推荐都在程序端实现。
【强制】禁用insert into …on duplicate key update…在高并发环境下,会造成主从不一致。
【强制】禁止联表更新语句,如update t1,t2 where t1.id=t2.id…。

MySQL的必知13点

  1. 能说下myisam 和 innodb的区别吗?
    myisam引擎是5.1版本之前的默认引擎,支持全文检索、压缩、空间函数等,但是不支持事务和行级锁,所以一般用于有大量查询少量插入的场景来使用,而且myisam不支持外键,并且索引和数据是分开存储的。
    innodb是基于聚簇索引建立的,和myisam相反它支持事务、外键,并且通过MVCC来支持高并发,索引和数据存储在一起。

  2. 说下mysql的索引有哪些吧,聚簇和非聚簇索引又是什么?在这里插入图片描述
    B+树是左小右大的顺序存储结构,节点只包含id索引列,而叶子节点包含索引列和数据,这种数据和索引在一起存储的索引方式叫做聚簇索引,一张表只能有一个聚簇索引。假设没有定义主键,InnoDB会选择一个唯一的非空索引代替,如果没有的话则会隐式定义一个主键作为聚簇索引。
    在这里插入图片描述
    这是主键聚簇索引存储的结构,那么非聚簇索引的结构是什么样子呢?非聚簇索引(二级索引)保存的是主键id值,这一点和myisam保存的是数据地址是不同的。
    最终,我们一张图看看InnoDB和Myisam聚簇和非聚簇索引的区别
    在这里插入图片描述

  3. 那你知道什么是覆盖索引和回表吗?
    覆盖索引指的是在一次查询中,如果一个索引包含或者说覆盖所有需要查询的字段的值,我们就称之为覆盖索引,而不再需要回表查询。
    而要确定一个查询是否是覆盖索引,我们只需要explain sql语句看Extra的结果是否是“Using index”即可。

以上面的user表来举例,我们再增加一个name字段,然后做一些查询试试。

explain select * from user where age=1; //查询的name无法从索引数据获取
explain select id,age from user where age=1; //可以直接从索引获取
  1. 锁的类型有哪些呢
    mysql锁分为共享锁和排他锁,也叫做读锁和写锁。读锁是共享的,可以通过lock in share mode实现,这时候只能读不能写。写锁是排他的,它会阻塞其他的写锁和读锁。从颗粒度来区分,可以分为表锁和行锁两种。
    表锁会锁定整张表并且阻塞其他用户对该表的所有读写操作,比如alter修改表结构的时候会锁表。行锁又可以分为乐观锁和悲观锁,悲观锁可以通过for update实现,乐观锁则通过版本号实现。.
  2. 你能说下事务的基本特性和隔离级别吗?
    事务基本特性ACID分别是:

原子性指的是一个事务中的操作要么全部成功,要么全部失败。

一致性指的是数据库总是从一个一致性的状态转换到另外一个一致性的状态。比如A转账给B100块钱,假设中间sql执行过程中系统崩溃A也不会损失100块,因为事务没有提交,修改也就不会保存到数据库。

隔离性指的是一个事务的修改在最终提交前,对其他事务是不可见的。

持久性指的是一旦事务提交,所做的修改就会永久保存到数据库中。

而隔离性有4个隔离级别,分别是:

read uncommit 读未提交,可能会读到其他事务未提交的数据,也叫做脏读。

用户本来应该读取到id=1的用户age应该是10,结果读取到了其他事务还没有提交的事务,结果读取结果age=20,这就是脏读。
在这里插入图片描述
read commit 读已提交,两次读取结果不一致,叫做不可重复读。

不可重复读解决了脏读的问题,他只会读取已经提交的事务。

用户开启事务读取id=1用户,查询到age=10,再次读取发现结果=20,在同一个事务里同一个查询读取到不同的结果叫做不可重复读。在这里插入图片描述
repeatable read 可重复复读,这是mysql的默认级别,就是每次读取结果都一样,但是有可能产生幻读。

serializable 串行,一般是不会使用的,他会给每一行读取的数据加锁,会导致大量超时和锁竞争的问题。

  1. 那ACID靠什么保证的呢?
    A原子性由undo log日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql

C一致性一般由代码层面来保证

I隔离性由MVCC来保证

D持久性由内存+redo log来保证,mysql修改数据同时在内存和redo log记录这次操作,事务提交的时候通过redo log刷盘,宕机的时候可以从redo log恢复

  1. 那你说说什么是幻读,什么是MVCC?
    要说幻读,首先要了解MVCC,MVCC叫做多版本并发控制,实际上就是保存了数据在某个时间节点的快照。

我们每行数实际上隐藏了两列,创建时间版本号,过期(删除)时间版本号,每开始一个新的事务,版本号都会自动递增。

还是拿上面的user表举例子,假设我们插入两条数据,他们实际上应该长这样。在这里插入图片描述
在这里插入图片描述
由于MVCC的原理是查找创建版本小于或等于当前事务版本,删除版本为空或者大于当前事务版本,小明的真实的查询应该是这样

select * from user where id<=3 and create_version<=3 and (delete_version>3 

所以小明最后查询到的id=1的名字还是’张三’,并且id=2的记录也能查询到。这样做是为了保证事务读取的数据是在事务开始前就已经存在的,要么是事务自己插入或者修改的。

明白MVCC原理,我们来说什么是幻读就简单多了。举一个常见的场景,用户注册时,我们先查询用户名是否存在,不存在就插入,假定用户名是唯一索引。

小明开启事务current_version=6查询名字为’王五’的记录,发现不存在。

小红开启事务current_version=7插入一条数据,结果是这样:
在这里插入图片描述
小明执行插入名字’王五’的记录,发现唯一索引冲突,无法插入,这就是幻读。
8. 那你知道什么是间隙锁吗?
间隙锁是可重复读级别下才会有的锁,结合MVCC和间隙锁可以解决幻读的问题。我们还是以user举例,假设现在user表有几条记录在这里插入图片描述
当我们执行:

begin;
select * from user where age=20 for update;

begin;
insert into user(age) values(10); #成功
insert into user(age) values(11); #失败
insert into user(age) values(20); #失败
insert into user(age) values(21); #失败
insert into user(age) values(30); #失败

只有10可以插入成功,那么因为表的间隙mysql自动帮我们生成了区间(左开右闭)

(negative infinity,10],(10,20],(20,30],(30,positive infinity)

由于20存在记录,所以(10,20],(20,30]区间都被锁定了无法插入、删除。

如果查询21呢?就会根据21定位到(20,30)的区间(都是开区间)。

需要注意的是唯一索引是不会有间隙索引的。
9. 你们数据量级多大?分库分表怎么做的?
首先分库分表分为垂直和水平两个方式,一般来说我们拆分的顺序是先垂直后水平。

垂直分库

基于现在微服务拆分来说,都是已经做到了垂直分库了
在这里插入图片描述
垂直分表

如果表字段比较多,将不常用的、数据较大的等等做拆分

在这里插入图片描述
水平分表

首先根据业务场景来决定使用什么字段作为分表字段(sharding_key),比如我们现在日订单1000万,我们大部分的场景来源于C端,我们可以用user_id作为sharding_key,数据查询支持到最近3个月的订单,超过3个月的做归档处理,那么3个月的数据量就是9亿,可以分1024张表,那么每张表的数据大概就在100万左右。

比如用户id为100,那我们都经过hash(100),然后对1024取模,就可以落到对应的表上了。
10. 那分表后的ID怎么保证唯一性的呢?
因为我们主键默认都是自增的,那么分表之后的主键在不同表就肯定会有冲突了。有几个办法考虑:

设定步长,比如1-1024张表我们分别设定1-1024的基础步长,这样主键落到不同的表就不会冲突了。
分布式ID,自己实现一套分布式ID生成算法或者使用开源的比如雪花算法这种
分表后不使用主键作为查询依据,而是每张表单独新增一个字段作为唯一主键使用,比如订单表订单号是唯一的,不管最终落在哪张表都基于订单号作为查询依据,更新也一样。
11. 分表后非sharding_key的查询怎么处理呢?
可以做一个mapping表,比如这时候商家要查询订单列表怎么办呢?不带user_id查询的话你总不能扫全表吧?所以我们可以做一个映射关系表,保存商家和用户的关系,查询的时候先通过商家查询到用户列表,再通过user_id去查询。
打宽表,一般而言,商户端对数据实时性要求并不是很高,比如查询订单列表,可以把订单表同步到离线(实时)数仓,再基于数仓去做成一张宽表,再基于其他如es提供查询服务。
数据量不是很大的话,比如后台的一些查询之类的,也可以通过多线程扫表,然后再聚合结果的方式来做。或者异步的形式也是可以的。

List<Callable<List<User>>> taskList = Lists.newArrayList();
for (int shardingIndex = 0; shardingIndex < 1024; shardingIndex++) {
    taskList.add(() -> (userMapper.getProcessingAccountList(shardingIndex)));
}
List<ThirdAccountInfo> list = null;
try {
    list = taskExecutor.executeTask(taskList);
} catch (Exception e) {
    //do something
}

public class TaskExecutor {
    public <T> List<T> executeTask(Collection<? extends Callable<T>> tasks) throws Exception {
        List<T> result = Lists.newArrayList();
        List<Future<T>> futures = ExecutorUtil.invokeAll(tasks);
        for (Future<T> future : futures) {
            result.add(future.get());
        }
        return result;
    }
}
  1. 说说mysql主从同步怎么做的吧?
    首先先了解mysql主从同步的原理

master提交完事务后,写入binlog
slave连接到master,获取binlog
master创建dump线程,推送binglog到slave
slave启动一个IO线程读取同步过来的master的binlog,记录到relay log中继日志中
slave再开启一个sql线程读取relay log事件并在slave执行,完成同步
slave记录自己的binglog
在这里插入图片描述
由于mysql默认的复制方式是异步的,主库把日志发送给从库后不关心从库是否已经处理,这样会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库升为主库后,日志就丢失了。由此产生两个概念。

全同步复制

主库写入binlog后强制同步日志到从库,所有的从库都执行完成后才返回给客户端,但是很显然这个方式的话性能会受到严重影响。

半同步复制

和全同步不同的是,半同步复制的逻辑是这样,从库写入日志成功后返回ACK确认给主库,主库收到至少一个从库的确认就认为写操作完成。
13. 那主从的延迟怎么解决呢?
这个问题貌似真的是个无解的问题,只能是说自己来判断了,需要走主库的强制走主库查询。

小龙虾们的好伙伴专栏导航 本文系统解析了OpenClaw技术架构,包括Channel层和网关层的设计实现,并与AgentSkills等技术方案进行对比。同时提供了OpenClaw的系列实用指南,涵盖小龙虾培养、客户资源管理、系统自动化巡检以及技术趋势助手构建等应用场景,帮助用户从零成本入门到高效落地应用,实现业务全流程自动化管理。 阅读详情

相关推荐

IPD(集成产品开发)管理之道

IPD,是集成产品开发(Integrated Product Development)的缩写,它是集成了众多管理模型和理论、众多企业最佳管理实践的一整套体系,可以帮助企业快速响应市场变化、缩短产品上市时间、减少资源浪费、提高生产力,最终取得商业成功。IPD的思想最早来源于美国PRTM公司出版的《产品及生命周期优化法》一书中,该书详细描述了IPD模式所包含的各个方面。但IPD在中国的普及,源于IBM和华为的推行使用。IPD作为一套先进的产品研发管理模式,其成功的基础是功能部门和各团队之间的密切配合。

钢镚·真的博客 2709

如何禁用烦人的“insert”键

在我们日常的电脑使用中,有些按键可能会让我们感到非常烦恼,其中最常见的就是“insert”键。这个键位于键盘的右上角,通常会在我们不经意间被按下,导致我们的输入出现了一些奇怪的问题。如果你也曾经遇到过这个问题,那么本文将为你介绍如何禁用这个烦人的“insert”键。总之,禁用“insert”键可以让我们的电脑使用更加顺畅,避免了因为不小心按下这个键而导致的输入问题。现在,无论你不小心按下这个键,都不会再出现覆盖模式了。在右侧空白的地方点击右键,选择新建“二进制值”,命名为"Scancode Map"。

中级CV工程师,欢迎来扰! 1万+

Android客户端如何设计架构

当我们在新开发一款APP时,我们在初期要如何设计架构呢?在这里我根据我的经验,总结了一些基本的架构思路。 客户端架构设计的时候,首先需要充分考虑到所开发的app的类型,这里我分为功能型和服务型两大类,功能型的app侧重业务和功能,服务型的app侧重服务和运算。下面我就具体来讲讲针对这两种类型的通用架构。 功能型app 功能型app的activity比较多,整个app都以一个个activity承载业务和功能,在设计这类app时,我们需要考虑哪些要素呢? 由于activity比较多,我们需要考虑页面的跳转路由,

子者不语的专栏 1544

本文详细说明 如何禁用insert键,或仅word禁用,其他区域正常使用!

本文详细介绍了如何在word中和windows系统中禁用insert键,有效避免在输入文字时覆盖已经写好的文字。支持仅word禁用,也可以全局禁用。

ZiroWang的博客 7076

Tesla V100 Windows 部署实战:从驱动安装到模式切换的避坑指南

本文是一份详细的Tesla V100在Windows系统下的部署实战指南。文章从硬件组装、系统选择讲起,重点阐述了驱动安装的正确方法,并深入剖析了将计算卡从TCC模式切换至WDDM模式的诱惑与潜在陷阱。最终,作者推荐保持默认TCC模式,并提供了使用nvidia-smi命令行等稳定可靠的显卡监控方案,旨在帮助用户避开常见坑点,高效利用这张专业计算卡进行AI计算等任务。

java5的博客 1706

EastWave应用案例:机箱屏蔽效能仿真

如何使用EastWave对机箱的电磁屏蔽效能进行仿真

2201_76034687的博客 1392

禁用Insert按键

???? https://www.wikihow.com/Disable-the-Insert-Key-in-Windows 转载于:https://www.cnblogs.com/trykle/p/11515621.html

weixin_30902251的博客 1878

麒麟V10 x86_64系统下Qt 5.12.7安装全攻略(附常见报错解决方案)

本文详细介绍了在麒麟V10 x86_64系统上安装Qt 5.12.7的完整流程,包括在线和离线两种安装方案,并提供了常见报错的解决方案。从环境准备到项目配置优化,再到高级调试技巧,全面覆盖Qt开发在国产操作系统上的实践要点,帮助开发者高效搭建开发环境。

weixin_29294395的博客 508

Insert into select为什么不可随意用

Insert into select为什么不可随意用 Insert into select请慎用。经常有人将A表的数据迁移到表B中去做一个备份,想通过程序先查询查出来然后批量插入。但考虑到需要耗费大量的网络I/O,所以使用insert into select实现,这样就可以避免使用网络I/O,直接使用SQL依靠数据库I/O完成。 但是… 例如我们要把order_today表的数据备份到order_record表。 在默认的事务隔离级别下:insert into order_record select * f

小八成长记 957

【软件介绍】RVC本地部署使用方法

【摘要】RVC是一款功能强大的开源语音转换工具,具有实时处理、多音效选择、高质量音频处理等特点。文章详细介绍了RVC的安装与使用方法:1)配置Python环境;2)根据电脑系统选择对应安装包解压;3)启动程序进入浏览器操作界面。重点讲解了声音克隆的关键步骤:建议使用短音频素材,选择合适训练方法(推荐pm或rmvpe),设置100次训练轮数,生成的模型文件存入weights文件夹。最后通过上传音频即可实现声音克隆。操作过程需注意保持程序运行状态,并提供了相关资源下载地址。

心动的那一刻,记忆便盛开了花 2976

【开源训练数据集2】10个最适合机器学习的股票市场数据集

​随着加密货币在世界各地的兴起,人们现在有比以往更多的投资方式。然而,这并不像低买高卖那么简单。如果你能准确预测股市,你就会成为地球上最富有的人之一。因此,之前已经有关于如何利用情绪分析来预测股市的研究。对于那些希望构建类似预测模型的人,本文将介绍 10 个用于机器学习的股票市场和加密货币数据集。

u010542847的博客 2139

windows键被禁用_如何在Windows 10上禁用插入键

windows键被禁用Brady Gavin 布雷迪·加文 When you inadvertently press Insert on your keyboard, it toggles to Overtype mode. This means anything you type next will overwrite the text that follows the cursor. Fort...

culunyi0802的博客 2977

RK3566/RK3568 Android 11添加系统服务

【代码】RK3566/RK3568 Android 11添加系统服务。

qq_23921815的博客 641

关于Mysql相关操作,了解和掌握的知识点

了解 和 掌握 mysql 数据库 相关的知识点

weixin_44004878的博客 912

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

MySQL必须要了解的知识

1.mysql事物的基本特征和事务隔离级别 四大特性: 1.原子性:事务中的所有操作要么成功,要么全部撤回到执行事务之前的状态。 2. 一致性:执行事务之前数据库是一致的,执行事务之后数据库也是一致的。 3.隔离性:事务操作的时候是独立的,互不干扰的。 4.持久性:事务一旦提交,结果就是永久的了。 隔离级别 1.读未提交 2.不可重复读 3.可重复读 4.串行话 2.mysql脏读、不可重复读、幻读 脏读:事务A读取了事务B更新的数据,然后B回滚操作 不可重复读:事务A多次读取同一数据,事务B在事务A多次读

qq_42897750的博客 288

应该掌握的mysql知识_mysql应该了解的知识点

数字类型整数: tinyint、smallint、mediumint、int、bigint浮点数: float、double、real、decimal日期和时间: date、time、datetime、timestamp、year字符串类型字符串: char、varchar文本: tinytext、text、mediumtext、longtext二进制(可用来存储图片、音乐等): tinyblob...

weixin_39538877的博客 97

MySQL知识了解

MySQL学习 一、初识MySQL JavaEE:企业级java开发 主要做Web这一方面,Web分为前端和后台 前端(页面:用来展示,数据库中的数据) 后台(连接点:连接数据库JDBC,连接前端( 控制,控制视图跳转,和给前端传递数据)) 数据库(存数据,例如:Txt,Excel,Word都可以存数据) 二、什么是数据库 数据库(DB,DateBase) 概念:存放数据的仓库,是一个软件,安装在操作系统之上,SQL可以存储大量数据 作用:存储数据,管理数据 三、数据库分类 关系数据库:(

suhanghah的博客 116

对于MySQL,你必须要了解的锁知识

对于MySQL,你必须要了解的锁知识 一、前言 MySQL 的锁按照范围可以分为全局锁、表锁、行锁,其中行锁是由数据库引擎实现的,并不是所有的引擎都提供行锁,MyISAM 就不支持行锁,所以文章介绍行锁会以InnoDB引擎为例来介绍行锁。 二、全局锁 MySQL 提供全局锁来对整个数据库实例加锁。 语法: FLUSH TABLES WITH READ LO...

Julysx的博客 275

【MySQL】一文带你了解MySQL的基础知识

😁大家好呀,今天是我第n次写MySQL,也是最近才学习MySQL,也想着记录一下自己的学习过程,并且分享给大家尼!MySQL 是由微软公司(Microsoft)开发的关系型数(RDBMS)。RDBMS 是 SQL 以及所有现代数据库系统的基础,比如 MS SQL Server,IBM DB2,Oracle,MySQL 以及微软的 Microsoft Access。

m0_64361522的博客 732

[Mysql-数据库基本知识了解]

数据库(Database,简称DB)概念: 长期存放在计算机内,有组织、可共享的大量数据的集合,是一个 数据“仓库”。数据库特点:结构化,共享性,独立性,安全性作用 :存放、管理数据分类:关系型数据库(MySQL...)、NoSQL数据库(redis,mongoDB)

2301_78794952的博客 610

Mysql务必要了解的知识

Mysql务必了解的知识 首先说下mysql比较重要以及常用的两个引擎 InnoDB和MyISAM 创建表格的时候可以指定表的存储引擎,语句如下 例:创建一个表格,指定引擎为MyISAM,编码为utf8 CREATE TABLE my_table( 字段名称,数据类型... ) ENGINE=MyISAM DEFAULT CHARSET=utf8 有什么区别? 1.InnoDB支持事务,支持行级锁,支持外键(实际当中尽量不使用外键,减少表关联) 2.MyISAM读比InnoDB快,但写操作远远低于inn

weixin_44541678的博客 727

对于MySQL你必须要了解的锁知识

无论是哪家公司,都很重视高并发高可用的技术,重视基础,重视JVM。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。其实我写了这么多,只是我自己的总结,并不一定适用于所有人,相信经过一些面试,大家都会有这些感触。最后我整理了一些面试真题资料,技术知识点剖析教程,还有和广大同仁一起交流学习共同进步,还有一些职业经验的分享。《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》

F1520080的博客 721

mysql 你必须了解的知识

数据库的简单概念 DBS(database system) :数据库与数据库管理系统的总称 DB(database) :数据存放的位置 DBMS(database manage system):管理数据库的应用程序 1.你并不直接访问数据库;你使用的是DBMS,它替你访问数据库。 2.MySQL是一种DBMS,即它是一种数据库软件。 3.SQL是一种专门用来与数据库通信的语言。 4.只有数据库知道SELECT语句中哪些列是实际的 表列,哪些列是计算字段。从客户机(如应用程序)的角度来看,计算 字段的数据

Gloomysunny的博客 386

MYSQL知识简单了解

MYSQL知识简单了解 mysql 简介 常见数据库Oracle、MYSQL、SQLServer、SQLite、postgreSQL等。用的较多的关系型数据库MYSQL、postgreSQL。 关系型数据库:用来存一类数据。 表结构设计的三大范式:《漫画数据库》 SQL语句 DDL:操作数据库的 DML:表的增删改查 DCL:用户及权限 存储引擎 插件式的存储引擎 常见的存储引擎:MyISAM和InnoDB MyISAM: 1、查询速度快 2、只支持表锁 3、不支持事物 InnoDB: 1、速度快 2、支持

ltshuangchen的博客 255

MySQL必须要了解的锁知识

MySQL 的锁按照范围可以分为全局锁、表锁、行锁,其中行锁是由数据库引擎实现的,并不是所有的引擎都提供行锁,MyISAM 就不支持行锁,所以文章介绍行锁会以InnoDB引擎为例来介绍。 二、全局锁 MySQL 提供全局锁来对整个数据库实例加锁。 语法: FLUSH TABLES WITH READ LOCK 这条语句一般都是用来备份的,当执行这条语句后,数据库所有打开的表都会被关闭...

La victoria的博客 303
上一篇: Json的使用方式
下一篇: IDEA配置Tomcat
凌晨里的无聊人
博客等级 码龄8年 2320粉丝 206原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌晨里的无聊人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值