首页 文章 精选 留言 我的

精选列表

搜索[数据库知识开放麦],共10000篇文章
优秀的个人博客,低调大师

史上最全的NB-IoT知识

通常,我们把物联网设备分为三类:①无需移动性,大数据量(上行),需较宽频段,比如城市监控摄像头。②移动性强,需执行频繁切换,小数据量,比如车队追踪管理。③无需移动性,小数据量,对时延不敏感,比如智能抄表。NB-IoT正是为了应对第③种物联网设备而生。NB-IoT源起于现阶段物联网的以下几大需求:•覆盖增强(增强20dB)•支持大规模连接,100K终端/200KHz小区•超低功耗,10年电池寿命•超低成本•最小化信令开销,尤其是空口。•确保整个系统的安全性,包括核心网。•支持IP和非IP数据传送。•支持短信(可选部署)。对于现有LTE网络,并不能完全满足以上需求。即使是LTE-A,关注的主要是载波聚合、双连接和D2D等功能,并没有考虑物联网。比如,在覆盖上,以水表为例,所处位置无线环境差,与智能手机相比,高度差导致信号差4dB,同时再盖上盖子,额外增加约10dB左右损耗,所以需要增强20dB。在大规模连接上,物联网设备太多,如果用现有的LTE网络去连接这些海量设备,会导致网络过载,即使传送的数据量小,可信令流量也够得喝上几壶。此外,NB-IoT有自己的特点,比如不再有QoS的概念,因为现阶段的NB-IoT并不打算传送时延敏感的数据包,像实时IMS一类的设备,在NB-IoT网络里不会出现。因此,3GPP另辟蹊径,在Release 13制定了NB-IoT标准来应对现阶段的物联网需求,在终端支持上也多了一个与NB-IoT对应的终端等级——cat-NB1。尽管NB-IoT和LTE紧密相关,且可集成于现有的LTE系统之上,很多地方是在LTE基础上专为物联网而优化设计,但从技术角度看,NB-IoT却是独立的新空口技术。今天,我们就来看看这一新空口技术到底有多新?1 网络1.1 核心网为了将物联网数据发送给应用,蜂窝物联网(CIoT)在EPS定义了两种优化方案:•CIoT EPS用户面功能优化(User Plane CIoT EPS optimisation)•CIoT EPS控制面功能优化(Control Plane CIoT EPS optimisation)如上图所示,红线表示CIoT EPS控制面功能优化方案,蓝线表示CIoT EPS用户面功能优化方案。对于CIoT EPS控制面功能优化,上行数据从eNB(CIoT RAN)传送至MME,在这里传输路径分为两个分支:或者通过SGW传送到PGW再传送到应用服务器,或者通过SCEF(Service Capa- bility Exposure Function)连接到应用服务器(CIoT Services),后者仅支持非IP数据传送。下行数据传送路径一样,只是方向相反。这一方案无需建立数据无线承载,数据包直接在信令无线承载上发送。因此,这一方案极适合非频发的小数据包传送。SCEF是专门为NB-IoT设计而新引入的,它用于在控制面上传送非IP数据包,并为鉴权等网络服务提供了一个抽象的接口。对于CIoT EPS用户面功能优化,物联网数据传送方式和传统数据流量一样,在无线承载上发送数据,由SGW传送到PGW再到应用服务器。因此,这种方案在建立连接时会产生额外开销,不过,它的优势是数据包序列传送更快。这一方案支持IP数据和非IP数据传送。1.2 接入网NB-IoT的接入网构架与LTE一样。eNB通过S1接口连接到MME/S-GW,只是接口上传送的是NB-IoT消息和数据。尽管NB-IoT没有定义切换,但在两个eNB之间依然有X2接口,X2接口使能UE在进入空闲状态后,快速启动resume流程,接入到其它eNB(resume流程将在本文后面详述)。1.3 频段NB-IoT沿用LTE定义的频段号,Release 13为NB-IoT指定了14个频段。2 物理层2.1 工作模式部署方式(Operation Modes)NB-IoT占用180KHz带宽,这与在LTE帧结构中一个资源块的带宽是一样的。所以,以下三种部署方式成为可能:1)独立部署(Stand alone operation)适合用于重耕GSM频段,GSM的信道带宽为200KHz,这刚好为NB-IoT 180KHz带宽辟出空间,且两边还有10KHz的保护间隔。2)保护带部署(Guard band operation)利用LTE边缘保护频带中未使用的180KHz带宽的资源块。3)带内部署(In-band operation)利用LTE载波中间的任何资源块。CE LevelCE Level,即覆盖增强等级(Coverage Enhancement Level)。从0到2,CE Level共三个等级,分别对应可对抗144dB、154dB、164dB的信号衰减。基站与NB-IoT终端之间会根据其所在的CE Level来选择相对应的信息重发次数。双工模式Release 13 NB-IoT仅支持FDD 半双工type-B模式。FDD意味着上行和下行在频率上分开,UE不会同时处理接收和发送。半双工设计意味着只需多一个切换器去改变发送和接收模式,比起全双工所需的元件,成本更低廉,且可降低电池能耗。在Release 12中,定义了半双工分为type A和type B两种类型,其中type B为Cat.0所用。在type A下,UE在发送上行信号时,其前面一个子帧的下行信号中最后一个Symbol不接收,用来作为保护时隙(Guard Period, GP),而在type B下,UE在发送上行信号时,其前面的子帧和后面的子帧都不接收下行信号,使得保护时隙加长,这对于设备的要求降低,且提高了信号的可靠性。2.2 下行链路对于下行链路,NB-IoT定义了三种物理信道:1)NPBCH,窄带物理广播信道。2)NPDCCH,窄带物理下行控制信道。3)NPDSCH,窄带物理下行共享信道。还定义了两种物理信号:1)NRS,窄带参考信号。2)NPSS和NSSS,主同步信号和辅同步信号。相比LTE,NB-IoT的下行物理信道较少,且去掉了PMCH(Physical Multicast channel,物理多播信道),原因是NB-IoT不提供多媒体广播/组播服务。下图是NB-IoT传输信道和物理信道之间的映射关系。MIB消息在NPBCH中传输,其余信令消息和数据在NPDSCH上传输,NPDCCH负责控制UE和eNB间的数据传输。NB-IoT下行调制方式为QPSK。NB-IoT下行最多支持两个天线端口(Antenna Port),AP0和AP1。和LTE一样,NB-IoT也有PCI(Physical Cell ID,物理小区标识),称为NCellID(Narrowband physical cell ID),一共定义了504个NCellID。帧和时隙结构和LTE循环前缀(Normal CP)物理资源块一样,在频域上由12个子载波(每个子载波宽度为15KHz)组成,在时域上由7个OFDM符号组成0.5ms的时隙,这样保证了和LTE的相容性,对于带内部署方式至关重要。每个时隙0.5ms,2个时隙就组成了一个子帧(SF),10个子帧组成一个无线帧(RF)。这就是NB-IoT的帧结构,依然和LTE一样。NRS(窄带参考信号)NRS(窄带参考信号),也称为导频信号,主要作用是下行信道质量测量估计,用于UE端的相干检测和解调。在用于广播和下行专用信道时,所有下行子帧都要传输NRS,无论有无数据传送。NB-IoT下行最多支持两个天线端口,NRS只能在一个天线端口或两个天线端口上传输,资源的位置在时间上与LTE的CRS(Cell-Specific Reference Signal,小区特定参考信号)错开,在频率上则与之相同,这样在带内部署(In-Band Operation)时,若检测到CRS,可与NRS共同使用来做信道估测。▲NRS资源位置同步信号NPSS为NB-IoT UE时间和频率同步提供参考信号,与LTE不同的是,NPSS中不携带任何小区信息,NSSS带有PCI。NPSS与NSSS在资源位置上避开了LTE的控制区域,其位置图如下:▲NPSS和NSSS资源位置NPSS的周期是10ms,NSSS的周期是20ms。NB-IoT UE在小区搜索时,会先检测NPSS,因此NPSS的设计为短的ZC(Zadoff-Chu)序列,这降低了初步信号检测和同步的复杂性。NBPBCHNBPBCH的TTI为640ms,承载MIB-NB(Narrowband Master Information Block),其余系统信息如SIB1-NB等承载于NPDSCH中。SIB1-NB为周期性出现,其余系统信息则由SIB1-NB中所带的排程信息做排程。和LTE一样,NB-PBCH端口数通过CRC mask识别,区别是NB-IOT最多只支持2端口。NB-IOT在解调MIB信息过程中确定小区天线端口数。在三种operation mode下,NB-PBCH均不使用前3个OFDM符号。In-band模式下NBPBCH假定存在4个LTE CRS端口,2个NRS端口进行速率匹配。▲NPBCH映射到子帧▲黄色小格表明NPBCH资源占用位置,洋红色表示NRS,紫色代表CRSNPDCCHNPDCCH中承载的是DCI(Downlink Control Information),包含一个或多个UE上的资源分配和其他的控制信息。UE需要首先解调NPDCCH中的DCI,然后才能够在相应的资源位置上解调属于UE自己的NPDSCH(包括广播消息,寻呼,UE的数据等)。NPDCCH包含了UL grant,以指示UE上行数据传输时所使用的资源。NPDCCH子帧设计如下图所示:▲浅绿色和深绿色代表NPDCCH使用的RE,紫色代表LTE CRS,蓝色代表NRS。上图表示在LTE单天线端口和NB-IoT2天线端口下in-band模式的映射NPDCCH的符号起始位置:对于in-band,如果是SIB子帧,起始位置为3,非SIB子帧,起始位置包含在SIB2-NB中;对于stand-alone和Guard band,起始位置统一为0。NPDCCH有别于LTE系统中的PDCCH的是,并非每个Subframe都有NPDCCH,而是周期性出现。NPDCCH有三种搜索空间(Search Space),分别用于排程一般数据传输、Random Access相关信息传输,以及寻呼(Paging)信息传输。各个Search Space有无线资源控制(RRC)配置相对应的最大重复次数Rmax,其Search Space的出现周期大小即为相应的Rmax与RRC层配置的一参数的乘积。RRC层也可配置一偏移(Offset)以调整Search Space的开始时间。在大部分的搜索空间配置中,所占用的资源大小为一PRB,仅有少数配置为占用6个Subcarrier。一个DCI中会带有该DCI的重传次数,以及DCI传送结束后至其所排程的NPDSCH或NPUSCH所需的延迟时间,NB-IoT UE即可使用此DCI所在的Search Space的开始时间,来推算DCI的结束时间以及排程的数据的开始时间,以进行数据的传送或接收。NPDSCHNPDSCH的子帧结构和NPDCCH一样。NPDSCH是用来传送下行数据以及系统信息,NPDSCH所占用的带宽是一整个PRB大小。一个传输块(Transport Block, TB)依据所使用的调制与编码策略(MCS),可能需要使用多于一个子帧来传输,因此在NPDCCH中接收到的Downlink Assignment中会包含一个TB对应的子帧数目以及重传次数指示。2.3 上行链路对于上行链路,NB-IoT定义了两种物理信道:1)NPUSCH,窄带物理上行共享信道。2)NPRACH,窄带物理随机接入信道。还有:1)DMRS,上行解调参考信号。NB-IoT上行传输信道和物理信道之间的映射关系如下图:除了NPRACH,所有数据都通过NPUSCH传输。时隙结构NB-IoT上行使用SC-FDMA,考虑到NB-IoT终端的低成本需求,在上行要支持单频(Single Tone)传输,子载波间隔除了原有的15KHz,还新制订了3.75KHz的子载波间隔,共48个子载波。当采用15KHz子载波间隔时,资源分配和LTE一样。当采用3.75KHz的子载波间隔时,如下图所示:15KHz为3.75KHz的整数倍,所以对LTE系统干扰较小。由于下行的帧结构与LTE相同,为了使上行与下行相容,子载波空间为3.75KHz的帧结构中,一个时隙同样包含7个Symbol,共2ms长,刚好是LTE时隙长度的4倍。此外,NB-IoT系统中的采样频率(Sampling Rate)为1.92MHz,子载波间隔为3.75KHz的帧结构中,一个Symbol的时间长度为512Ts(Sampling Duration),加上循环前缀(Cyclic Prefix, CP)长16Ts,共528Ts。因此,一个时隙包含7个Symbol再加上保护区间(Guard Period)共3840Ts,即2ms长。NPUSCHNPUSCH用来传送上行数据以及上行控制信息。NPUSCH传输可使用单频或多频传输。▲单频与多频传输在NPUSCH上,定义了两种格式:format 1和format 2。NPUSCH format 1 为UL-SCH上的上行信道数据而设计,其资源块不大于1000 bits;NPUSCH format 2传送上行控制信息(UCI)。映射到传输快的最小单元叫资源单元(RU,resource unit),它由NPUSCH格式和子载波空间决定。有别于LTE系统中的资源分配的基本单位为子帧,NB-IoT根据子载波和时隙数目来作为资源分配的基本单位,如下表所示:对于NPUSCH format 1,当子载波空间为3.75 kHz时,只支持单频传输,一个RU在频域上包含1个子载波,在时域上包含16个时隙,所以,一个RU的长度为32ms。当子载波空间为15kHz时,支持单频传输和多频传输,一个RU包含1个子载波和16个时隙,长度为8ms;当一个RU包含12个子载波时,则有2个时隙的时间长度,即1ms,此资源单位刚好是LTE系统中的一个子帧。资源单位的时间长度设计为2的幂次方,是为了更有效的运用资源,避免产生资源空隙而造成资源浪费。对于NPUSCH format 2,RU总是由1个子载波和4个时隙组成,所以,当子载波空间为3.75 kHz时,一个RU时长为8ms;当子载波空间为15kHz时,一个RU时长为2ms。对于NPUSCH format 2,调制方式为BPSK。对于NPUSCH format 1,调制方式分为以下两种情况:●包含一个子载波的RU,采用BPSK和QPSK。●其它情况下,采用QPSK。由于一个TB可能需要使用多个资源单位来传输,因此在NPDCCH中接收到的Uplink Grant中除了指示上行数据传输所使用的资源单位的子载波的索引(Index),也会包含一个TB对应的资源单位数目以及重传次数指示。NPUSCH Format 2是NB-IoT终端用来传送指示NPDSCH有无成功接收的HARQ-ACK/NACK,所使用的子载波的索引(Index)是在由对应的NPDSCH的下行分配(Downlink Assignment)中指示,重传次数则由RRC参数配置。DMRS根据NPUSCH格式,DMRS每时隙传输1个或者3个SC-FDMA符号。▲NPUSCH format 1。上图中,对于子载波空间为15 kHz ,一个RU占用了6个子载波。▲NPUSCH format 2,此格式下,RU通常只占一个子载波。NPRACH和LTE的Random Access Preamble使用ZC序列不同,NB-IoT的Random Access Preamble是单频传输(3.75KHz子载波),且使用的Symbol为一定值。一次的Random Access Preamble传送包含四个Symbol Group,一个Symbol Group是5个Symbol加上一CP,如下图:▲Radom Access Preamble Symbol Group每个Symbol Group之间会有跳频。选择传送的Random Access Preamble即是选择起始的子载波。基站会根据各个CE Level去配置相应的NPRACH资源,其流程如下图:▲NB-IoT Random Acces流程Random Access开始之前,NB-IoT终端会通过DL measurement(比如RSRP)来决定CE Level,并使用该CE Level指定的NPRACH资源。一旦Random Access Preamble传送失败,NB-IoT终端会在升级CE Level重新尝试,直到尝试完所有CE Level的NPRACH资源为止。3 小区接入NB-IoT的小区接入流程和LTE差不多:小区搜索取得频率和符号同步、获取SIB信息、启动随机接入流程建立RRC连接。当终端返回RRC_IDLE状态,当需要进行数据发送或收到寻呼时,也会再次启动随机接入流程。3.1 协议栈和信令承载总的来说,NB-IoT协议栈基于LTE设计,但是根据物联网的需求,去掉了一些不必要的功能,减少了协议栈处理流程的开销。因此,从协议栈的角度看,NB-IoT是新的空口协议。以无线承载(RB)为例,在LTE系统中,SRB(signalling radio bearers,信令无线承载)会部分复用,SRB0用来传输RRC消息,在逻辑信道CCCH上传输;而SRB1既用来传输RRC消息,也会包含NAS消息,其在逻辑信道DCCH上传输。LTE中还定义了SRB2,但NB-IoT没有。此外,NB-IoT还定义一种新的信令无线承载SRB1bis,SRB1bis和SRB1的配置基本一致,除了没有 PDCP,这也意味着在Control Plane CIoT EPS optimisation下只有SRB1bis,因为只有在这种模式才不需要。▲NB-IoT协议栈3.2 系统信息NB-IoT经过简化,去掉了一些对物联网不必要的SIB,只保留了8个:•SIBType1-NB:小区接入和选择,其它SIB调度•SIBType2-NB:无线资源分配信息•SIBType3-NB:小区重选信息•SIBType4-NB:Intra-frequency的邻近Cell相关信息•SIBType5-NB:Inter-frequency的邻近Cell相关信息•SIBType14-NB:接入禁止(Access Barring)•SIBType16-NB:GPS时间/世界标准时间信息需特别说明的是,SIB-NB是独立于LTE系统传送的,并非夹带在原LTE的SIB之中。3.3 小区重选和移动性由于NB-IoT主要为非频发小数据包流量而设计,所以RRC_CONNECTED中的切换过程并不需要,被移除了。如果需要改变服务小区,NB-IoT终端会进行RRC释放,进入RRC_IDLE状态,再重选至其他小区。在RRC_IDLE状态,小区重选定义了intra frequency和inter frequency两类小区,inter frequency指的是in-band operation下两个180 kHz载波之间的重选。NB-IoT的小区重选机制也做了适度的简化,由于NB-IoT 终端不支持紧急拨号功能,所以,当终端重选时无法找到Suitable Cell的情况下,终端不会暂时驻扎(Camp)在Acceptable Cell,而是持续搜寻直到找到Suitable Cell为止。根据3GPP TS 36.304定义,所谓Suitable Cell为可以提供正常服务的小区,而Acceptable Cell为仅能提供紧急服务的小区。3.4 随机接入过程NB-IoT的RACH过程和LTE一样,只是参数不同。基于竞争的NB-IOT随机接入过程基于非竞争的NB-IOT随机接入过程3.5 连接管理由于NB-IoT并不支持不同技术间的切换,所以RRC状态模式也非常简单。RRC Connection EstablishmentRRC Connection Establishment流程和LTE一样,但内容却不相同。很多原因都会引起RRC建立,但是,在NB-IoT中,RRCConnectionRequest中的Establishment Cause里没有delayTolerantAccess,因为NB-IOT被预先假设为容忍延迟的。另外,在Establishment Cause里,UE将说明支持单频或多频的能力。与LTE不同的是,NB-IoT新增了Suspend-Resume流程。当基站释放连接时,基站会下达指令让NB-IoT终端进入Suspend模式,该Suspend指令带有一组Resume ID,此时,终端进入Suspend模式并存储当前的AS context。当终端需要再次进行数据传输时,只需要在RRC Connection Resume Request中携带Resume ID(如上图第四步),基站即可通过此Resume ID来识别终端,并跳过相关配置信息交换,直接进入数据传输。简而言之,在RRC_Connected至RRC_IDLE状态时,NB-IoT终端会尽可能的保留RRC_Connected下所使用的无线资源分配和相关安全性配置,减少两种状态之间切换时所需的信息交换数量,以达到省电的目的。4 Data Transfer如前文所述,NB-IoT定义了两种数据传输模式:Control Plane CIoT EPS optimisation方案和User Plane CIoT EPS optimisation方案。对于数据发起方,由终端选择决定哪一种方案。对于数据接收方,由MME参考终端习惯,选择决定哪一种方案。4.1 Control Plane CIoT EPS Optimisation对于Control Plane CIoT EPS Optimisation,终端和基站间的数据交换在RRC级上完成。对于下行,数据包附带在RRCConnectionSetup消息里;对于上行,数据包附带在RRCConnectionSetupComplete消息里。如果数据量过大,RRC不能完成全部传输,将使用DLInformationTransfer和ULInformationTransfer消息继续传送。这两类消息中包含的是带有NAS消息的byte数组,其对应NB-IoT数据包,因此,对于基站是透明的,UE的RRC也会将它直接转发给上一层。在这种传输模式下,没有RRC connection reconfiguration流程,数据在RRC connection setup消息里传送,或者在RRC connection setup之后立即RRC connection release并启动resume流程。4.2 User Plane CIoT EPS optimisation在User Plane CIoT EPS optimisation模式下,数据通过传统的用户面传送,为了降低物联网终端的复杂性,只可以同时配置一个或两个DRB。此时,有两种情况:•当RRC连接释放时,RRC连接释放会携带携带Resume ID,并启动resume流程,如果resume成功,更新密匙安全建立后,保留了先前RRC_Connected的无线承载也随之建立。•当RRC连接释放时,如果RRC连接释放没有携带携带Resume ID,或者resume请求失败,安全和无线承载建立过程如下图所示:首先,通过SecurityModeCommand和SecurityModeComplete建立AS级安全。在SecurityModeCommand消息中,基站使用SRB1和DRB提供加密算法和对SRB1完整性保护。LTE中定义的所有算法都包含在NB-IoT里。当安全激活后,进入RRC connection reconfiguration流程建立DRBs。在重配置消息中,基站为UE提供无线承载,包括RLC和逻辑信道配置。PDCP仅配置于DRBs,因为SRB采用默认值。在MAC配置中,将提供BSR、SR、DRX等配置。最后,物理配置提供将数据映射到时隙和频率的参数。4.3 多载波配置在RRCConnectionReconfiguration消息中,可在上下行设置一个额外的载波,称为非锚定载波(non-anchor carrier)。基于多载波配置,系统可以在一个小区里同时提供多个载波服务,因此,NB-IoT的载波可以分为两类:提供NPSS、NSSS与承载NPBCH和系统信息的载波称为Anchor Carrier,其余的载波则称为Non-Anchor Carrier。当提供non-anchor载波时,UE在此载波上接收所有数据,但同步、广播和寻呼等消息只能在Anchor Carrier上接收。NB-IoT终端一律需要在Anchor Carrier上面Random Access,基站会在Random Access过程中传送Non-Anchor Carrier调度信息,以将终端卸载至Non-Anchor Carrier上进行后续数据传输,避免Anchor Carrier的无线资源吃紧。另外,单个NB-IoT终端同一时间只能在一个载波上传送数据,不允许同时在Anchor Carrier和Non-Anchor Carrier上传送数据。

优秀的个人博客,低调大师

Android应用开发—知识点汇总

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/voidreturn/article/details/77113335 获取Fragment的context: getActivity().getApplicationContext()或者getActivity() You can use getActivity(), which returns the activity associated with a fragment. The activity is a context (since Activity extends Context). 设置TextView的颜色setTextColor()的用法: setTextColor(0xff999faa); setTextColor(Color.parseColor("#999faa")) Android textView 动态设置字体大小,带单位: setTextSize(TypedValue.COMPLEX_UNIT_PX,22); setTextSize(TypedValue.COMPLEX_UNIT_SP,22); setTextSize(TypedValue.COMPLEX_UNIT_DIP,22); 初始化一个ArrayList<>并赋值: ArrayList<String> list = new ArrayList<String>() {{add("string1"); add("string2"); add("string3");}} setBackgroundDrawable和setBackgroundResource的区别: setBackgroundXXX的用处,设置View背景。 setBackgroundDrawable的参数为Drawable对象。 setBackgroundColor的参数为Color对象,比如说Color.Red为红色或 Color.rgb(255,0,0)来指定一个红色 setBackgroundResource的参数为资源ID,比如说R.drawable.icon 对于ImageView类有类似 setImageXXX 道理同上,setImageBitmap的参数为Bitmap对象,同时ImageView还支持矩阵对象,比如setImageMatrix的参数为Matrix对象。 Android延时执行接口: new Handler().postDelayed(new Runnable(){ @Override public void run() { func(); } }, 250); 查看Android系统服务命令: adb shell service list Activity有三种基本状态: Active:处于屏幕前景(当前task的栈顶Activity处于Active状态),同一时刻只能有一个Activity处于Active状态。 Paused状态:处于背景画面画面状态,失去了焦点,但依然是活动状态。 Stopped:不可见,但依然保持所有的状态和内存信息。 同一个Service的类在android中可以有多个实例吗? 不可以。Service的启动模式决定它不会在系统中存在多个实例,当有新的Intent传递过来的时候,android系统会直接使用已经存在的Service实例而不会重新创建,所以在android系统中的Service都是单例的。 但为什么在锤子手机上有好几个xstate service??? android继承activity和application有什么不同: 初学安卓,看到有些代码继承activity,有些继承application,不知有什么? Activty是UI界面的抽象,Application是应用程序的抽象。一个Application有若干个Activity组成。一般继承Application主要是做一些初始化以及获取全局Context的引用,每个用户界面都要继承自Acitivity。 Fragment中调用startActivityForResult: 注意要采用fragment的startActivityForResult,而不要通过activity调用,否则activity的onActivityResult回被回调,fragment不会被调用,这样start和onResult就分离了。 目前还没有遇到这个问题,先收藏着 彻底搞懂startActivityForResult在FragmentActivity和Fragment中的异同 浅谈Android Fragment嵌套使用存在的一些BUG以及解决方法 去除字符串中的标点符号 public static String removePunct(String s) { String str = s.replaceAll("[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……& amp;*()——+|{}【】‘;:”“’。,、?|-]", ""); str = str.replace("\"", ""); return str; } 判断字符串中是否都是中文字符 public static boolean isChinese(String string) { String regex = "^[\u4E00-\u9FA5]+$"; Pattern pattern = Pattern.compile(regex); Matcher match = pattern.matcher(string); return match.matches(); } 令人厌恶的Bundles 摘录自Android 中 EventBus 的使用(2):缓存事件 “我在上一篇文章中曾说过,我并不喜欢Android中的Bundle,而且尽量避免使用它们。我不喜欢被象Serializable或者是Parcelable这类对象所约束,尤其是它们还缺少对类型安全的检查。我的意思是必竟这是Java,而不是Python或者Javascript什么的。我希望我的IDE能够发现并告诉我这样的错误,如一个组件向另外一个组件发送了一个不是它期望的对象类型。 不要误会,Intent在进程间通信时还是很有用的,在这种情况下将携带的数据序列化成通用格式是合情合理的。但如果仅仅是为了在用户旋转了一下屏幕后,让程序保持原来的状态,以科学的名义说,有必要非得用这种方法么?没错,我说的就是Android提供的处理配置改变的标准模式——在onSaveInstanceState(Bundle bundle)和onRestoreInstanceState(Bundle bundle)中保存和恢复状态数据。且不提那些荒唐复杂的Fragment生命周期问题,单单是保持运行状态的这种处理方式就是我最不喜欢的Android开发特点之一。” 刚刚遇到了类似问题:Parcel android.os.Parcel@dbaf03f: Unmarshalling unknown type code 2131625126 at offset 1308 导致了crash XXXX info = mXXXXList.get(position); if (info == null) { return; } Intent intent = new Intent(XXXXActivity.this, XXXXActivity.class); intent.putExtra(XXX.KEY_SOUND_INFO, info); if (intent != null) { mXXXX = (XXXX) intent.getSerializableExtra(XXX.KEY_SOUND_INFO); } 由于Serializable导致的问题,出现几率比较小,目前还没找到原因。 AsyncTask, Loader和Executor…… 拜托! 摘录自Android 中 EventBus 的使用(3):多线程事件处理 Android中有很多种执行异步操作的方法(指平行于UI线程的)。AsyncTask对于用户来说是最简单的一种机制,并且只需要少量的设置代码即可。然而,它的使用是有局限的,正如Android官方文档中所描述的: AsyncTask被设计成为一个工具类,在它内部包含了Thread和Handler,但它本身并不是通用线程框架的一部分。AsyncTask应该尽可能地被用在执行一些较短的操作中(最多几秒)。如果你需要在线程中执行较长时间的任务,那么建议你直接使用java.util.concurrent包中提供的各种API,如Executor、 ThreadPoolExecutor以及FutureTask。 不过即便是执行短时间的操作也会带来一些问题,特别是在与Activity/Fragment生命周期有关的地方。由于AsyncTask会持续地运行下去(即使启动它们的Activity/Fragment已经被销毁了)。这样,一旦你在onPostExecute方法中试图对UI进行更新,那么最终将导致抛出一个IllegalStateException异常。 Android 3.0中引入了Loader API用来解决Activity/Fragment生命周期的问题(它们的确很有效)。Loader API被设计成向Activity/Fragment中以异步方式加载数据。尽管加载数据是一种非常常见的异步操作,但并非唯一一种需要从UI线程中分开的操作。Loader还需要在Activity/Fragment中实现另外一个监听接口。尽管这么做没有错,但我个人并不喜欢这种模式(我的意思是最终你的代码中会包含许多的回调函数,导致代码的可读性变得很差)。最后,Activity和Fragment也并非唯一需要对异步操作分线程的地方。例如如果在Service里,你就不能访问LoaderManager,所以最终你还是得使用AsyncTask或者java.util.concurrent。 java.util.concurrent包很不错,我在Android和非Android项目中都可以使用。不过使用时需要对其进行多一点儿配置和管理,不象AsyncTask那么简单。你需要对ExecutorService进行初始化,管理和监视它的生命周期,并且可能需要跟一些Future对象打交道。 只要使用恰当,AsyncTask、 Loader和Executor都是非常有效的。但在复杂应用中,需要为每个任务选择合适的工具,最终你可能三种都会用到。这样你就得维护三种不同的处理并发的框架代码。 RelativeLayout布局内组件设置居中 备忘 android:layout_centerVertical="true" 设置渐变色的背景 设置背景色可以通过在res/drawable里定义一个xml,如下: xxx.xml <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <item> <shape> <gradient android:angle="0" android:endColor="#28d5fa" android:startColor="#0083fa" android:type="linear" /> </shape> </item> </layer-list> 引用: <RelativeLayout android:id="@+id/va_voice_print_step_ll" android:layout_width="match_parent" android:layout_height="149dp" android:background="@drawable/xxx"> </RelativeLayout> shape:定义形状(主要包括方形、圆形等);gradient:定义该形状里面为渐变色填充;startColor:起始颜色;endColor:结束颜色;angle:表示方向角度。(当angle=0时,渐变色是从左向右。 然后逆时针方向转,当angle=90时为从下往上)。 gradient主要配置起点颜色、终点颜色、中间点的坐标、中间点的颜色、渐变角度(90度为上下渐变,0为左右渐变); padding主要配置上下左右边距; corners节点配置四周园角的半径; 参考链接:Android (shape,gradient)使用总结,android 背景渐变色(shape,gradient) 如果在Android中判断某个线程是否是主线程? public static boolean isInMainThread() { return Looper.myLooper() == Looper.getMainLooper(); } EditText中灰色文字提示 android:hint="请输入xx" 如何查看Activity Task栈的情况 adb shell dumpsys activity activities adb shell dumpsys activity top 打开app对应设置通知中心 public void openNotificationSettings() { try { Intent intent = new Intent(); intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) { intent.putExtra("android.provider.extra.APP_PACKAGE", context.getPackageName()); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { intent.putExtra("app_package", context.getPackageName()); intent.putExtra("app_uid", context.getApplicationInfo().uid); } intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } catch (Exception e) { e.printStackTrace(); } } gradle里面的cached module文件位置 ~/.gradle/caches/modules-2/files-2.1/com.ali* 判断app是否在前台运行 public boolean isAppOnForeground() { // Returns a list of application processes that are running on the // device ActivityManager activityManager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); String packageName = getApplicationContext().getPackageName(); List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager .getRunningAppProcesses(); if (appProcesses == null) return false; for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { // The name of the process that this object is associated with. if (appProcess.processName.equals(packageName) && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return true; } } return false; } Activity内使用Broadcast接收消息 大部分的Broadcast示例都是新建一个class继承BroadcastReceiver来说明Broadcast的使用,但是这个class中接收到的消息,如何进行后续处理呢?其实大部分情况下是希望在activity中通过Broadcast接收消息,做一些后续的处理工作,而如果在一个新建的继承自BroadcastReceiver的class中,如何和某个Activity通讯,这是一个悖论,消息发生源传递给Broadcast,Broadcast再传递给Activity,后一步要采用什么通讯方式呢?为什么不消息发生源不直接发生消息给Activity呢? 由于大部分示例都是在一个新的class中进行,导致我一度认为Broadcast只能写在class里。后来发现可以通过动态注册的方式直接new一个BroadcastReceiver的方式,写在Activity内部,由于BroadcastReceiver在Activity内部,BroadcastReceiver中onReceive()即可操作Activity内数据和控件,实现Activity接受消息的目的。 private BroadcastReceiver mSearchRequestReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //do somethings } } }; @Override public void onResume() { super.onResume(); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); lbm.registerReceiver(mSearchRequestReceiver, new IntentFilter(SEARCH_REQUEST_BROADCAST_ACTION)); } @Override protected void onPause() { super.onPause(); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); lbm.unregisterReceiver(mSearchRequestReceiver); } 判断当前线程是否是Ui线程: public static boolean isMainThread() { return Thread.currentThread() == Looper.getMainLooper().getThread(); } Glide.with()使用 with(Context context):使用Application上下文,Glide请求将不受Activity/Fragment生命周期控制。 with(Activity activity):使用Activity作为上下文,Glide的请求会受到Activity生命周期控制。 with(FragmentActivity activity):Glide的请求会受到FragmentActivity生命周期控制。 with(android.app.Fragment fragment):Glide的请求会受到Fragment 生命周期控制。 with(android.support.v4.app.Fragment fragment):Glide的请求会受到Fragment生命周期控制。

优秀的个人博客,低调大师

新手必读:OpenStack基础知识介绍

为了更好的理解,我们首先来说一下云计算的类型。根据所提供服务的类型,云计算有以下三种落地方式: 1、Iaas(基础架构即服务),用户能从中申请到硬件或虚拟硬件,包括裸机或虚拟机,然后在上边安装操作系统或其他应用程序。 2、PaaS(平台即服务),用户能从中申请到一个安装了操作系统以及支撑应用程序运行所需要的运行库等软件的物理机或虚拟机,然后在上边安装其他应用程序,但不能修改已经预装好的操作系统和运行环境。 3、SaaS(软件即服务),用户可以通过网络以租赁的方式来使用一些软件,而不是购买,比较常见的模式是提供一组账号密码。 OpenStack就是一种IaaS。2010年7月,RackSpace和美国国家航空航天局合作,分别贡献出RackSpace云文件平台代码和NASA Nebula平台代码,并以Apache许可证开源发布了OpenStack,OpenStack由此诞生。OpenStack第一版的代号为 Austin,以RackSpace所在的美国德州Texas首府命名,计划每隔几个月发布一个全新的版本,并且以26个英文字母为首字母从A到Z顺序命名后面的版本。第一版仅有Swift和Nova两个项目。 2011年2月,OpenStack社区发布了Bexar版本,这是OpenStack的第二版,新增了Glance来提供镜像服务。 2011年4月,OpenStack社区发布了更加稳定的Cactus版本,但是这个版本没有新的项目。 2011年9月,OpenStack发布了它的第四个版本Diablo,从此OpenStack的版本更新定为每半年一次,分别是当年的春秋两季。 ……. OpenStack目前共涵盖了七个核心组件,分别是计算(Compute)、对象存储(Object Storage)、认证(Identity)、用户界面(Dashboard)、块存储(Block Storage)、网络(Network)和镜像服务(Image Service)。每个组件都是多个服务的集合,一个服务意味着运行着的一个进程。 Compute(Nova)Compute的项目代号是Nova,他根据需求提供虚拟机服务,比如创建虚拟机或对虚拟机做热迁移等。 Object Storage(Swift)它允许存储或检索对象,也可以认为它允许存储或检索文件,它能以低成本的方式管理大量无结构数据。 Identity(Keystone)为所有OpenStack服务提供身份验证和授权,跟踪用户以及他们的权限,提供一个可用服务及API列表。 DashBoard(Horizon)它为所有OpenStack的服务提供一个模块化的基于Django的界面,通过这个界面,不论是最终用户还是运维人员都可以完成大多数的操作,比如启动虚拟机,分配IP地址,动态迁移等。 Block Storage(Cinder)提供块存储服务 Network(Neutron)用于提供网络连接服务,允许用户创建自己的虚拟网络并连接各种网络设备接口。 ImageService(Glance)提供一个虚拟机镜像的存储、查询和检索服务,通过提供一个虚拟磁盘映像的目录和存储库,为Nova虚拟机提供镜像服务。 下面以创建虚拟机为例说明一下各个组件之间是如何相互配合完成工作的。用户首先接触到的是界面,也就是Horizon。通过Horizon上的简单界面操作,一个创建虚拟机的请求被发送到OpenStack系统后端。既然要启动一个虚拟机,就必须指定虚拟机操作系统是什么类型,就必须下载启动镜像以供虚拟机启动使用,这件事情就有Glance来完成的,而此时Glance所管理的镜像是有可能存储在Swift上的,所以需要与Swift交互得到需要的镜像文件。 在创建虚拟机的时候,自然而然地需要Cinder提供块服务和Neutron提供网络服务,以便该虚拟机有volume可以使用,能被分配到IP 地址与外界网络连接,而且之后改虚拟机资源的访问要经过KeyStone的认证之后才可以继续。至此,OpenStack的所有核心组件都参与了这个创建虚拟机的操作。 本文作者:佚名 来源:51CTO

优秀的个人博客,低调大师

Spark MLlib知识点学习整理

MLlib的设计原理:把数据以RDD的形式表示,然后在分布式数据集上调用各种算法。MLlib就是RDD上一系列可供调用的函数的集合。 操作步骤: 1、用字符串RDD来表示信息。 2、运行MLlib中的一个特征提取算法来吧文本数据转换为数值的特征。给操作会返回一个向量RDD。 3、对向量RDD调用分类算法,返回一个模型对象,可以使用该对象对新的数据点进行分类。 4、使用MLlib的评估函数在测试数据集上评估模型。 机器学习基础: 机器学习算法尝试根据 训练数据 使得表示算法行为的数学目标最大化,并以此来进行预测或作出决定。包括分类、回归、聚类,每种都有不一样的目标。 所有的学习算法都需要定义每个数据点的特征集,也就是传给学习函数的值。 更重要的在于如何去正确的定义特征。 例如: 在产品推荐的任务中,仅仅机上一个额外的特征(推荐给用户的书籍也可能取决于用户看过的电影),就有可能极大地改进结果。 当数据已成为特征向量的形式后,大多数机器学习算法会根据这些向量优化一个定义好的数学模型。 然后算法会再运行结束时返回一个代表学习决定的模型。 MLlib数据类型 1、Vector 一个数学向量。MLlib既支持稠密向量也支持稀疏向量。前者表示向量的每一位都存储下来,后者则存储非零位以节省空间。 稠密向量:把所有唯独的值存放在一个浮点整数组中。 稀疏向量只把各维度中的非零值存储下来。当最多只有10%的元素为非零元素时,通常更倾向于使用稀疏向量。 spark中创建向量的方式有 import org.apache.spark.mllib.linalg.Vectors //创建稠密向量<1.0,2.0,3.0>;Vectors.dense接收一串值或一个数组 val denseVec1 = Vectors.dense(1.0,2.0,3.0)) val denseVec2 = Vectors.dense(Array(1.0,2.0,3.0)) //创建稀疏向量<1.0,0.0,2.0,0.0> 向量的维度(4) 以及非零位的位置和对应的值 val sparseVec1 = Vectors.sparse(4,Array(0,2),Array(1.0,2.0)) 2、LabeledPoint 诸如分类和回归的算法这样的监督学习算法中,LabeledPoint用来表示带标签的数据点。它包含一个特征向量与一个标签(由一个浮点数表示),位置在mllib.regression包中。 3、Rating 用户对一个产品的评分,在mllib.recomendation包中,用于产品推荐。 4、各种Model类 每个Model都是训练算法的结果,一般有一个predict()方法可以用来对新的数据点或数据点组成的RDD应用该模型进行预测。 特征转化: TF-IDF:词频,逆文档频率是一种用来从文本文档中生成特征向量的简单方法。它为文档中的每个词计算两个统计值:一个是词频(TF),也就是每个词在文档中出现的次数,另一个是逆文档频率(IDF),用来衡量一个词语特定文档的相关度。 MLlib有两个算法可以用来计算TF-IDF:HashTF和TF HashTF从一个文档中计算出给定大小的词频向量。为了将词和向量顺序对应起来,所以使用了哈希。HashingTF使用每个单词对所需向量的长度S取模得出的哈希值,把所有单词映射到一个0到S-1之间的数字上。由此可以保证生成一个S维的向量。随后当构建好词频向量后,使用IDF来计算逆文档频率,然后将它们与词频相乘计算TF-IDF。 MLlib统计 1、Statistics.colStats(rdd) 计算由向量组成的RDD的统计性综述,保存着向量集合中每列的最大值、最小值、平均值和方差。 2、statistics.corr(rdd,method_ 计算由向量组成的RDD中的列间的相关矩阵,使用皮卡森相关或斯皮尔曼相关中的一种。 3、statistics.corr(rdd1,rdd2,method) 计算两个由浮点值组成的RDD的相关矩阵。 4、Statistics.chiSqTest(rdd) 计算由LabeledPoint对象组成的RDD中每个特征与标签的皮卡森独立性测试结果。返回一个ChiSqTestResult对象,其中有p值、测试统计及每个特征的自由度。 分类与回归 监督试学习指算法尝试使用有标签的训练数据(已知结果的数据点)根据对象的特征预测的结果。在分类中,预测出的变量是离散的(就是一个在有限集中的值,叫做类别) 。比如,分类可能是将邮件文卫垃圾邮件和非垃圾邮件,也有可能是文本所使用的语言。在回归中,预测出的是变量是连续的(根据年龄和体重预测一个人的身高) 线性回归: 1、numIteratrions 要运行的迭代次数(默认值:100) 2、stepSize 梯度下降的步长(默认值:1.0) 3、intercept 是否给数据加上一个干扰特征或者偏差特征--也就是一个值始终未1的特征(默认值:false) 4、regParam Lasso和ridge的正规化参数(默认值:1.0) import org.apache.spark.mllib.regression.LabeledPoint import org.apache.spark.mllib.regression.LinearRegressionWithSGD val points: RDD[LabeledPoint] = //.. val lr = new LinearRegressiionWithSGD().setNumIterations(200).setIntercept(true) val model = lr.run(points) println("weight: %s, intercept: %s".format(model.weights, model.intercept)) 逻辑回归 用来寻找一个分割阴性和阳性示例的线性分割平面。在MLlib中,接收一组标签为0或1的LabeledPoint,返回可以预测新点的分类的LogisticRegressionModel对象。 决策树与随机深林 决策树是一个灵活的模型,可以用来进行分类,也可以用来进行回归。决策树以节点树的形式表示,每个节点基于数据的特征作出一个二元决定(比如这个人的年龄是否大于20?),而树的每个叶节点则包含一种预测结果(例如,这个人是不是会买一个产品?)决策树的吸引力在于模型本身容易检查,而且决策树既支持分类的特征,也支持连续的特征。 参考于:《Spark快速大数据分析》

优秀的个人博客,低调大师

oracle点知识8——索引组织表

关于索引的入门参照博客:http://blog.csdn.net/changyanmanman/article/details/7097318 索引组织表(index organizedtable, IOT)就是存储在一个索引结构中的表。存储在堆中的表是无组织的(也就是说,只要有可用的空间,数据可以放在任何地方),IOT中的数据则按主键存储和排序。对你的应用来说,IOT表和一个“常规”表并无二致。 IOT有什么意义呢?使用堆组织表时,我们必须为表和表主键上的索引分别留出空间。而IOT不存在主键的空间开销,因为索引就是数据,数据就是索引,二者已经合二为一。 但是,IOT带来的好处并不止于节约了磁盘空间的占用,更重要的是大幅度降低了I/O,减少了访问缓冲区缓存(尽管从缓冲区缓存获取数据比从硬盘读要快得多,但缓冲区缓存并不免费,而且也绝对不是廉价的。每个缓冲区缓存获取都需要缓冲区缓存的多个闩,而闩是串行化设备,会限制应用的扩展能力)IOT适用的场合有: 1、完全由主键组成的表。这样的表如果采用堆组织表,则表本身完全是多余的开销,因为所有的数据全部同样也保存在索引里,此时,堆表是没用的。 2、代码查找表。如果你只会通过一个主键来访问一个表,这个表就非常适合实现为IOT. 3、如果你想保证数据存储在某个位置上,或者希望数据以某种特定的顺序物理存储,IOT就是一种合适的结构。 IOT提供如下的好处: ·提高缓冲区缓存效率,因为给定查询在缓存中需要的块更少。 ·减少缓冲区缓存访问,这会改善可扩缩性。 ·获取数据的工作总量更少,因为获取数据更快。 ·每个查询完成的物理I/O更少。 如果经常在一个主键或唯一键上使用between查询,也是如此。如果数据有序地物理存储,就能提升这些查询的性能。 索引组织表的创建格式如下: createtableindexTable( IDvarchar2(10), NAMEvarchar2(20), constraintpk_idprimarykey(ID) ) organizationindex; 注意两点: ● 创建IOT时,必须要设定主键,否则报错。 ● 索引组织表实际上将所有数据都放入了索引中。 索引组织表属性 1、OVERFLOW子句(行溢出) 因为所有数据都放入索引,所以当表的数据量很大时,会降低索引组织表的查询性能。此时设置溢出段将主键和溢出数据分开来存储以提高效率。溢出段的设置有两种格式: PCTTHRESHOLD n:制定一个数据块的百分比,当行数据占用大小超出时,该行的其他列数据放入溢出段 INCLUDING column_name:指定列之前的列都放入索引块,之后的列都放到溢出段 ● 当行中某字段的数据量无法确定时使用PCTTHRESHOLD。 ● 若所有行均超出PCTTHRESHOLD规定大小,则考虑使用INCLUDING。 createtablet88( IDvarchar2(10), NAMEvarchar2(20), constraintpk_idprimarykey(ID) ) organizationindex PCTTHRESHOLD20 overflowtablespaceusers INCLUDINGname; ● 如上例所示,name及之后的列必然被放入溢出列,而其他列根据PCTTHRESHOLD规则。 2、COMPRESS子句(键压缩) 与普通的索引一样,索引组织表也可以使用COMPRESS子句进行键压缩以消除重复值。 具体的操作是,在organization index之后加上COMPRESSn子句 ● n的意义在于:指定压缩的列数。默认为无穷大。 例如对于数据(1,2,3)、(1,2,4)、(1,2,5)、(1,3,4)、(1,3,5)时 若使用COMPRESS则会将重复出现的(1,2)、(1,3)进行压缩 若使用COMPRESS 1时,只对数据(1)进行压缩 索引组织表的维护 索引组织表可以和普通堆表一样进行INSERT、UPDATE、DELETE、SELECT操作。 可使用ALTER TABLE ... OVERFLOW语句来更改溢出段的属性。 alter tablet88add overflow;--新增一个overflow ● 要ALTER任何OVERVIEW的属性,都必须先定义overflow,若建表时没有可以新增 alter tablet88pctthreshold 15 including name;--调整overflow的参数 alter tablet88initrans 2 overflow initrans 4;--修改数据块和溢出段的initrans特性 ● 关于initrans的概念参考http://space.itpub.net/265709/viewspace-166534 索引组织表的应用 Heap Table 就是一般的表,获取表中的数据是按命中率来得到的。没有明确的先后之分,在进行全表扫描的时候,并不是先插入的数据就先获取。数据的存放也是随机的,当然根据可用空闲的空间来决定。 IOT就是类似一个全是索引的表,表中的所有字段都放在索引上,所以就等于是约定了数据存放的时候是按照严格规定的,在数据插入以前其实就已经确定了其位置,所以不管插入的先后顺序,它在那个物理上的那个位置与插入的先后顺序无关。这样在进行查询的时候就可以少访问很多blocks,但是插入的时候,速度就比普通的表要慢一些。 适用于信息检索、空间和OLAP程序。 索引组织表的适用情况:1、 代码查找表。 2、 经常通过主码访问的表。 3、 构建自己的索引结构。 4、 加强数据的共同定位,要数据按特定顺序物理存储。 5、 经常用between…and…对主码或唯一码进行查询。数据物理上分类查询。如一张订单表,按日期装载数据,想查单个客户不同时期的订货和统计情况。 经常更新的表当然不适合IOT,因为oracle需要不断维护索引,而且由于字段多索引成本就大。 如果不是经常使用主键访问表,就不要使用IOT 索引组织表中的二次索引: 在索引表上建立二次索引(secondary index)访问索引组织表的非主键列或者非主键前缀列的性能将得到提高。 oracle为索引组织表建立的二次索引是建立在逻辑ROWID上面的,什么是逻辑rowid呢?其实就是根据索引组织表的主键生成的rowid,它不是存储位置的实际rowid,oracle能够根据这个逻辑rowid进行 物理推测 找到索引项在索引块中的实际(物理)位置。(捋一下思路:二次索引建立在逻辑rowid上,rowid能推测出数据在索引块的实际位置)这样就能访问索引块了。可以省略通过索引主键来访问的步骤,减少I/O. 但是有一个很明显的问题,就是因为索引组织表的数据行没有固定的物理地址,当索引项被移动到新的物理块时,就还需要再执行主键搜索。 对一个常规表来说,通过间接索引(secondary index)访问表数据意味着先扫描间接索引再获取包含所需数据行的数据块(data block)。而对于索引表(index-organized table)来说,通过间接索引访问表数据的步骤依据是否使用物理推测(physical guess),及物理推测的准确度而有所不同: 如不使用物理推测,数据访问需要两次索引扫描:首先扫描间接索引,再依据其结果扫描主键索引(primary key index)。 如使用物理推测且推测结果准确,数据访问需要首先扫描间接索引,再进行 I/O 操作获取包含所需数据行的数据块。 如使用物理推测且推测结果不准确,数据访问需要首先扫描间接索引,并根据物理推测执行 I/O 操作获取了错误的数据块,之后再进行主键索引扫描。 索引组织表的位图索引: Oracle 支持在分区的(partitioned)或非分区的(nonpartitioned)索引表(index-organized table)上创建位图索引(bitmap index)。为索引表创建位图索引时需要使用一个映射表(mapping table)。 映射表:这个表的存储结构式按照堆组织表存储的,它用来存储索引组织表的逻辑ROWID,具体说来,就是映射表在每一行中存储一个索引组织表的逻辑rowid,这一映射表自己的每一行的物理rowid与索引组织表的逻辑rowid就建立了一一对应的关系。 建立在索引组织表上的位图索引与建立在堆表上的位图索引十分相似,只不过这里索引组织表使用了映射表中的物理rowid,而堆表直接直接使物理rowid与实际数据对应,IOT中间多了一层映射表,每个iot只需一个映射表就把所有的逻辑rowid存储到物理的映射表中。建立在IOT中的上的多个位图可以共用一个映射表。(这里我在想,不管是IOT还是堆组织表,都是根据索引键的值做的位图索引,比如用性别列做索引,有男,女两个位图,搜索的时候不管是IOT还是堆表,都是一样的根据搜索条件去位图置位表里选择,然后堆表直接找到置位对应的物理rowid,IOT通过映射找到逻辑rowid进行访问) 无论是堆表(heap-organized)还是索引表(index-organized),都会使用搜索键(search key)来检索位图索引(bitmap index)。如果在位图索引中找到了符合条件的记录,这个位图索引项(bitmap index entry)将被转换为物理 rowid(physical rowid)。对于堆表,Oracle 将使用此物理 rowid 访问基表(base table)。而对于索引表,Oracle 将使用此物理 rowid 访问映射表(mapping table)得到逻辑 rowid(logical rowid),再通过逻辑 rowid 访问索引表。 索引表(index-organized table)的数据行发生了移动后,不会导致建立在其上的位图索引(bitmap index)失效。数据行移动后会导致使用映射表(mapping table)中某些逻辑 rowid(logical rowid)进行物理推测(physical guess)时不准确。但是索引表仍旧可以通过主键(primary key)访问。 数据段和索引段:http://blog.csdn.net/changyanmanman/article/details/7270361 索引总结:http://blog.csdn.net/changyanmanman/article/details/7337020

优秀的个人博客,低调大师

ios 工程配置统一增加类的前缀(知识点也只能算知识点)

在前边的代码规范中提及:团队开发或者个人开发为了打包或者自己工程中避免创建新的类核第三方系统的重复增加类的统一前缀!!又很多人问我这种开发小技巧。下面我就普及一下: 1.首先选中你的工程配置 2.然后点击开发空间的右侧 3.在project document 中的class prefix 中加入你们团队个性的前缀就好了!

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册