专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

实现自己的数据库一

  一前言
  从上篇原创文章到现在又是新的一年,今天是2023年的大年初三,先在这里祝各位亲爱的老铁们新年快乐,身体健康,在新的一年里更帅气、更漂亮,都能完成自己的小目标。
  一直以来,我对数据存储还是比较感兴趣的,计算机从大的抽象层次来说,只干了三件事情,存入数据,计算,输出数据。所以数据的存储和搜索可以说是占据计算机的大半功能了。在工作中,也自己设计过一些存储和索引,不过是简单的哈希表的结构存储,对以B树为核心的数据库一直挺有兴趣,所以翻找了一些原理文章和源码研究了下,虽然原理看的不少,但是总觉得没有动手亲自写过还是学习的不够深刻,同时在github上找到了一步步写简单db的项目,于是开始借鉴学习后(代码参考后有所改进)有了这一系列文章。
  这次也不定啥目标了,怕坑挖大了,填不完,能写多少就写多少吧,同时希望自己写的这个开源,并将自己以后所学所知的一些优化的技巧应用在这上面,当一个练手的小项目吧,不要相信题目,题目只是吸引大家进来的,请原谅我厚着脸皮起的这么大的题目。二开始2。1名字和设计原则名字这是个练手的小的不能再小的数据库,最终很可能会基于B树来构建,至于后续的谁知道那,所以起了个名叫microdb,会用纯c开发,希望用标准的C开发,仿照sqlite,不会考虑多系统的兼容性,这是小玩具,仅此而已。设计原则简单!简单!简单!2。2关于数据库存储的疑问
  在设计需要持久化到硬盘索引的时候,觉得写的不够好,数据结构还有存储格式有很大的优化空间。总在想在Mysql等数据库上,上亿条记录最多通过四次的磁盘读就搜寻到了需要的数据,这个是怎么实现的?内存对应的数据是何时持久化到磁盘上的?B树上每个分支的指针怎么保存,内存里面就是地址,B树持久化到磁盘上,这个指针是磁盘块的地址吗?2。3sqlite
  只所以仿照sqlite,原因无非是它够小,只有一个c文件,功能少模仿简单。
  说明:整体来说sqlite将sql命令通过分词、解析和代码生成器最后生成字节码,在虚拟机上运行,直到它完成或返回结果、或遇到致命错误、或中断。2。3第一个版本
  主要开发工具vscode,采用xmake做c的构建工具,主要是比较简单和方便,可以跨平台使用,不了解的可以参考我的xmake构建工具的文章。新建个项目,最终展示如下:
  先来仿照sqlite的命令行实现个简单的解释器,它会循环执行:读取用户输入执行命令输出结果继续等待用户输出。关键代码如下:intmain(intargc,charargv){InputBufferinputbuffernewinputbuffer();while(true){printprompt();readinput(inputbuffer);if(strcmp(inputbufferbuffer,。exit)0){closeinputbuffer(inputbuffer);exit(EXITSUCCESS);}else{printf(unkowncommand:s。,inputbufferbuffer);}}return0;}
  其中InputBuffer为自定义的保存用户输入的缓冲区,读取一行数据后判断命令是否为。exit命令,不是退出命令则打印不识别命令,是退出命令则退出,非常简单:typedefstruct{charbuffer;sizetbufferlength;ssizetinputlength;}InputBuffer;intgetlinemy(charbuffer,intlength,FILEfd){inti0;charch;charbuf〔MAXLEN〕{0};while((chfgetc(fd))!EOFch!){if(MAXLEN1i){break;}buf〔i〕ch;}lengthi;buf〔i〕;buffer(char)malloc(sizeof(char)(i1));assert(buffer!NULL);strncpy(buffer,buf,i1);returni;}voidreadinput(InputBufferinputbuffer){ssizetbytesreadgetlinemy((inputbufferbuffer),(inputbufferbufferlength),stdin);if(bytesread0){printf(Errorreadinginput);exit(EXITFAILURE);}inputbufferinputlengthbytesread;inputbufferbuffer〔bytesread〕0;}
  运行提示行:F:ccodemicrodbmybuildwindowsdebugmicrodbmy。exemicrodb。testunkowncommand:。test。microdb。helpunkowncommand:。help。microdb。exit三小小的改进版本3。1支持语句识别
  上个版本的功能除了识别。exit退出外,没啥其他有用的功能,这个版本先添加对语句的支持,另外我们区分下点号开头的表示是元命令,否则就是正常的sql语句,需要我们解析执行的先不管怎么解析和执行。第2版的main函数,内容如下:intmain(intargc,charargv){InputBufferinputbuffernewinputbuffer();while(true){printprompt();readinput(inputbuffer);if(inputbufferbuffer〔0〕。){switch(dometacommand(inputbuffer)){case(METACOMMANDSUCCESS):continue;case(METACOMMANDUNRECOGNIZEDCOMMAND):printf(Unrecognizedcommands,inputbufferbuffer);continue;}}else{Statementstatement;switch(preparestatement(inputbuffer,statement)){case(PREPARESUCCESS):break;case(PREPAREUNRECOGNIZEDSTATEMENT):printf(Unrecognizedkeywordatstartofs。,inputbufferbuffer);continue;}executestatement(statement);printf(Executed。);}}return0;}
  将整个输入分成两个部分,以点号开头的表示元命令,不然就当成sql语句进行处理,解析好语句后,就执行,执行只是打印个输出内容:F:ccodemicrodbmybuildwindowsdebugmicrodbmy。exemicrodb。testUnrecognizedcommand。testmicrodb。helpUnrecognizedcommand。helpmicrodbinsertaThisiswherewewoulddoaninsert。Executed。microdbselectaThisiswherewewoulddoaselect。Executed。microdb。exit
  关于语句和解析语句的定义如下:typedefenum{METACOMMANDSUCCESS,METACOMMANDUNRECOGNIZEDCOMMAND}MetaCommandResult;typedefenum{STATEMENTINSERT,STATEMENTSELECT}StatementType;typedefenum{PREPARESUCCESS,PREPAREUNRECOGNIZEDSTATEMENT}PrepareResult;typedefstruct{StatementTypetype;}Statement;MetaCommandResultdometacommand(InputBufferinputbuffer){if(strcmp(inputbufferbuffer,。exit)0){closeinputbuffer(inputbuffer);exit(EXITSUCCESS);}else{returnMETACOMMANDUNRECOGNIZEDCOMMAND;}}PrepareResultpreparestatement(InputBufferinputbuffer,Statementstatement){if(strncmp(inputbufferbuffer,insert,6)0){statementtypeSTATEMENTINSERT;returnPREPARESUCCESS;}elseif(strncmp(inputbufferbuffer,select,6)0){statementtypeSTATEMENTSELECT;returnPREPARESUCCESS;}returnPREPAREUNRECOGNIZEDSTATEMENT;}voidexecutestatement(Statementstatement){switch(statementtype){case(STATEMENTINSERT):printf(Thisiswherewewoulddoaninsert。);break;case(STATEMENTSELECT):printf(Thisiswherewewoulddoaselect。);break;}}3。2支持在内存中插入和查询语句
  首先数据保存在内存中,采用硬编码的方式来保存用户信息,用户信息如下表:
  插入语句和查询语句的语法也进行了简化,插入语句如下:insert1cstackfoobar。comselect
  整体实现思路如下:扩展解析功能,将插入的数据以行为基本单元保存在称为页的一块内存中。每个页面有很多行组成,行紧凑排列。整个系统会根据需要申请多个页面,所有的页面都保存在一个大数组里面。
  对row的定义如下:typedefstruct{uint32tid;charusername〔COLUMNUSERNAMESIZE〕;charemail〔COLUMNEMAILSIZE〕;}Row;判断数据类型的长度,(Struct)0是把null强转为Struct指针,后获取属性,这里面只获取类型所以不会报错definesizeofattribute(Struct,Attribute)sizeof(((Struct)0)Attribute)获取ID的属性的长度constuint32tIDSIZEsizeofattribute(Row,id);获取用户名的长度constuint32tUSERNAMESIZEsizeofattribute(Row,username);获取邮箱的长度constuint32tEMAILSIZEsizeofattribute(Row,email);ID偏移量constuint32tIDOFFSET0;用户名偏移量constuint32tUSERNAMEOFFSETIDOFFSETIDSIZE;邮箱的偏移量constuint32tEMAILOFFSETUSERNAMEOFFSETUSERNAMESIZE;整行长度constuint32tROWSIZEIDSIZEUSERNAMESIZEEMAILSIZE;
  列的长度和偏移量
  下面两个函数比较关键,即序列化列和反序列化列,这里面序列化并没有把数据写入到磁盘,只是放入一块连续的平铺的内存中而已,不过这个却是可以方便持久化到磁盘上。序列化行,将row信息放入连续内存行中voidserializerow(Rowsource,voiddestination){memcpy(destinationIDOFFSET,(sourceid),IDSIZE);memcpy(destinationUSERNAMEOFFSET,(sourceusername),USERNAMESIZE);memcpy(destinationEMAILOFFSET,(sourceemail),EMAILSIZE);}反序列化,将内存块行转成rowvoiddeserializerow(voidsource,Rowdestination){memcpy((destinationid),sourceIDOFFSET,IDSIZE);memcpy((destinationusername),sourceUSERNAMEOFFSET,USERNAMESIZE);memcpy((destinationemail),sourceEMAILOFFSET,EMAILSIZE);}
  定义一个页面为4KB大小,然后定义最大只能保存100个页面,每个页面再按照每个用户总的字节数大小进行划分,具体如下:总页数defineTABLEMAXPAGES100每页的大小constuint32tPAGESIZE4096;每页可以保存row的总量constuint32tROWSPERPAGEPAGESIZEROWSIZE;整个表可以保存的总的数据量constuint32tTABLEMAXROWSROWSPERPAGETABLEMAXPAGES;typedefstruct{uint32tnumrows;voidpages〔TABLEMAXPAGES〕;}Table;
  行不跨页,每页会有些浪费空间。定位行的算法也是常用在布隆过滤器的算法,如下:voidrowslot(Tabletable,uint32trownum){uint32tpagenumrownumROWSPERPAGE;voidpagetablepages〔pagenum〕;if(pageNULL){pagetablepages〔pagenum〕malloc(PAGESIZE);}uint32trowoffsetrownumROWSPERPAGE;uint32tbyteoffsetrowoffsetROWSIZE;return(char)pagebyteoffset;}
  通过:uint32tpagenumrownumROWSPERPAGE;来定位具体的页,通过uint32trowoffsetrownumROWSPERPAGE;来定位具体的row,然后通过offset来定义在页面的具体偏移量。uint32tbyteoffsetrowoffsetROWSIZE;return(char)pagebyteoffset;
  插入和查询函数定义如下:ExecuteResultexecuteinsert(Statementstatement,Tabletable){if(tablenumrowsTABLEMAXROWS){returnEXECUTETABLEFULL;}Rowrowtoinsert(statementrowtoinsert);serializerow(rowtoinsert,rowslot(table,tablenumrows));tablenumrows1;returnEXECUTESUCCESS;}ExecuteResultexecuteselect(Statementstatement,Tabletable){Rowrow;for(uint32ti0;itablenumrows;i){deserializerow(rowslot(table,i),row);printrow(row);}returnEXECUTESUCCESS;}
  插入比较简单,关键是定位到具体的页面的偏移量,将row的内容持久化到内存块中。查询是每次都是全部查询没有查询全部的功能。四第一个正式版本
  代码一共320行,要定义为main。cpp,用c编译器编译才可以,虽然大部分是c的语法,但是定义const外部产量原因,c编译器无法通过。代码实现了内存一个固定表格的插入和查询功能,和一个交互界面,下一阶段是实现文件的持久化和B树的存储功能。includestdio。hifdefined(MSCVER)includeBaseTsd。htypedefSSIZETssizet;endifincludestdint。hincludestring。hincludemalloc。hincludecstdlibifndeftruedefinetrue1definefalse0endifdefineEXITSUCCESS0defineMAXLEN1024pragmawarning(disable:4819)defineCOLUMNUSERNAMESIZE32defineCOLUMNEMAILSIZE255defineTABLEMAXPAGES100元命令的解析结果typedefenum{METACOMMANDSUCCESS,METACOMMANDUNRECOGNIZEDCOMMAND}MetaCommandResult;插入和查询语句typedefenum{STATEMENTINSERT,STATEMENTSELECT}StatementType;解析命令结果typedefenum{PREPARESUCCESS,PREPAREUNRECOGNIZEDSTATEMENT,PREPARENEGATIVEID,PREPARESTRINGTOOLONG,PREPARENEGATIVEID,PREPARESYNTAXERROR}PrepareResult;执行结果typedefenum{EXECUTESUCCESS,EXECUTETABLEFULL}ExecuteResult;行定义typedefstruct{uint32tid;charusername〔COLUMNUSERNAMESIZE1〕;charemail〔COLUMNEMAILSIZE1〕;}Row;表的定义typedefstruct{uint32tnumrows;voidpages〔TABLEMAXPAGES〕;}Table;语句定义typedefstruct{StatementTypetype;Rowrowtoinsert;}Statement;缓冲区定义typedefstruct{charbuffer;sizetbufferlength;ssizetinputlength;}InputBuffer;definesizeofattribute(Struct,Attribute)sizeof(((Struct)0)Attribute)constuint32tIDSIZEsizeofattribute(Row,id);constuint32tUSERNAMESIZEsizeofattribute(Row,username);constuint32tEMAILSIZEsizeofattribute(Row,email);偏移量constuint32tIDOFFSET0;constuint32tUSERNAMEOFFSETIDOFFSETIDSIZE;constuint32tEMAILOFFSETUSERNAMEOFFSETUSERNAMESIZE;constuint32tROWSIZEIDSIZEUSERNAMESIZEEMAILSIZE;constuint32tPAGESIZE4096;constuint32tROWSPERPAGEPAGESIZEROWSIZE;constuint32tTABLEMAXROWSROWSPERPAGETABLEMAXPAGES;InputBuffernewinputbuffer(){InputBufferinputbuffer(InputBuffer)malloc(sizeof(InputBuffer));inputbufferbufferNULL;inputbufferbufferlength0;inputbufferinputlength0;returninputbuffer;}intgetlinemy(charbuffer,sizetlength,FILEfd){inti0;charch;charbuf〔MAXLEN〕{0};while((chfgetc(fd))!EOFch!){if(MAXLEN1i){break;}buf〔i〕ch;}lengthi;buf〔i〕;buffer(char)malloc(sizeof(char)(i1));strncpy(buffer,buf,i1);returni;}voidprintrow(Rowrow){printf((d,s,s),rowid,rowusername,rowemail);}从命令行读取一行命令voidreadinput(InputBufferinputbuffer){ssizetbytesreadgetlinemy((inputbufferbuffer),(inputbufferbufferlength),stdin);if(bytesread0){printf(Errorreadinginput);exit(EXITFAILURE);}inputbufferinputlengthbytesread;inputbufferbuffer〔bytesread〕0;}voidcloseinputbuffer(InputBufferinputbuffer){free(inputbufferbuffer);free(inputbuffer);inputbufferNULL;}解析元命令MetaCommandResultdometacommand(InputBufferinputbuffer){if(strcmp(inputbufferbuffer,。exit)0){closeinputbuffer(inputbuffer);exit(EXITSUCCESS);}else{returnMETACOMMANDUNRECOGNIZEDCOMMAND;}}解析插入语句PrepareResultprepareinsert(InputBufferinputbuffer,Statementstatement){statementtypeSTATEMENTINSERT;charkeywordstrtok(inputbufferbuffer,);charidstringstrtok(NULL,);charusernamestrtok(NULL,);charemailstrtok(NULL,);if(idstringNULLusernameNULLemailNULL){returnPREPARESYNTAXERROR;}intidatoi(idstring);if(id0){returnPREPARENEGATIVEID;}if(strlen(username)COLUMNUSERNAMESIZE){returnPREPARESTRINGTOOLONG;}if(strlen(email)COLUMNEMAILSIZE){returnPREPARESTRINGTOOLONG;}statementrowtoinsert。idid;strcpy(statementrowtoinsert。username,username);strcpy(statementrowtoinsert。email,email);returnPREPARESUCCESS;}语句的解析PrepareResultpreparestatement(InputBufferinputbuffer,Statementstatement){if(strncmp(inputbufferbuffer,insert,6)0){returnprepareinsert(inputbuffer,statement);}elseif(strncmp(inputbufferbuffer,select,6)0){statementtypeSTATEMENTSELECT;returnPREPARESUCCESS;}returnPREPAREUNRECOGNIZEDSTATEMENT;}持久化rowvoidserializerow(Rowsource,voiddestination){memcpy((char)destinationIDOFFSET,(sourceid),IDSIZE);memcpy((char)destinationUSERNAMEOFFSET,(sourceusername),USERNAMESIZE);memcpy((char)destinationEMAILOFFSET,(sourceemail),EMAILSIZE);}反持久化rowvoiddeserializerow(voidsource,Rowdestination){memcpy((destinationid),(char)sourceIDOFFSET,IDSIZE);memcpy((destinationusername),(char)sourceUSERNAMEOFFSET,USERNAMESIZE);memcpy((destinationemail),(char)sourceEMAILOFFSET,EMAILSIZE);}核心row的定位voidrowslot(Tabletable,uint32trownum){uint32tpagenumrownumROWSPERPAGE;voidpagetablepages〔pagenum〕;if(pageNULL){pagetablepages〔pagenum〕malloc(PAGESIZE);}uint32trowoffsetrownumROWSPERPAGE;uint32tbyteoffsetrowoffsetROWSIZE;return(char)pagebyteoffset;}核心定位row之后持久化ExecuteResultexecuteinsert(Statementstatement,Tabletable){if(tablenumrowsTABLEMAXROWS){returnEXECUTETABLEFULL;}Rowrowtoinsert(statementrowtoinsert);serializerow(rowtoinsert,rowslot(table,tablenumrows));tablenumrows1;returnEXECUTESUCCESS;}查询语句执行ExecuteResultexecuteselect(Statementstatement,Tabletable){Rowrow;for(uint32ti0;itablenumrows;i){deserializerow(rowslot(table,i),row);printrow(row);}returnEXECUTESUCCESS;}ExecuteResultexecutestatement(Statementstatement,Tabletable){switch(statementtype){case(STATEMENTINSERT):returnexecuteinsert(statement,table);case(STATEMENTSELECT):returnexecuteselect(statement,table);}}Tablenewtable(){Tabletable(Table)malloc(sizeof(Table));tablenumrows0;for(uint32ti0;iTABLEMAXPAGES;i){tablepages〔i〕NULL;}returntable;}voidfreetable(Tabletable){for(inti0;tablepages〔i〕;i){free(tablepages〔i〕);}free(table);}voidprintprompt(){printf(microdb);}intmain(intargc,charargv){InputBufferinputbuffernewinputbuffer();Tabletablenewtable();while(true){printprompt();readinput(inputbuffer);if(inputbufferbuffer〔0〕。){switch(dometacommand(inputbuffer)){case(METACOMMANDSUCCESS):continue;case(METACOMMANDUNRECOGNIZEDCOMMAND):printf(Unrecognizedcommands,inputbufferbuffer);continue;}}else{Statementstatement;switch(preparestatement(inputbuffer,statement)){case(PREPARESUCCESS):break;case(PREPARESTRINGTOOLONG):printf(Stringistoolong。);continue;case(PREPARENEGATIVEID):printf(IDmustbepositive。);continue;case(PREPARESYNTAXERROR):printf(Syntaxerror。Couldnotparsestatement。);continue;case(PREPAREUNRECOGNIZEDSTATEMENT):printf(Unrecognizedkeywordatstartofs。,inputbufferbuffer);continue;}switch(executestatement(statement,table)){caseEXECUTESUCCESS:printf(Executed。);break;caseEXECUTETABLEFULL:printf(Error:Tablefull。);break;}}}return0;}

美国人的西部大开发为何说西进运动,重塑了美国?19世纪美国经历了轰轰烈烈的西进运动,这场运动重塑了美国。1803年,美国总统托马斯杰斐逊以1500万美元从法国政府手中购买了路易斯安那州的领土。美国的国土因此从密西西比河延伸到落历史趣谈闰月常有,但你见过闰正月吗?历史上有过吗?大家知道吗?今年农历癸卯年(兔年),一年总共384天,很多人会问了,为啥今年的天数格外多?因为今年是闰二月呀,比平常的年份多出一月来,自然天数就多了。关于闰月,北方的早年间的习俗是2月14号情人节你知道起源从何而来吗情人节,又称圣瓦伦丁节。起源于古代罗马,于每年2月14日举行,现已成为欧美各国青年人喜爱的节日。关于圣瓦伦丁节名称的来源,说法不一。有的说是纪念一位叫瓦伦丁的基督教殉难者,他用反抗野史慈禧晚年的8个中外情人文全球趣闻实录图网络疑似慈禧太后情人一恭亲王奕訢传在慈禧进宫前就已经认识恭亲王了,并一度关系很好,慈禧做秀女的时候由于奕訢地位名声高升,担心其会图谋不轨所以一直打压他,后面因为向同南边出杂音,咱们该做点啥?魏武帝刚担任洛阳北部尉时,造五色棒,县门左右,有犯禁,不避豪强,皆棒杀之。于是全境秩序井然,流氓混子都规规矩矩了。如今这国际形势,倒颇有几分当初洛阳北部地区的模样。美西全力撑乌,誓凭什么武则天能成为一代女皇,而其他人不能?纵观中国历史,女性的执政者不在少数,如汉朝的吕后西晋的皇后贾南风北魏的太后冯氏和胡氏唐朝的武则天辽朝的太后萧氏清朝的西太后叶赫那拉氏等。然而,在众多女性执政者中,唐朝的武则天是唯一中国历史上9位传奇女子1。皇帝之妻嫘(lei)祖上古时代,公元前2700年,皇帝的妻子,她首次提倡了婚嫁制度,发明了养蚕缫丝的技术,被后人奉为先蚕娘娘,是人类文明的母祖。她跟随皇帝巡视全国,教民育蚕丝织独孤伽罗隋文帝又爱又恨的一代贤后,也是一位失败的悲情母亲公元601年,大隋王朝第一位皇后独孤伽罗,因感染风寒卧病在床,在宫里调养身体。隋文帝杨坚得空在后宫散步,不巧见到一位楚楚动人的妙龄宫女,一时心旌荡漾临幸了她,几天后才还朝理政。独孤汉朝的政教关系儒教存在吗?儒教是怎样产生的?儒教的产生与国教化任何历史现象都要放在特定的历史条件中去考察,并研究其出现的历史原因。儒教在其所处时代的产生发展及最终胜利,亦是是诸多因素共同作用的结果。本部分将集中阐述儒教及基督刘亦菲家族世系本人姓刘,父亲姓安,爷爷姓孔,却是饶阳宋氏?刘亦菲的新剧去有风的地方又引起了一波收视热潮,神仙姐姐风采依旧。刘亦菲于1987年出生于武汉,但是她的祖籍却是河北饶阳。说起来有意思,刘亦菲姓刘,他的父亲却姓安,而他的爷爷却又姓孔品读资治通鉴没有顶尖的智慧勇气和耐心,玩不了空手套白狼可略过原文,直接读解析和启发第86卷孝怀皇帝上永嘉元年(丁卯,公元三零七年)原文胡部大张督冯莫突等,拥众数千,壁于上党,石勒往从之,因说督等曰刘单于举兵击晋,部大拒而不从,自度终能
面对不可一世的蒙古帝国,为何弱小的南宋可以坚持45年之久?蒙金战争前期,成吉思汗顺手打服了高丽。不过,高丽人貌似并不服蒙古人。之后的十几年,高丽时叛时附。每当蒙古大军撤走,高丽人就会背叛。每当蒙古大军卷土重来,高丽人就会举旗投降。由于当时10月6日,历史的今天天文学家发现太阳系外第一颗行星12014年10月6日约翰欧基斯等3人获诺贝尔奖2014年10月6日17时30分左右,瑞典卡罗琳医学院在斯德哥尔摩宣布,将2014年诺贝尔生理学或医学奖授予英国科学家约翰奥奇夫和挪天文学家发现银河系的死亡恒星的墓地银河地下世界的第一张地图揭示了一个延伸到银河系高度三倍的墓地,几乎三分之一的天体已完全从银河系中抛出。悉尼大学悉尼天文学研究所的博士生DavidSweeney说这些死亡恒星的紧凑残可凡倾听对话天文学家叶叔华,遇见夜空中最亮的星曹可凡与叶叔华合影茫茫宇宙中,有一颗以她的名字命名的小行星,那是1994年发现的第3241号小行星。行星本不发光,但这个名字在地球上的主人,却用她的一生发光发热,照亮了祖国的天文学冷类星体形成新恒星,尽管活动星系核天文学家感到困惑利用美国宇航局的爱非亚些远信,亲自想下人中的研究人员发现了CO4179星系,尽管在量指中心自时亮的活动车关吃,这个年前之的从走源仔维所究议,但它下在严生新的但星米白海萨大学的动人员两大世界冠军首日出局!塞尔比不敌傅家俊,特鲁姆普遭希金斯逆转10月6日,2022年斯诺克香港大师赛展开了首日角逐,中国香港名将傅家俊亮相揭幕战,并在下午场的比赛中上演了爆冷好戏,52战胜四届世锦赛冠军得主英格兰名将马克塞尔比。而晚上的恩怨对淘汰赛首日女团八强全部出炉,男团产生四席国乒明日出战第56届成都世乒赛团体赛迎来淘汰赛首日比赛,结果女团八强全部出炉,男团产生四席国乒明日出战!具体赛况如下男团韩国30波兰赵胜敏张禹珍以及赵大成均30获胜,不过有三局险胜!中国香港3湖北阳新社区为辖区老人圆婚纱梦(阳新县融媒体中记者朱兰青通讯员吴萱萱)哇,好漂亮的新娘,好帅的新郎!在大家的赞美声中,身穿美丽婚纱笔挺西装和中式礼服的爷爷和奶奶们害羞地来到了镜头前。9月28日上午,在重阳节即将广州出发韶关2天游,畅玩新丰岭南红叶世界,观醉美日出云海今天给大家介绍一条韶关新丰岭南红叶世界2天游行程,邂逅震撼青云映日,打卡岭南凉都壮观的云海,赏最美的日落,高山生态茶园,星空餐厅,打卡高山牧场,霍比特屋,天空之境住网红星空玻璃房打一湖清水,一叶红茶,阳新仙岛红陪你国庆七天乐农村新报讯(记者方桐通讯员明月新)灵秀仙岛迎盛会,共品佳茗庆金秋。10月4日,阳新仙岛湖畔,由阳新县王英镇政府县发改局县农业农村局等多部门联合主办的首届仙岛红茶文化旅游度假节拉开帷张朝阳杨振宁比霍金更伟大但霍金对大众的传播更好稿源手机中国霍金是教科书中经常出现的物理学家,这或许跟他本人励志的经历有关。有很多人好奇,究竟是霍金更伟大,还是成就非凡的杨振宁伟大?这个问题在网上引起了很多讨论。在前不久的举行的
友情链接:快好知快生活快百科快传网中准网文好找聚热点快软网