Hbase基础篇

Stella981
• 阅读 619

hbase存储:HBase存储数据其底层使用的是HDFS来作为存储介质,HBase的每一张表对应的HDFS目录上的一个文件夹,文件夹名以HBase表进行命名(如果没有使用命名空间,则默认在default目录下),在表文件夹下存放在若干个Region命名的文件夹,Region文件夹中的每个列簇也是用文件夹进行存储的,每个列簇中存储就是实际的数据,以HFile的形式存在。路径格式如下:

/hbase/data/default/<tbl_name>/<region_id>/<cf>/<hfile_id>

namespace:命名空间的作用是把多个属于相同业务领域的表分成一个组。一个表可以自由选择是否有命名空间,如果创建表的时候加上了命名空间后,这个表名字就成为了: :

。通过命名空间我们可以像关系型数据库一样将表分组,对于不同的组进行不同的环境设定,比如配额管理、安全管理

Hbase:系统表空间,用于HBase内部表。default:那些没有定义表空间的表都被自动分配到这个表空间下

Table(表):一个表由一个或者多个列族组成。数据属性,比如超时时间(TTL),压缩算法(COMPRESSION)等,都在列族的定义中定义。定义完列族后表是空的,只有添加了行,表才有数据

Row(行):一个行包含了多个列,这些列通过列族来分类。行中的数据所属列族只能从该表所定义的列族中选取,不能定义这个表中不存在的列族,否则你会得到一个NoSuchColumnFamilyException。由于HBase是一个列式数据库,所以一个行中的数据可以分布在不同的服务器上。每个row都拥有唯一的rowKey(行键)来标定这个行的唯一性。每个列都有多个版本,多个版本的值存储在单元格(cell)中

Column Family(列簇):HBase会尽量把同一个列族的列放到同一个服务器上,这样可以提高存取性能,并且可以批量管理有关联的一堆列。所有的数据属性都是定义在列族上。若干个列可以被归类为一个列簇。同一个表中不同的列簇可以有完全不同的属性配置,但是同一个列簇内的所有列都会有相同的属性,因为他们都在一个列簇里面,而属性都是定义在列簇上的

如下图为表设置了两个列族,而且,定义了每一个列族中要存放的列,如图所示:{Name} -> Column Family-A, {City, Phone, Gender} -> Column Family-B,不同列族的数据会被存储在不同的路径中。即,设置多个列族时一行数据可能存在于两个路径中。整行读取的时候,需要将两个路径中的数据合并在一起才可以获取到完整的一行记录。但如果仅仅读取Name一列的话,只需要读取Column Family-A即可

Hbase基础篇

Column Qualifier(列):多个列组成一个行。列族和列经常用Column Family: Column Qualifier来一起表示。列是可以随意定义的,一个行中的列不限名字、不限数量,只限定列族

一个列中可以存储多个版本的数据。而每个版本就称为一个单元格(Cell),所以在HBase中的单元格跟传统关系型数据库的单元格概念不一样。HBase中的数据细粒度比传
统数据结构更细一级,同一个位置的数据还细分成多个版本

Timestamp(时间戳/版本号):你既可以把它称为是时间戳,也可以称为是版本号,因为它是用来标定同一个列中多个单元格的版本号的。当你不指定版本号的时候,系统会自动采用当前的时间戳来作为版本号

rowkey(行键):Hbase无法根据某个column来排序,永远是根据rowkey来排序的。如果插入Hbase的时候,之前已经存在即将插入的rowkey,它会把之前的row更新掉,之前已经存在的column,会被放在这个单元格的历史记录里面,并不会丢掉,只是你需要带上版本参数才可以找到这个值

rowkey的排序规则:每一个行都有一个类似主键的rowkey,而这个rowkey在HBase中是严格按照字典排序的,也就是说11比2小,row11会排在row1和row2中间

cell(单元格):一个列上可以存储多个版本的单元格,单元格是数据存储的最小单元。Hbase里面唯一确定一条数据的是:**rowkey:column family:column:version,**如果不写版本号,Hbase会取最后一个版本的数据返回给你,如果用户不指定版本号,他就是系统默认的时间给你

ACID就是Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)、Durability(持久性)的首字母缩写。ACID是事务正确执行的保证。HBase部分支持了ACID

一、Hbase宏观架构

Hbase基础篇

Master:mast服务器负责维护表结构信息,实际的数据都存在regionServer服务器上。负责启动的时候分配Region到具体的RegionServer,执行各种管理操作,比如Region的分割和合并,创建表、修改列族配置

RegionServer:一般一台服务器只会安装一个RegionServer,也可以安装多个。RegionServer上有一个或者多个Region。我们读写的数据就存储在Region上。如果你的HBase是基于HDFS的,那么Region所有数据存取操作都是调用了HDFS的客户端接口来实现的。客户端读取数据是直接连接regionServer的,所以当master挂掉之后依然可以查询数据,但是不能建表了。regionServer十分依赖ZK,ZK管理了所有Hbase的regionServer的信息,包括具体的字段存在哪个RegionServer上。客户端每次连接Hbase,都是先与ZK通信,查询出来那个regionServer需要连接,然后在连接RegionServer

Region:它是一段数据的集合,一个region是多个**行(row)**的集合,表的一部分数据。HBase是一个会自动分片的数据库。一个Region就相当于关系型数据库中分区表的一个分区,region有以下特性

    1.Region不能跨服务器,一个RegionServer上有一个或者或者Region

    2、数据量小的时候,一个Region可以存储所有数据;当数据量大的时候,Hbase会拆分Region

    3、Hbase在负载均衡的时候,也有可能会从一台ResgionServer上把Region移动到另一台RegionServer上

    4、Region是基于Hdfs的,它的所有数据存取操作都是调用了HDFS的客户端接口来实现的

HDFS:Hadoop的一部分。HBase并不直接跟服务器的硬盘交互,而是跟HDFS交互,所以HDFS是真正承载数据的载体

ZooKeeper:把Master服务器关掉你的业务系统照样跑,能读能写;但是把ZooKeeper关掉,你就不能读取数据了,因为你读取数据所需要的元数据表hbase:meata的位置存储在ZooKeeper上

1、RegionServer架构

Hbase基础篇

一个WAL:预写日志,WAL是Write-Ahead Log的缩写。从名字就可以看出它的用途,就是:预先写入。当操作到达Region的时候,HBase先不管三七二十一把操作写到WAL里面去。HBase会先把数据放到基于内存实现的Memstore里,等数据达到一定的数量时才刷写(flush)到最终存储的HFile内。而如果在这个过程中服务器宕机或者断电了,那么数据就丢失了。WAL是一个保险机制,数据在写到Memstore之前,先被写到WAL了。这样当故障恢复的时候可以从WAL中恢复数据

多个Region:Region相当于一个数据分片。每一个Region都有起始rowkey和结束rowkey,代表了它所存储的row范围

1.1、Region结构

Hbase基础篇

多个Store:每一个Region内都包含有多个Store实例。一个Store对应一个列族的数据,如果一个表有两个列族,那么在一个Region里面就有两个Store。在最右边的单个Store的解剖图上,我们可以看到Store内部有MemStore和HFile这两个组成部分。

1.1.1 Store 结构

  Hbase基础篇

MemStore:每个Store中有一个MemStore实例。数据写入WAL之后就会被放入MemStore。MemStore是内存的存储对象,只有当MemStore满了的时候才会将数据刷写(flush)到HFile中。

HFile:在Store中有多个HFile。当MemStore满了之后HBase就会在HDFS上生成一个新的HFile,然后把MemStore中的内容写到这个HFile中。HFile直接跟HDFS打交道,它是数据的存储实体

  WAL是存储在HDFS上的,Memstore是存储在内存中的,HFile又是存储在HDFS上的。数据是先写入WAL,再被放入Memstore,最后被持久化到HFile中。
数据在进入HFile之前已经被存储到HDFS一次了,为什么还需要被放入Memstore?
  这是因为HDFS上的文件只能创建、追加、删除,但是不能修改。那就是使用内存先把数据整理成顺序存放,然后再一起写入硬盘。这就是Memstore存在的意义。Memstore存在的意义是维持数据按照rowkey顺序排列,而不是做一个缓存

1.1.2 MemStore

  数据被写入WAL之后就会被加载到MemStore中去。MemStore的大小增加到超过一定阀值的时候就会被刷写到HDFS上,以HFile的形式被持久化起来

  (1)由于HDFS上的文件不可修改,为了让数据顺序存储从而提高读取效率,HBase使用了LSM树结构来存储数据。数据会先在Memstore中整理成LSM树,最后再刷写到HFile上。不过不要想当然地认为读取也是先读取Memstore再读取磁盘哟!读取的时候是有专门的缓存叫BlockCache,这个BlockCache如果开启了,就是先读BlockCache,读不到才是读HFile+Memstore,

  (2)优化数据的存储。比如一个数据添加后就马上删除了,这样在刷写的时候就可以直接不把这个数据写到HDFS上

  每一次的刷写都会产生一个全新的HFile文件,由于HDFS的特性,所以这个文件不可修改

  memstore内部存储使用的是跳表。Hbase属于LSM tree结构的数据库,LSM tree 结构的数据库有一个特点,实时写入的数据先写入内存,内存达到阈值再往磁盘flush的时候,会生成类似storFile的有序文件,而跳表就是天然有序的,所以在flush的时候效率很高,而且跳表查找、插入删除性能都很高,这个就是Hbase memstore内部存储使用跳表的原因之一。Hbase使用的是JUC下面的concurrentSkipListMap()

1.1.3 HFile

Hbase基础篇

  HFile是数据存储的实际载体,我们创建的所有表、列等数据都存储在HFile里面  

  我们可以看到HFile是由一个一个的块组成的。在HBase中一个块的大小默认为64KB,由列族上的BLOCKSIZE属性定义。
  Data:数据块。每个HFile有多个Data块。我们存储在HBase表中的数据就在这里。Data块其实是可选的,但是几乎很难看到不包含Data块的HFile。
  Meta:元数据块。Meta块是可选的,Meta块只有在文件关闭的时候才会写入。Meta块存储了该HFile文件的元数据信息,
  FileInfo:文件信息,其实也是一种数据存储块。FileInfo是HFile的必要组成部分,是必选的。它只有在文件关闭的时候写入,存储的是这个文件的信息,比如最后一个Key(LastKey),平均的Key长度(Avg Key Len)等。
  DataIndex:存储Data块索引信息的块文件。索引的信息其实也就是Data块的偏移值(offset)。DataIndex也是可选的,有Data块才有DataIndex。
  MetaIndex:存储Meta块索引信息的块文件。MetaIndex块也是可选的,有Meta块才有MetaIndex。
  Trailer:必选的,它存储了FileInfo、DataIndex、MetaIndex块的偏移值

   布隆过滤器:所有数据在Hbase中都以一个个HFile为单元来存储,一个HFile大小概为几百兆字节到几千兆字节,每一个检索请求到来的时候,扫描器都会从头到尾地扫描整个HFile。为了提高HFile的检索速度,HBase使用了块索引机制。原理就是在HFile中增加一个部分,单独存储该HFile中的所有行键,这样扫描器可以先通过检索块索引来查找行键,当找到行键后再去具体的位置获取该行的其他信息。

  布隆过滤器可以知道元素在集合中是否“不存在”或者“可能存在”,也就是说如果布隆过滤器认为该元素不存在,那么就是不存在。这样可以极大地加速检索的速度,因为当布隆过滤器认为要检索的数据不在该块索引中时,扫描器可以跳过那些绝对不需要扫描的块索引

  Hbase基础篇

1.2 WAL预写日志

预写日志(Write-ahead log,WAL)就是设计来解决宕机之后的操作恢复问题的。数据到达Region的时候是先写入WAL,然后再被加载到Memstore的。就算Region的机器宕掉了,由于WAL的数据是存储在HDFS上的,所以数据并不会丢失

延迟写入WAL:当你的改动,比如Put、Delete、Append来到Region的时候会先放在内存中,这些改动立刻就会被写入WAL。

Region会等到条件满足的时候才把操作写入WAL。这里提到的条件主要指的是时间间隔hbase.regionserver.optionallogflushinterval,这个时间间隔的意思是HBase间隔多久会把操作从内存写入WAL,默认值是1s

WAL滚动:WAL一定是一个环状的滚动日志结构,因为这种结构写入效果最高,而且可以保证空间不会持续变大。

WAL滚动的条件是:

  1、WAL的检查间隔由hbase.regionserver.logroll.period定义,默认值为1小时。检查的内容是把当前WAL中的操作跟实际持久化到HDFS(HFile中)上的操作比较,看哪些操作已经被持久化了,被持久化的操作就会被移动到.oldlogs文件夹内(这个文件夹也是在HDFS上的)。

  2、当WAL文件所在的块(Block)快要满了。

  3、当WAL所占的空间大于或者等于某个阀值:你如果是基于HDFS的,默认WAL所占块空间大于或等于95%块大小,这个WAL文件就会被归档到.oldlogs文件夹内

删除.oldlogs条件:  

  Master会负责定期地去清理.oldlogs文件夹,条件是“当这个WAL不需要作为用来恢复数据的备份”的时候。判断的条件是“没有任何引用指向这个WAL文件。

  1、TTL进程:该进程会保证WAL文件一直存活直到达到hbase.master.logcleaner.ttl定义的超时时间(默认10分钟)为止

       2、备份(replication)机制:如果你开启了HBase的备份机制,那么HBase要保证备份集群已经完全不需要这个WAL文件了,才会删除这个WAL文件。

二、增删改查

1、当你新增一个单元格的时候,HBase在HDFS上新增一条数据。

  2、当你修改一个单元格的时候,HBase在HDFS又新增一条数据,只是版本号比之前那个大(或者你自己定义)。

  3、当你删除一个单元格的时候,HBase还是新增一条数据!只是这条数据没有value,类型为DELETE,这条数据叫墓碑标记(Tombstone)。

  真正的删除数据

  Compaction会从一个region的一个store中选择一些hfile文件进行合并。合并说来原理很简单,先从这些待合并的数据文件中读出KeyValues,再按照由小到大排列后写入一个新的文件中。之后,这个新生成的文件就会取代之前待合并的所有文件对外提供服务。HBase根据合并规模将Compaction分为了两类:MinorCompaction和MajorCompaction

  由于数据库在使用过程中积累了很多增删查改操作,数据的连续性和顺序性必然会被破坏。为了提升性能,HBase每间隔一段时间都会进行一次合并(Compaction),合并的对象为HFile文件。合并分为两种minor compaction和major compaction。

  在HBase进行major compaction的时候,它会把多个HFile合并成1个HFile,在这个过程中,一旦检测到有被打上墓碑标记的记录,在合并的过程中就忽略这条记录。这样在新产生的HFile中,就没有这条记录了,自然也就相当于被真正地删除了

  Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile

三、总结归纳

  Hbase基础篇

1、一个RegionServer包含多个Region,划分规则是:一个表的一段键值在一个RegionServer上会产生一个Region。不过当你1行的数据量太大了(要非常大,否则默认都是不切分的),HBase也会把你的这个Region根据列族切分到不同的机器上去。

2、一个Region包含多个Store,划分规则是:一个列族分为一个Store,如果一个表只有一个列族,那么这个表在这个机器上的每一个Region里面都只有一个Store。

3、一个Store里面只有一个Memstore。

4、一个Store里面有多个HFile(StoreFile是HFile的抽象对象,所以如果说到StoreFile就等于HFile)。每次Memstore的刷写(flush)就产生一个新的HFile出来

写入和读出过程

1、写入

Hbase基础篇

WAL:数据被发出之后第一时间被写入WAL。由于WAL是基于HDFS来实现的,所以也可以说现在单元格就已经被持久化了,但是WAL只是一个暂存的日志,它是不区分Store的。这些数据是不能被直接读取和使用。
Memstore:数据随后会立即被放入Memstore中进行整理。Memstore会负责按照LSM树的结构来存放数据。这个过程就像我们在打牌的时候,抓牌之后在手上对牌进行整理的过程。
HFile:最后,当Memstore太大了达到尺寸上的阀值,或者达到了刷写时间间隔阀值的时候,HBaes会被这个Memstore的内容刷写到HDFS系统上,称为一个存储在硬盘上的HFile文件。至此,我们可以称为数据真正地被持久化到硬盘上,就算宕机,断电,数据也不会丢失了

2、读出

读取顺序是先从BlockCache中找数据,找不到了再去Memstore和HFile中查询数据

为了要过滤墓碑标记的数据,HBase的Scan操作在取到所需要的所有行键对应的信息之后还会继续扫描下去,直到被扫描的数据大于给出的限定条件为止,这样它才能知道哪些数据应该被返回给用户,而哪些应该被舍弃。所以你增加过滤条件也无法减少Scan遍历的行数,只有缩小STARTROW和ENDROW之间的行键范围才可以明显地加快扫描的速度。在Scan扫描的时候store会创建StoreScanner实例。StoreScanner会把MemStore和HFile结合起来扫描。其中红色块部分都是属于指定row的数据,Scan要把所有符合条件的StoreScanner都扫描过一遍之后才会返回数据给用户

1、客户端通过 ZooKeeper 以及-ROOT-表和.META.表找到目标数据所在的 RegionServer(就是 数据所在的 Region 的主机地址)

2、联系 RegionServer 查询目标数据

3、RegionServer 定位到目标数据所在的 Region,发出查询请求

4、在BlockCache中查找,命中则返回

5、Region 在 Memstore 中查找,命中则返回

6、如果在 Memstore 中找不到,则在 HFile 中扫描 为了能快速的判断要查询的数据在不在这个 HFile 中,应用了 BloomFilter

Hbase基础篇

Region 定位

(1)客户端先通过ZooKeeper的/hbase/meta-region-server节点查询到哪台RegionServer上有hbase:meta表。

(2)客户端连接含有hbase:meta表的RegionServer。hbase:meta表存储了所有Region的行键范围信息,通过这个表就可以查询出你要存取的rowkey属于哪个Region的范围里面,以及这个Region又是属于哪个RegionServer。

(3)获取这些信息后,客户端就可以直连其中一台拥有你要存取的rowkey的RegionServer,并直接对其操作。

(4)客户端会把meta信息缓存起来,下次操作就不需要进行以上加载hbase:meta的步骤了

  habse:meta.:是一张元数据表,它存储了所有Region的简要信息。.META.表中的一行记录就是一个Region,该行记录了该Region的起始行、结束行和该Region的连接信息,这样客户端就可以通过这个来判断需要的数据在哪个Region上。

Hbase基础篇

四、rowkey设计

1、reversing

初步设计出的RowKey在数据分布上不均匀,但RowKey尾部的数据却呈现出了良好的随机性,此时,可以考虑将RowKey的信息翻转,或者直接将尾部的bytes提前到RowKey的前部

缺点:场景利于Get但不利于Scan,因为数据在原RowKey上的自然顺序已被打乱

2、salting

Salting的原理是在原RowKey的前面添加固定长度的随机bytes,随机bytes能保障数据在所有Regions间的负载均衡

缺点:既然是随机bytes,基于原RowKey查询时无法获知随机bytes信息是什么,也就需要去各个可能的Regions中去查看。可见, Salting对于读取是糟糕的

3、hashing

基于RowKey的完整或部分数据进行Hash,而后将Hashing后的值完整替换原RowKey或部分替换RowKey的前缀部分

缺点:与Reversing类似, Hashing也不利于Scan,因为打乱了原RowKey的自然顺序。

五、Hbase优化

1、blockCache

一个RegionServer只有一个BlockCache。BlockCache不是数据存储的必要组成部分,是用来优化读取性能的;

Hbase基础篇

BlockCache的工作原理:读请求到HBase之后先尝试查询BlockCache,如果获取不到就去HFile(StoreFile)和Memstore中去获取。如果获取到了则在返回数据的同时把Block块缓存到BlockCache中。

几种BlockCache

   (1)LRUBlock Cache

    近期最少使用算法的缩写。读出来的block会被放到BlockCache中待下次查询使用。当缓存满了的时候,会根据LRU的算法来淘汰block。LRUBlockCache被分为三个区域:

    Hbase基础篇

   列族的IN-MEMORY:被设置为IN-MEMORY并不是意味着这个列簇是存储在内存中的,这个列簇依然是跟别的列簇一样存储在硬盘上,一般的Block被第一次读出后是放到single-access的,只有当被访问多次后才会放到multi-access,而带有IN-MEMORY属性的列族中的Block一开始就被放到in-memory区域。这个区域的缓存有最高的存活时间,在需要淘汰Block的时候,这个区域的Block是最后被考虑到的

  LRUBlockCache内存使用比例默认是0.4。要注意在Hbase内存使用上MemStore+BlockCache内存比例不能超过0.8,否则就会报错。

  使用完全基于JVM Heap的缓存带来的后果就是:内存中的对象越来越多,每隔一段时间就会发生FULL GC

  (2)Bucket Cache

  • BucketCache上来直接分配了14种区域,注意是14种,大小分别是4、8、16、32、40、48、56、64、96、128、192、256、384、512KB的block,且种类列表可以通过hbase.bucketcache.bucket.sizes属性来定义(种类之间用逗号分隔,不一定是14个)
  • BucketCache存储不一定使用堆外内存,可以使用堆(heap)、堆外(offheap)、文件(file)。可以通过hbase.bucketcache.ioengine为上述三个单词中的一个做配置
  • 每个Bucket的大小上限为最大尺寸的block * 4_,_比如设置最大的Block类型为512KB,那么每个Bucket最大为512KB * 4=2018KB
  • 要保证每一个block类型至少有一个Bucket的空间,否则直接报错,按照每个Bucket的大小上限均分为多个Bucket,之前的例子至少要保证2048KB*14这么大的存储空间

  Hbase基础篇

  BucketCache可以自己划分内存空间,自己管理内存空间,Block放进去的时候会考虑offset偏移量,所以内存碎片少,发生GC时间短

#使用的存储介质,可以为heap/offheap/file,默认offheap
hbase.bucketcache.ioengine
#是否打开组合模式,默认为true
hbase.bucketcache.combinedcache.enabled
#BucketCache所占大小,0.0-1.0代表站堆内存比例,大于1的值表示MB为单位的内存;默认为0.0,即关闭BucketCache
hbase.bucketcache.size
#定义所有的Block种类,单位为B,每一种类型必须是1024的整数倍
hbase.bucketcache.bucket.sizes
#该值不是在hbase-site.xml中配置,而是一个启动参数,默认按需获取堆外内存,如果配置了,就相当于设置了堆外内存上限
-XX:MaxDirectMemorySize

(3)组合模式

说就是把不同类型的Block分别放到LRUCache和BucketCache中。

  Index Block和Bloom Block会被放到LRUCache中。Data Block被直接放到BucketCache中,所以数据会去LRUCache查询一下,然后再去BucketCache中查询真正的数据。其实这种实现是一种更合理的二级缓存,数据从一级缓存到二级缓存最后到硬盘,数据是从小到大,存储介质也是由快到慢。考虑到成本和性能的组合,比较合理的介质是:LRUCache使用内存->BuckectCache使用SSD->HFile使用机械硬盘

如何看缓存命中率:看缓存的命中率,只需要打开hadoop metrics,查看hbase.regionserver.blockCacheHitRatio。该值的取值范围为0.0~1.0

六、Hbase问题

1、Hbase多列簇

每个regionServer有多个region,每个region有多个store。每个store包含一个memstore和多个storeFile

在Hbase表中,每个列簇对应region中的一个store,region的大小达到阈值会分裂,因此如果表中有多个列簇的时候,可能会出现以下情况

(1) 一个region中有多个store:如果每个CF的数据分布不均匀,比如CF1有100万,CF2有1万,则region分裂会导致CF2在每个region中数据量太少,查询CF2时候会横跨多个region导致效率变低

(2) 如果每个CF均匀分部:CF1为50万,CF250万,CF350万,则region分裂时候,导致每个CF在region的数据量偏少,查询某个CF时会导致很快多个Region的概率增大

(3)多个CF:有多个CF代表有多个store,也就是有多个memestore,也就是会导致内存的开销增大,使得效率降低

(4)缓存刷新和压缩:region中的缓存刷新和压缩是基本操作,即一个CF出现缓存刷新或压缩操作,其他CF也会做同一样的操作,当列簇太多时就会导致IO频繁

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这