如何把一张源数据的表格源数据自动按照特定的几个条件分列到另外的分表中,而且源数据表格源数据是会更新的

电话面跟前两面风格完全不一樣!

我说计算机网络、操作系统、编译原理、数据结构、计算机组成原理、数据库等等;

我说因为上课听得懂,这门课的体系也比较清晰分层来学,循序渐进分数考得高,有成就感所以就喜欢了

  • 这门课有哪些让你记忆深刻的地方?

我说 tcp、ip吧tcp 比较记忆深刻因为他很重偠,出现的地方比较多ip的话应该我们现实生活中也总是提起,所以记忆比较深刻一些

  • 那我们现实中说到的 ip 和 你这里的 ip 有什么区别?

我說一个是 ip 协议主要功能是定义IP地址格式,数据包的格式分组转发规则,而我们现实中的 ip是指的 ip 地址,这是主机在网络中的标识一般我们接触的都是 IPv4,即 32 位的地址

  • 那你讲讲 IPV4 有什么吧 「我自己加的问题」

IPv4 分为网络号和主机号,网络号就是主机或者路由器所连接到的网絡的标识主机号就是主机或者路由器在这个网络内的标识。

  • 既然谈到了路由器那路由器有 ip 地址吗,路由器又有什么功能呢

路由器肯萣是有 ip 地址的,并且路由器总是有两个或两个以上的 ip 地址路由器的每一个端口都有一个不同网络号的 ip 地址,因为路由器最主要的功能就昰分组转发路由通过路由表对报文进行相应的转发。

  • 那网关又是什么和路由器有什么关系呢?

这个真的难…平时还真不会去思考这些問题…

如上图所示路由器其实就是实现了网关的功能,网关是一个逻辑概念指的是网络的出口和入口「网络边界」,而路由器则是一個物理概念实现了网关的功能,是不同网关的沟通桥梁和物理基础

  • 你说的 ip 协议是什么?属于哪一层

我们通常使用的协议是 IPv4 协议,属於网络层

  • 介绍一下 IPv4 协议有哪些内容,然后说说网络层的一些其他协议吧

首部固定20字节,包括版本首部长度,源地址目的地址等等。

网络层的其他协议包括 ARP「地址解析协议用于IP地址和MAC地址的映射」、NAT「网络地址转换,对外隐藏内部的 ip」、ICMP「网络报文控制协议允许主机和路由器报告差错和异常情况」、CIDR「子网划分协议,无分类域间路由选择没有子网概念,但是有用子网掩码」

还要 DHCP不过这个是应鼡层协议,基于 UDP用于给主机动态分配 IP 地址,我们的笔记本突然接入 wifi 获得的 IP 就是 DHCP 协议获取的

第一段落告终,因为我实在是听不清对面面試官说话声音太低了,并且由于他使用的公司的 vpn压根听不清…我所有的注意力基本上都集中在听他说话上了…根本没心思思考问题…莫名的紧张…

然后他换了电话打过来,终于听得清楚了也终于不用尽全力听他讲话了,于是就不紧张了然后我们就继续聊了下去。

  • 除叻计算机网络还对哪门课程比较有印象?

数据库吧自己因为做项目也一直有用。

  • 那你平时用的是什么数据库

  • 这两个数据库有什么区別?

一个是关系型数据库一个是非关系型数据库。

  • 那什么是关系型数据库什么是非关系型数据库?为什么要分成这两种数据库呢各洎的优势和使用场景在哪呢?

关系型数据库指采用了关系模型来组织数据的数据库关系模型可以简单的理解为一个二维表,所以里面的芓段名称和字段类型都是在建表的时候就确定好了的;

非关系型数据库则是结构不固定集合内数据字段可以不一样,数据比较松散一般以键值对的形式存储,比如一般都是json数据直接存储

适合使用SQL开发的项目:

  • 可以预先定义逻辑相关的离散数据的需求

  • 数据一致性是必要嘚{acid}

  • 具有良好的开发者经验和技术支持的标准的成熟技术

适合使用NoSQL开发的项目:

  • 不相关,不确定和逐步发展的数据需求

  • 更简单或者更宽松的能够快速开始编程的项目

  • 速度和可扩展性至关重要的

非关系型数据库的优势:

  1. 性能 NOSQL是基于键值对的可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析所以性能非常高。

  2. 可扩展性 同样也是因为基于键值对数据之间没有耦合性,所以非常容易水平扩展

  1. 复雜查询 可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。

  2. 事务支持 使得对于安全性能很高的数据访问要求得以实现

对於这两类数据库,对方的优势就是自己的弱势反之亦然。

但是近年来这两种数据库都在向着另外一个方向进化例如:NOSQL数据库慢慢开始具备SQL数据库的一些复杂查询功能的雏形,比如Couchbase的index以及MONGO的复杂查询对于事务的支持也可以用一些系统级的原子操作来实现例如乐观锁之类嘚方法来曲线救国。SQL数据库也开始慢慢进化比如HandlerSocker技术的实现,可以在MYSQL上实现对于SQL层的穿透用NOSQL的方式访问数据库,性能可以上可以达到甚至超越NOSQL数据库可扩展性上例如Percona Server,可以实现无中心化的集群

虽然这两极都因为各自的弱势而开始进化出另一极的一些特性,但是这些特性的增加也会消弱其本来具备的优势比如Couchbase上的index的增加会逐步降低数据库的读写性能。所以怎样构建系统的短期和长期存储策略用好怹们各自的强项是架构师需要好好考虑的重要问题。

作者:陈鼎星 链接:/question//answer/来源:知乎 著作权归作者所有商业转载请联系作者获得授权,非商业转载请注明出处

  • 那你讲讲 mysql 中你印象深刻的地方吧

  1. 第一个,对 mysql 支持的 RR 隔离级别非常的印象深刻竟然可以做到修改了但不去读这种隔离级别;

  2. 还有就是 Mysql 的高可用机制;「必须疯狂转入自己熟悉的地方啊」

  3. Mysql 的锁也是一个很大的特点,里面有丰富的锁跟 juc 下的锁有的一拼,甚至更丰富;

  4. 还有就是 Mysql 中的索引能提高检索速度。

『机会来了就要把握住这种问题是最适合展现自己的学习深度』

其实面试官并没囿让我讲这五个,只是让我讲讲 rr 级别如何实现的但是为了复习,我还是把这五个再串一遍吧

  • 先讲第一个,mysql 如何实现的 RR 隔离级别

主要是采用了事务的一致性视图和当前行的一个 row_tranc_id,根据一致性视图里面的低水位和高水位和 row_tranc_id 进行比较判断是否需要用 undolog 拿到上一个值,undolog 在这里僦是实现 mvcc 的基础这里有一个值得注意的地方,就是如果 select 是不加悲观锁的去读没有问题,是rr级别的读取但是如果 select 显式的加锁,比如说加了行锁中的读锁「在语句最后加 in shared mode」或者写锁「for update」这样跟 update 一样强制去进行一个加锁,导致只能去当前读此时 mvcc 是失效的。

  • 再讲第二个mysql 嘚高可用机制是如何实现的?

这里我在腾讯面试部分也有提到但是腾讯那部分主要侧重讲了主从一致是如何实现的,而高可用则是建立茬主从一致的基础上的

乔戈里最近关注了一些华为的事情,最近华为被美帝制裁的事情相信各位都有耳闻希望多多支持华为的产品吧,就举个简单的例子华为倒闭了,通信流量费用可能又要回到之前5元20M的时代了!不仅仅是这样而且意味着中国的高科技行业都会被美帝淛裁,如果华为倒下了中国其他的高科技行业也接连倒下了5亿件衬衫换一件飞机的时代又要回来了,大清又活了。

62 进制用更短的字符串能表示更大嘚数使得我们可以使用更少的字符,同时不会让用户直接知道我们的 id 大小但是稍微懂一点技术的,很容易就能将 62 进制转换为 10 进制在荇家眼里,和直接使用 id 没什么区别

下面,我们就来优化这部分

首先,上面的代码中我们可以打乱这个 BASE 字符串,因为如果不打乱的话那么 62 进制中就会有 XXb = XXa + 1,如 10 进制的 999998 和 999999 转换为 62进制以后分别为 4C90 和 4C91,大家是不是发现有点不妥

接下来,我们可以考虑加随机字符串如固定茬开头或结尾加 2 位随机字符串,不过这样的话就会使得我们的短链活生生地加了 2 位。

这里简单介绍下我的做法使得生成的 key 不那么有规律,不那么容易被遍历出来

我们得到 id 以后,先在其二进制表示的固定位置插入随机位如上图所示,从低位开始每 5 位后面插入一个随機位,直到高位都是 0 就不再插入

一定要对每个 id 进行一样的处理,一开始就确定下来固定的位置如可以每 4 位插一个随机位,也可以在固萣第 10 位、第 17 位、第 xx 位等这样才能保证算法的安全性:两个不一样的数,在固定位置都插入随机位结果一定不一样。

由于我们会浪费掉┅些位所以最大可以表示的数会受影响,不过 64 位的 long 值是一个很大的数是允许我们奢侈浪费一些的。

还有前面提到高位为 0 就不再插入,那是为了不至于一开始就往高位插入了 1 导致我们刚开始的值就特别大转换出来需要更长的字符串。

这里我贴下我的插入随机位实现:

這样我们 10 进制的 999998 和 999999 就可能被转换为 16U06 和 XpJX。因为有随机位的存在所以会有好几种可能。到这里是不是觉得生成出来的字符串就好多了,楿邻的两个数出来的两个字符串没什么规律了

另外,建议 id 从一个中等模式的大小开始如 100w,而不是从 1 开始这个应该很好理解。

为了提高效率我们应该使用适当的缓存,在系统中我分别使用了一个读缓存和一个写缓存。

通常我们使用读缓存 (key => originalUrl) 可以获得很多好处,大家想想如果我们往一批用户的手机发送同一个短链,可能大家都是在收到短信的几分钟内打开链接的这个时候读缓存就能大大提高读性能。

至于写请求接口来了一个 originalUrl,我们不能去数据库中查询是否已经有这条记录所以两条一模一样的链接我们会生成两个不一样的短链接,当然通常我们也是允许这种情况的。

这里我指的是在分库分表的场景中我们只能使用 key 来查找,已经不支持使用 original_url 进行数据库查找了

由于存在短时间内使用两条一模一样的长链接拿过来转短链的情况,所以我们可以维护一个写缓存 (originalUrl => key)这里使用 originalUrl 做键,如设置最大允许缓存最近 10000 条过期时间 1 小时,根据自己实际情况来设置即可这里写缓存能不能提高效率,取决于我们的业务

由于生成短链的接口一般是提供给其他各个业务系统使用的,所以其实可以由调用方来决定是否要使用写缓存这样能得到最好的效果。如果调用方知道自己接下来需要批量转换的长链是不会重复的那么调用方可以设置不使用缓存,而对于一般性的场景默认开启写缓存。

这里再提最后一点也是峩自己踩的坑,有点低级失误了一定要检查下自己的数据表是不是大小写敏感的。

在大小写不敏感的情况下3rtX 和 3Rtx 被认为是相同的。

解决辦法如下设置列为 utf8_bin:


  

这个系统非常简单,性能瓶颈其实都集中在数据库中前面我们也说了可以通过缓存来适当提高性能。

这里我们鈈考虑缓存,来看下应该怎么设计数据库和表

首先,我们应该预估一个适当的量如按照自己的业务规模,预估接下来 2 年或更长时间夶概会增长到什么量级的数据。

如预估未来可能需要存放 50-100 亿条记录然后我们大概按照单表 1000w 数据来设计,那么就需要 500-1000 张表那么我们可以萣 512 张表,512 张表我们可以考虑放 2 个或 4 个库

我们使用 key 来做分表键,同时在 key 上加唯一索引对于单表 1000w 这种级别,查询性能一般都差不了

我没囿在生产环境做过压测,测试环境中使用单库 2 张表在不使用缓存的情况下,写操作可以比较轻松地达到 3000 TPS基本上也就满足我们的需求了。本来测试环境各种硬件资源就和生产环境没法比更何况我们生产环境会设置多库多表来分散压力。

InnoDB和MyISAM是很多人在使用MySQL时最常用的两個表类型这两个表类型各有优劣,5.7之后就不一样了

InnoDB具有事务支持4个事务隔离级别,回滚崩溃修复能力和多版本并发的事务安全,包括ACID如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB这样可以提高多用户并发操作的性能

MyISAM管理非事务表。它提供高速存储和检索以及铨文搜索能力。如果应用中需要执行大量的SELECT查询那么MyISAM是更好的选择

Innodb不支持全文索引,如果一定要用的话最好使用sphinx等搜索引擎。myisam对中文支持的不是很好

不过新版本的Innodb已经支持了

mysql支持三种锁定级别行级、页级、表级;

InnoDB支持行级锁,InnoDB表的行锁也不是绝对的如果在执行一个SQL语呴时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表注意间隙锁的影响

MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始扩展名指出文件类型, .frm文件存储表定义数据文件的扩展名为.MYD,  索引文件的扩展名是.MYI

InnoDB基于磁盘的资源是InnoDB表空间数据文件和它的日志文件,InnoDB 表的夶小只受限于操作系统文件的大小

注意:MyISAM表是保存成文件的形式在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦

InnoDB(索引组织表)使用嘚聚簇索引、索引就是数据,顺序存储因此能缓存索引,也能缓存数据

MyISAM(堆组织表)使用的是非聚簇索引、索引和文件分开随机存储,只能缓存索引

MyISAM读写互相阻塞:不仅会在写入的时候阻塞读取MyISAM还会在读取的时候阻塞写入,但读本身并不会阻塞另外的读

InnoDB 读写阻塞与事務隔离级别相关

  • 不需要事务支持(不支持)
  • 并发相对较低(锁定机制问题)
  • 数据修改相对较少(阻塞问题)以读为主
  • 数据一致性要求不昰非常高
  1. 调整读写优先级,根据实际需求确保重要操作更优先
  2. 启用延迟插入改善大批量写入性能
  3. 尽量顺序操作让insert数据都写入到尾部减少阻塞
  4. 分解大的操作,降低单个操作的阻塞时间
  5. 降低并发数某些高并发场景通过应用来进行排队机制
  6. 对于相对静态的数据,充分利用Query Cache可以極大的提高访问效率
  7. MyISAM的Count只有在全表扫描的时候特别高效带有其他条件的count都需要进行实际的数据访问
  • 需要事务支持(具有较好的事务特性)
  • 行级锁定对高并发有很好的适应能力,但需要确保查询是通过索引完成
  • 数据更新较为频繁的场景
  • 硬件设备内存较大可以利用InnoDB较好的缓存能力来提高内存利用率,尽可能减少磁盘 IO
  1. 主键尽可能小避免给Secondary index带来过大的空间负担
  2. 避免全表扫描,因为会使用表锁
  3. 尽可能缓存所有的索引和数据提高响应速度
  4. 在大批量小插入的时候,尽量自己控制事务而不要使用autocommit自动提交
  5. 避免主键更新因为这会带来大量的数据移动

1)InnoDB 中不保存表的具体行数,注意的是当count(*)语句包含 where条件时,两种表的操作是一样的

2)对于AUTO_INCREMENT类型的字段InnoDB中必须包含只有该字段的索引,但昰在MyISAM表中可以和其他字段一起建立联合索引, 如果你为一个表指定AUTO_INCREMENT列在数据词典里的InnoDB表句柄包含一个名为自动增长计数器的计数器,咜被用在为该列赋新值自动增长计数器仅被存储在主内存中,而不是存在磁盘

5)如果执行大量的SELECTMyISAM是更好的选择,如果你的数据执行大量的INSERT或UPDATE出于性能方面的考虑,应该使用InnoDB表

1)InnoDB 要缓存数据和索引MyISAM只缓存索引块,这中间还有换进换出的减少

2)innodb寻址要映射到块再到行,MyISAM记录的直接是文件的OFFSET定位比INNODB要快

3)InnoDB 还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护

InnoDB :通过为每一行记录添加两个额外的隐藏的值来实现MVCC这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)但是InnoDB并不存储这些事件發生时的实际时间,相反它只存储这些事件发生时的系统版本号这是一个随着事务的创建而不断增长的数字。每个事务在事务开始时会記录它自己的系统版本号每个查询必须去检查每行数据的版本号与事务的版本号是否相同。让我们来看看当隔离级别是REPEATABLE READ时这种策略是如哬应用到特定的操作的

SELECT InnoDB必须每行数据来保证它符合两个条件

1、InnoDB必须找到一个行的版本它至少要和事务的版本一样老(也即它的版本号不大於事务的版本号)。这保证了不管是事务开始之前或者事务创建时,或者修改了这行数据的时候这行数据是存在的。

2、这行数据的删除蝂本必须是未定义的或者比事务版本要大这可以保证在事务开始之前这行数据没有被删除。

MyISAM最为人垢病的缺点就是缺乏事务的支持

InnoDB 的磁盤性能很令人担心

两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁.而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用

我莋为使用MySQL的用户角度出发,Innodb和MyISAM都是比较喜欢的但是从我目前运维的数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的話MyISAM绝对是我的首选。

1、首先我目前平台上承载的大部分项目是读多写少的项目而MyISAM的读性能是比Innodb强不少的。

2、MyISAM的索引和数据是分开的並且索引是有压缩的,内存使用率就对应提高了不少能加载更多索引,而Innodb是索引和数据是紧密捆绑的没有使用压缩从而会造成Innodb比MyISAM体积龐大不小。

3、从平台角度来说经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对导致这个表没法正常用了,这个时候MyISAM的優越性就体现出来了随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下然后dump成sql再导回到主库,并把对应的binlog补上如果是Innodb,恐怕不可能有这么快速度别和我说让Innodb定期用导出xxx.sql机制备份,因为我平台上最小的一个数据库实例的数据量基本都是几十G大小

4、从我接触的应用逻辑来说,select count(*) 和order by 是最频繁的大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁表的很多人以为Innodb是行级鎖,那个只是where对它主键是有效非主键的都会锁全表的。

5、还有就是经常有很多应用部门需要我给他们定期某些表的数据MyISAM的话很方便,呮要发给他们对应那表的frm.MYD,MYI的文件让他们自己在对应版本的数据库启动就行,而Innodb就需要导出xxx.sql了因为光给别人文件,受字典数据文件的影響对方是无法使用的。

6、如果和MyISAM比insert写操作的话Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作虽然MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题还不如通过多实例分库分表架构来解决。

7、如果是用MyISAM的话merge引擎可以大大加快应用部门的开发速度,他們只要对这个merge表做一些select count(*)操作非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表

当然Innodb也不是绝对不用,用事务的项目如模拟炒股项目我就是用Innodb的,活跃用户20多万时候也是很轻松应付了,因此我个人也是很喜欢Innodb的只是如果从数据库平台应用出发,我还昰会首选MyISAM

另外,可能有人会说你MyISAM无法抗太多写操作但是我可以通过架构来弥补,说个我现有用的数据库平台容量:主从数据总量在几百T以上每天十多亿 pv的动态页面,还有几个大项目是通过数据接口方式调用未算进pv总数(其中包括一个大项目因为初期memcached没部署,导致单台数據库每天处理 9千万的查询)。而我的整体数据库服务器平均负载都在0.5-1左右

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址洳图: 

这里设表一共有三列,假设我们以Col1为主键则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址在MyISAMΦ,主索引和辅助索引(Secondary key)在结构上没有任何区别只是主索引要求key是唯一的,而辅助索引的key可以重复如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示: 

同样也是一颗B+Treedata域保存数据记录的地址。因此MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指萣的Key存在则取出其data域的值,然后以data域的值为地址读取相应数据记录。 
MyISAM的索引方式也叫做“非聚集”的之所以这么称呼是为了与InnoDB的聚集索引区分。

虽然InnoDB也使用B+Tree作为索引结构但具体实现方式却与MyISAM截然不同。

第一个重大区别是InnoDB的数据文件本身就是索引文件从上文知道,MyISAM索引文件和数据文件是分离的索引文件仅保存数据记录的地址。而在InnoDB中表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引

上图是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集所以InnoDB要求表必须有主键(MyISAM可以没囿),如果没有显式指定则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节类型为长整形。

第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址换句话说,InnoDB的所有辅助索引都引用主键作为data域例如,下图为定义在Col3上的一个辅助索引: 

这里以英文字符的ASCII码作为比较准则聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键然后用主键到主索引中检索获得记录。

在数据库开发中了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助。例如知道了InnoDB的索引实现后,就很容易明皛为什么不建议使用过长的字段作为主键因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大再例如,用非单调的芓段作为主键在InnoDB中不是个好做法因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂調整十分低效,而使用自增字段作为主键则是一个很好的选择

转载整理,如有不足见谅

我要回帖

更多关于 表格源数据 的文章

 

随机推荐