❶ MFC操作数据库有关的类
1、 MFC的ODBC类简介
MFC的ODBC类对较复杂的ODBC API进行了封装,提供了简化的调用接口,从而大大方便了数据库应用程序的开发。程序员不必了解ODBC API和sql的具体细节,利用ODBC类即可完成对数据库的大部分操作。
MFC的ODBC类主要包括:
CDatabase类:主要功能是建立与数据源的连接。
CRecordset类:该类代表从数据源选择的一组记录(记录集),程序可以选择数据源中的某个表作为一个记录集,也可以通过对表的查询得到记录集,还可以合并同一数据源中多个表的列到一个记录集中.通过该类可对记录集中的记录进行滚动、修改、增加和删除等操作。
CRecordView类:提供了一个表单视图与某个记录集直接相连,利用对话框数据交换机制(DDX)在记录集与表单视图的控件之间传输数据。该类支持对记录的浏览和更新,在撤销时会自动关闭与之相联系的记录集。
CFieldExchange类:支持记录字段数据交换(DFX),即记录集字段数据成员与相应的数据库的表的字段之间的数据交换。该类的功能与CDataExchange类的对话框数据交换功能类似。
CDBException类:代表ODBC类产生的异常。
概括地讲,CDatabase针对某个数据库,它负责连接数据源;CRecordset针对数据源中的记录集,它负责对记录的操作;CRecordView负责界面,而CFieldExchange负责CRecordset与数据源的数据交换。
利用AppWizard和ClassWizard,用户可以方便地建立数据库应用程序,但这并不意味着可以对MFC的ODBC类一无所知.读者应注意阅读后面几小节中的内容,为学习后面的例子打好基础.
2、 CDatabase类
要建立与数据源的连接,首先应构造一个CDatabase对象,然后再调用CDatabase的Open成员函数.Open函数负责建立连接,其声明为
virtual BOOL Open( LPCTSTR lpszDSN, BOOL bExclusive = FALSE, BOOL bReadOnly = FALSE, LPCTSTR lpszConnect = “ODBC;”, BOOL bUseCursorLib = TRUE ); throw( CDBException, CMemoryException );
参数lpszDSN指定了数据源名(构造数据源的方法将在后面介绍),在lpszConnect参数中也可包括数据源名,此时lpszDSN必需为 NULL,若在函数中未提供数据源名且使lpszDSN为NULL,则会显示一个数据源对话框,用户可以在该对话框中选择一个数据源.参数 bExclusive说明是否独占数据源,由于目前版本的类库还不支持独占方式,故该参数的值应该是FALSE,这说明数据源是被共享的.参数 bReadOnly若为TRUE则对数据源的连接是只读的.参数lpszConnect指定了一个连接字符串,连接字符串中可以包括数据源名、用户帐号 (ID)和口令等信息,字符串中的"ODBC"表示要连接到一个ODBC数据源上.参数bUseCursorLib若为TRUE,则会装载光标库,否则不 装载,快照需要光标库,动态集不需要光标库. 若连接成功,函数返回TRUE,若返回FALSE,则说明用户在数据源对话框中按了Cancel按钮。若函数内部出现错误,则框架会产生一个异常。
下面是一些调用Open函数的例子。
CDatabase m_db; //在文档类中嵌入一个CDatabase对象
//连接到一个名为"Student Registration"的数据源
m_db.Open("Student Registration");
//在连接数据源的同时指定了用户帐号和口令
m_db.Open(NULL,FALSE,FALSE,"ODBC;DSN=Student Registration;UID=ZYF;PWD=1234");
m_db.Open(NULL); //将弹出一个数据源对话框
要从一个数据源中脱离,可调用函数Close。在脱离后,可以再次调用Open函数来建立一个新的连接.调用IsOpen可判断当前是否有一个连接,调用GetConnect可返回当前的连接字符串。函数的声明为
virtual void Close( );
BOOL IsOpen( ) const; //返回TRUE则表明当前有一个连接
const CString& GetConnect( ) const;
CDatabase的析构函数会调用Close,所以只要删除了CDatabase对象就可以与数据源脱离。
3、CRecordset类
CRecordset类代表一个记录集.该类是MFC的ODBC类中最重要、功能最强大的类。
10.5.1 动态集、快照、光标和光标库
在多任务操作系统或网络环境中,多个用户可以共享同一个数据源。共享数据的一个主要问题是如何协调各个用户对数据源的修改。例如,当某一个应用改变了数 据源中的记录时,别的连接至该数据源的应用应该如何处理。对于这个问题,基于MFC的ODBC应用程序可以采取几种不同的处理办法,这将由程序采用哪种记 录集决定。
记录集主要分为快照(Snapshot) 和动态集(Dynaset)两种,CRecordset类对这两者都支持。这两种记录集的不同表现在它们对别的应用改变数据源记录采取了不同的处理方法。
快照型记录集提供了对数据的静态视.快照是个很形象的术语,就好象对数据源的某些记录照了一张照片一样.当别的用户改变了记录时(包括修改、添加和删 除),快照中的记录不受影响,也就是说,快照不反映别的用户对数据源记录的改变.直到调用了CRecordset::Requery重新查询后,快照才会 反映变化.对于象产生报告或执行计算这样的不希望中途变动的工作,快照是很有用的。需要指出的是,快照的这种静态特性是相对于别的用户而言的,它会正确反 映由本身用户对记录的修改和删除,但对于新添加的记录直到调用Requery后才能反映到快照中.
动态集提供了数据的动态视.当别的用户修改或删除了记录集中的记录时,会在动态集中反映出来:当滚动到修改过的记录时对其所作的修改会立即反映到动态集 中,当记录被删除时,MFC代码会跳过记录集中的删除部分.对于其它用户添加的记录,直到调用Requery时,才会在动态集中反映出来。本身应用程序对 记录的修改、添加和删除会反映在动态集中。当数据必须是动态的时侯,使用动态集是最适合的。例如,在一个火车票联网售票系统中,显然应该用动态集随时反映 出共享数据的变化。
在记录集中滚动,需要有一个标志来指明滚动后的位置(当前位置)。ODBC驱动程序会维护一个光标,用来跟踪记录集的当前记录,可以把光标理解成跟踪记录集位置的一种机制。
光标库(Cursor Library)是处于ODBC驱动程序管理器和驱动程序之间的动态链接库(ODBCCR32.DLL).光标库的主要功能是支持快照以及为底层驱动程序 提供双向滚动能力,高层次的驱动程序不需要光标库,因为它们是可滚动的.光标库管理快照记录的缓冲区,该缓冲区反映本程序对记录的修改和删除,但不反映其 它用户对记录的改变,由此可见,快照实际上相当于当前的光标库缓冲区.
应注 意的是,快照是一种静态光标(Static Cursor).静态光标直到滚动到某个记录才能取得该记录的数据.因此,要保证所有的记录都被快照,可以先滚动到记录集的末尾,然后再滚动到感兴趣的第 一个记录上.这样做的缺点是滚动到末尾需要额外的开销,会降低性能.
与快照不同,动态集不用光标库维持的缓冲区来存放记录.实际上,动态集是不使用光标库的,因为光标库会屏蔽掉一些支持动态集的底层驱动程序功能.动态集是一种键集驱动光标(Keyset-Driven Cursor),当打开一个动态集时,驱动程序保存记录集中每个记录的键.只要光标在动态集中滚动,驱动程序就会通过键来从数据源中检取当前记录,从而保证选取的记录与数据源同步.
从上面的分析中可以看出,快照和动态集有一个共同的特点,那就是在建立记录集后,记录集中的成员就已经确定了.这就是为什么两种记录集都不能反映别的用户添加记录的原因.
10.5.2 域数据成员与数据交换
CRecordset类代表一个记录集.用户一般需要用ClassWizard创建一个CRecordset的派生类.ClassWizard可以为派 生的记录集类创建一批数据成员,这些数据成员与记录的各字段相对应,被称为字段数据成员或域数据成员.例如,对于表10.2所示的将在后面例子中使用的数 据库表,ClassWizard会在派生类中加入6个域数据成员
10.5.3 SQL查询
记录集的建立实际上主要是一个查询过程,SQL的SELECT语句用来查询数据源.在建立记录集时,CRecordset会根据一些参数构造一个 SELECT语句来查询数据源,并用查询的结果创建记录集.明白这一点对理解CRecordset至关重要.SELECT语句的句法如下:
SELECT rfx-field-list FROM table-name [WHERE m_strFilter]
[ORDER BY m_strSort]
其中table-name是表名,rfx-field-list是选择的列(字段).WHERE和ORDER BY是两个子句,分别用来过滤和排序。下面是SELECT语句的一些例子:
SELECT CourseID, InstructorID FROM Section
SELECT * FROM Section WHERE CourseID=‘MATH202’ AND Capacity=15
SELECT InstructorID FROM Section ORDER BY CourseID ASC
其中第一个语句从Section表中选择CourseID和InstructorID字段.第二个语句从Section表中选择CourseID为 MATH202且Capacity等于15的记录,在该语句中使用了象"AND"或"OR"这样的逻辑连接符.要注意在SQL语句中引用字符串、日期或时 间等类型的数据时要用单引号括起来,而数值型数据则不用.第三个语句从Section表中选择InstructorID列并且按CourseID的升序排 列,若要降序排列,可使用关键字DESC.
提示:如果列名或表名中包含有空格,则必需用方括号把该名称包起来。例如,如果有一列名为“Client Name”,则应该写成“[Client Name]”。
10.5.4 记录集的建立和关闭
要建立记录集,首先要构造一个CRecordset派生类对象,然后调用Open成员函数查询数据源中的记录并建立记录集.在Open函数中,可能会调用GetDefaultConnect和GetDefaultSQL函数.函数的声明为
CRecordset( CDatabase* pDatabase = NULL);
参数pDatabase指向一个CDatabase对象,用来获取数据源.如果pDatabase为NULL,则会在Open函数中自动构建一个 CDatabase对象.如果CDatabase对象还未与数据源连接,那么在Open函数中会建立连接,连接字符串(参见10.3.1)由成员函数 GetDefaultConnect提供.
virtual CString GetDefaultConnect( );
该函数返回缺省的连接字符串.Open函数在必要的时侯会调用该函数获取连接字符串以建立与数据源的连接.一般需要在CRecordset派生类中覆盖该函数并在新版的函数中提供连接字符串.
virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, LPCTSTR lpszSQL = NULL, DWORD dwOptions = none );
throw( CDBException, CMemoryException );
该函数使用指定的SQL语句查询数据源中的记录并按指定的类型和选项建立记录集.参数nOpenType说明了记录集的类型,如表10.3所示,如果要求 的类型驱动程序不支持,则函数将产生一个异常.参数lpszSQL是一个SQL的SELECT语句,或是一个表名.函数用lpszSQL来进行查询,如果 该参数为NULL,则函数会调用GetDefaultSQL获取缺省的SQL语句.参数dwOptions可以是一些选项的组合,常用的选项在表10.4 中列出.若创建成功则函数返回TRUE,若函数调用了CDatabase::Open且返回FALSE,则函数返回FALSE.
表10.3 记录集的类型
类型
含义
AFX_DB_USE_DEFAULT_TYPE
使用缺省值.
CRecordset::dynaset
可双向滚动的动态集.
CRecordset::snapshot
可双向滚动的快照.
CRecordset::dynamic
提供比动态集更好的动态特性,大部分ODBC驱动程序不支持这种记录集.
CRecordset::forwardOnly
只能前向滚动的只读记录集.表10.4 创建记录集时的常用选项
选项
含义
CRecordset::none
无选项(缺省).
CRecordset::appendOnly
不允许修改和删除记录,但可以添加记录.
CRecordset::readOnly
记录集是只读的.
CRecordset::skipDeletedRecords
有些数据库(如FoxPro)在删除记录时并不真删除,而是做个删除标记,在滚动时将跳过这些被删除的记录.virtual CString GetDefaultSQL( );
Open函数在必要时会调用该函数返回缺省的SQL语句或表名以查询数据源中的记录.一般需要在CRecordset派生类中覆盖该函数并在新版的函数中提供SQL语句或表名.下面是一些返回字符串的例子.
“Section” //选择Section表中的所有记录到记录集中
“Section, Course” //合并Section表和Course表的各列到记录集中
//对Section表中的所有记录按CourseID的升序进行排序,然后建立记录集
“SELECT * FROM Section ORDER BY CourseID ASC”
上面的例子说明,通过合理地安排SQL语句和表名,Open函数可以十分灵活地查询数据源中的记录.用户可以合并多个表的字段,也可以只选择记录中的某些字段,还可以对记录进行过滤和排序.
上一小节说过,在建立记录集时,CRecordset会构造一个SELECT语句来查询数据源.如果在调用Open时只提供了表名,那么SELECT语 句还缺少选择列参数rfx-field-list(参见10.5.3).框架规定,如果只提供了表名,则选择列的信息从DoFieldExchange中 的RFX语句里提取.例如,如果在调用Open时只提供了"Section"表名,那么将会构造如下一个SELECT语句:
SELECT CourseID,SectionNo,InstructorID,RoomNo, Schele,Capacity FROM Section
建立记录集后,用户可以随时调用Requery成员函数来重新查询和建立记录集.Requery有两个重要用途:
使记录集能反映用户对数据源的改变(参见10.5.1).
按照新的过滤或排序方法查询记录并重新建立记录集.
在调用Requery之前,可调用CanRestart来判断记录集是否支持Requery操作.要记住Requery只能在成功调用Open后调用,所以程序应调用IsOpen来判断记录集是否已建立.函数的声明为
virtual BOOL Requery( );throw( CDBException, CMemoryException );
返回TRUE表明记录集建立成功,否则返回FALSE.若函数内部出错则产生异常.
BOOL CanRestart( ) const; //若支持Requery则返回TRUE
BOOL IsOpen( ) const; //若记录集已建立则返回TRUE
CRecordset类有两个公共数据成员m_strFilter和m_strSort用来设置对记录的过滤和排序.在调用Open或Requery 前,如果在这两个数据成员中指定了过滤或排序,那么Open和Requery将按这两个数据成员指定的过滤和排序来查询数据源.
成员m_strFilter用于指定过滤器.m_strFilter实际上包含了SQL的WHERE子句的内容,但它不含WHERE关键字.使用m_strFilter的一个例子为:
m_pSet->m_strFilter=“CourseID=‘MATH101’”; //只选择CourseID为MATH101的记录
if(m_pSet->Open(CRecordset::snapshot, “Section”))
. . . . . .
成员m_strSort用于指定排序.m_strSort实际上包含了ORDER BY子句的内容,但它不含ORDER BY关键字.m_strSort的一个例子为
m_pSet->m_strSort=“CourseID DESC”; //按CourseID的降序排列记录
m_pSet->Open();
. . . . . .
事实上,Open函数在构造SELECT语句时,会把m_strFilter和m_strSort的内容放入SELECT语句的WHERE和ORDER BY子句中.如果在Open的lpszSQL参数中已包括了WHERE和ORDER BY子句,那么m_strFilter和m_strSort必需为空.
调用无参数成员函数Close可以关闭记录集.在调用了Close函数后,程序可以再次调用Open建立新的记录集.CRecordset的析构函数会调用Close函数,所以当删除CRecordset对象时记录集也随之关闭。
10.5.5 滚动记录
CRecordset提供了几个成员函数用来在记录集中滚动,如下所示.当用这些函数滚动到一个新记录时,框架会自动地把新记录的内容拷贝到域数据成员中.
void MoveNext( ); //前进一个记录
void MovePrev( ); //后退一个记录
void MoveFirst( ); //滚动到记录集中的第一个记录
void MoveLast( ); //滚动到记录集中的最后一个记录
void SetAbsolutePosition( long nRows );
该函数用于滚动到由参数nRows指定的绝对位置处.若nRows为负数,则从后往前滚动.例如,当nRows为-1时,函数就滚动到记录集的末尾.注意,该函数不会跳过被删除的记录.
virtual void Move( long nRows, WORD wFetchType = SQL_FETCH_RELATIVE );
该函数功能强大.通过将wFetchType参数指定为SQL_FETCH_NEXT、SQL_FETCH_PRIOR、 SQL_FETCH_FIRST、SQL_FETCH_LAST和SQL_FETCH_ABSOLUTE,可以完成上面五个函数的功能.若 wFetchType为SQL_FETCH_RELATIVE,那么将相对当前记录移动,若nRows为正数,则向前移动,若nRows为负数,则向后移 动.
如果在建立记录集时选择了CRecordset::skipDeletedRecords选项,那么除了SetAbsolutePosition外,在滚动记录时将跳过被删除的记录,这一点对象FoxPro这样的数据库十分重要.
如果记录集是空的,那么调用上述函数将产生异常.另外,必须保证滚动没有超出记录集的边界.调用IsEOF和IsBOF可以进行这方面的检测.
BOOL IsEOF( ) const;
如果记录集为空或滚动过了最后一个记录,那么函数返回TRUE,否则返回FALSE.
BOOL IsBOF( ) const;
如果记录集为空或滚动过了第一个记录,那么函数返回TRUE,否则返回FALSE.
❷ MongoDB是什么,怎么用看完你就知道了
MongoDB是一款为web应用程序和互联网基础设施设计的数据库管理系统。没错MongoDB就是数据库,是NoSQL类型的数据库。
(1)MongoDB提出的是文档、集合的概念,使用BSON(类JSON)作为其数据模型结构,其结构是面向对象的而不是二维表,存储一个用户在MongoDB中是这样子的。
使用这样的数据模型,使得MongoDB能在生产环境中提供高读写的能力,吞吐量较于mysql等SQL数据库大大增强。
(2)易伸缩,自动故障转移。易伸缩指的是提供了分片能力,能对数据集进行分片,数据的存储压力分摊给多台服务器。自动故障转移是副本集的概念,MongoDB能检测主节点是否存活,当失活时能自动提升从节点为主节点,达到故障转移。
(3)数据模型因为是面向对象的,所以可以表示丰富的、有层级的数据结构,比如博客系统中能把“评论”直接怼到“文章“的文档中,而不必像myqsl一样创建三张表来描述这样的关系。
(1)文档数据类型
SQL类型的数据库是正规化的,可以通过主键或者外键的约束保证数据的完整性与唯一性,所以SQL类型的数据库常用于对数据完整性较高的系统。MongoDB在这一方面是不如SQL类型的数据库,且MongoDB没有固定的Schema,正因为MongoDB少了一些这样的约束条件,可以让数据的存储数据结构更灵活,存储速度更加快。
(2)即时查询能力
MongoDB保留了关系型数据库即时查询的能力,保留了索引(底层是基于B tree)的能力。这一点汲取了关系型数据库的优点,相比于同类型的NoSQL redis 并没有上述的能力。
(3)复制能力
MongoDB自身提供了副本集能将数据分布在多台机器上实现冗余,目的是可以提供自动故障转移、扩展读能力。
(4)速度与持久性
MongoDB的驱动实现一个写入语义 fire and forget ,即通过驱动调用写入时,可以立即得到返回得到成功的结果(即使是报错),这样让写入的速度更加快,当然会有一定的不安全性,完全依赖网络。
MongoDB提供了Journaling日志的概念,实际上像mysql的bin-log日志,当需要插入的时候会先往日志里面写入记录,再完成实际的数据操作,这样如果出现停电,进程突然中断的情况,可以保障数据不会错误,可以通过修复功能读取Journaling日志进行修复。
(5)数据扩展
MongoDB使用分片技术对数据进行扩展,MongoDB能自动分片、自动转移分片里面的数据块,让每一个服务器里面存储的数据都是一样大小。
MongoDB核心服务器主要是通过mongod程序启动的,而且在启动时不需对MongoDB使用的内存进行配置,因为其设计哲学是内存管理最好是交给操作系统,缺少内存配置是MongoDB的设计亮点,另外,还可通过mongos路由服务器使用分片功能。
MongoDB的主要客户端是可以交互的js shell 通过mongo启动,使用js shell能使用js直接与MongoDB进行交流,像使用sql语句查询mysql数据一样使用js语法查询MongoDB的数据,另外还提供了各种语言的驱动包,方便各种语言的接入。
mongomp和mongorestore,备份和恢复数据库的标准工具。输出BSON格式,迁移数据库。
mongoexport和mongoimport,用来导入导出JSON、CSV和TSV数据,数据需要支持多格式时有用。mongoimport还能用与大数据集的初始导入,但是在导入前顺便还要注意一下,为了能充分利用好mongoDB通常需要对数据模型做一些调整。
mongosniff,网络嗅探工具,用来观察发送到数据库的操作。基本就是把网络上传输的BSON转换为易于人们阅读的shell语句。
因此,可以总结得到,MongoDB结合键值存储和关系数据库的最好特性。因为简单,所以数据极快,而且相对容易伸缩还提供复杂查询机制的数据库。MongoDB需要跑在64位的服务器上面,且最好单独部署,因为是数据库,所以也需要对其进行热备、冷备处理。
因为本篇文章不是API手册,所有这里对shell的使用也是基础的介绍什么功能可以用什么语句,主要是为了展示使用MongoDB shell的方便性,如果需要知道具体的MongoDB shell语法可以查阅官方文档。
创建数据库并不是必须的操作,数据库与集合只有在第一次插入文档时才会被创建,与对数据的动态处理方式是一致的。简化并加速开发过程,而且有利于动态分配命名空间。如果担心数据库或集合被意外创建,可以开启严格模式。
以上的命令只是简单实例,假设如果你之前没有学习过任何数据库语法,同时开始学sql查询语法和MongoDB 查询语法,你会发现哪一个更简单呢?如果你使用的是java驱动去操作MongoDB,你会发现任何的查询都像Hibernate提供出来的查询方式一样,只要构建好一个查询条件对象,便能轻松查询(接下来会给出示例),博主之前熟悉ES6,所以入手MongoDB js shell完成没问题,也正因为这样简洁,完善的查询机制,深深的爱上了MongoDB。
使用java驱动链接MongoDB是一件非常简单的事情,简单的引用,简单的做增删改查。在使用完java驱动后我才发现spring 对MongoDB 的封装还不如官方自身提供出来的东西好用,下面简单的展示一下使用。
这里只举例了简单的链接与简单的MongoDB操作,可见其操作的容易性。使用驱动时是基于TCP套接字与MongoDB进行通信的,如果查询结果较多,恰好无法全部放进第一服务器中,将会向服务器发送一个getmore指令获取下一批查询结果。
插入数据到服务器时间,不会等待服务器的响应,驱动会假设写入是成功的,实际是使用客户端生成对象id,但是该行为可以通过配置配置,可以通过安全模式开启,安全模式可以校验服务器端插入的错误。
要清楚了解MongoDB的基本数据单元。在关系型数据库中有带列和行的数据表。而MongoDB数据的基本单元是BSON文档,在键值中有指向不定类型值的键,MongoDB拥有即时查询,但不支持联结操作,简单的键值存储只能根据单个键来获取值,不支持事务,但支持多种原子更新操作。
如读写比是怎样的,需要何种查询,数据是如何更新的,会不会存在什么并发问题,数据结构化的程度是要求高还是低。系统本身的需求决定mysql还是MongoDB。
在关于schema 的设计中要注意一些原则,比如:
数据库是集合的逻辑与物理分组,MongoDB没有提供创建数据库的语法,只有在插入集合时,数据库才开始建立。创建数据库后会在磁盘分配一组数据文件,所有集合、索引和数据库的其他元数据都保存在这些文件中,查阅数据库使用磁盘状态可通过。
集合是结构上或概念上相似得文档的容器,集合的名称可以包含数字、字母或 . 符号,但必须以字母或数字开头,完全。
限定集合名不能超过128个字符,实际上 . 符号在集合中很有用,能提供某种虚拟命名空间,这是一种组织上的原则,和其他集合是一视同仁的。在集合中可以使用。
其次是键值,在MongoDB里面所有的字符串都是UTF-8类型。数字类型包括double、int、long。日期类型都是UTC格式,所以在MongoDB里面看到的时间会比北京时间慢8小时。整个文档大小会限制在16m以内,因为这样可以防止创建难看的数据类型,且小文档可以提升性能,批量插入文档理想数字范围是10~200,大小不能超过16MB。
(1)索引能显着减少获取文档的所需工作量,具体的对比可以通过 .explain()方法进行对比
(2)解析查询时MongoDB通过最优计划选择一个索引进行查询,当没有最适合索引时,会先不同的使用各个索引进行查询,最终选出一个最优索引做查询
(3)如果有一个a-b的复合索引,那么仅针对a的索引是冗余的
(4)复合索引里的键的顺序是很重要的
(1)单键索引
(2)复合索引
(3)唯一性索引
(4)稀疏索引
如索引的字段会出现null的值,或是大量文档都不包含被索引的键。
如果数据集很大时,构建索引将会花费很长的时间,且会影响程序性能,可通过
当使用 mongorestore 时会重新构建索引。当曾经执行过大规模的删除时,可使用
对索引进行压缩,重建。
(1)查阅慢查询日志
(2)分析慢查询
注意新版本的MongoDB 的explain方法是需要参数的,不然只显示普通的信息。
本节同样主要简单呈现MongoDB副本集搭建的简易性,与副本集的强壮性,监控容易性
提供主从复制能力,热备能力,故障转移能力
实际上MongoDB对副本集的操作跟mysql主从操作是差不多的,先看一下mysql的主从数据流动过程
而MongoDB主要依赖的日志文件是oplog
写操作先被记录下来,添加到主节点的oplog里。与此同时,所有从结点复制oplog。首先,查看自己oplog里最后一条的时间戳;其次,查询主节点oplog里所有大于此时间戳的条目;最后,把那些条目添加到自己的oplog里并应用到自己的库里。从节点使用长轮询立即应用来自主结点oplog的新条目。
当遇到以下情况,从节点会停止复制
local数据库保存了所有副本集元素据和oplog日志
可以使用以下命令查看复制情况
每个副本集成员每秒钟ping一次其他所有成员,可以通过rs.status()看到节点上次的心跳检测时间戳和 健康 状况。
这个点没必要过多描述,但是有一个特殊场景,如果从节点和仲裁节点都被杀了,只剩下主节点,他会把自己降级成为从节点。
如果主节点的数据还没有写到从库,那么数据不能算提交,当该主节点变成从节点时,便会触发回滚,那些没写到从库的数据将会被删除,可以通过rollback子目录中的BSON文件恢复回滚的内容。
(1)使用单节点链接
只能链接到主节点,如果链接到从节点的话,会被拒绝写入操作,但是如果没有使用安全模式,因为mongo的fire and forget 特性,会把拒绝写入的异常给吃掉。
(2)使用副本集方式链接
能根据写入的情况自动进行故障转移,但是当副本集进行新的选举时,还是会出现故障,如果不使用安全模式,依旧会出现写不进去,但现实成功的情况。
分片是数据库切分的一个概念实现,这里也是简单总结为什么要使用分片以及分片的原理,操作。
当数据量过大,索引和工作数据集占用的内存就会越来越多,所以需要通过分片负载来解决这个问题
(1)分片组件
(2)分片的核心操作
分片一个集合:分片是根据一个属性的范围进行划分的,MongoDB使用所谓的分片键让每个文档在这些范围里找到自己的位置
块:是位于一个分片中的一段连续的分片键范围,可以理解为若干个块组成分片,分片组成MongoDB的全部数据
(3)拆分与迁移
块的拆分:初始化时只有一个块,达到最大块尺寸64MB或100000个文档就会触发块的拆分。把原来的范围一分为二,这样就有了两个块,每个块都有相同数量的文档。
迁移:当分片中的数据大小不一时会产生迁移的动作,比如分片A的数据比较多,会将分片A里面的一些块转移到分片B里面去。分片集群通过在分片中移动块来实现均衡,是由名为均衡器的软件进程管理的,任务是确保数据在各个分片中保持均匀分布,当集群中拥有块最多的分片与拥有块最少分片的块差大于8时,均衡器就会发起一次均衡处理。
启动两个副本集、三个配置服务器、一个mongos进程
配置分片
(1)分片查询类型
(2)索引
分片集合只允许在_id字段和分片键上添加唯一性索引,其他地方不行,因为这需要在分片间进行通信,实施起来很复杂。
当创建分片时,会根据分片键创建一个索引。
(1)分片键是不可修改的、分片键的选择非常重要
(2)低效的分片键
(3)理想的分片键
(1)部署拓扑
根据不同的数据中心划分
这里写图片描述
(2)最低要求
(3)配置的注意事项
需要估计集群大小,可使用以下命令对现有集合进行分片处理
(4)备份分片集群
备份分片时需要停止均衡器
(1)部署架构
使用64位机器、32位机器会制约mongodb的内存,使其最大值为1.5GB
(2)cpu
mongodb 只有当索引和工作集都可放入内存时,才会遇到CPU瓶颈,CPU在mongodb使用中的作用是用来检索数据,如果看到CPU使用饱和的情况,可以通过查询慢查询日志,排查是不是查询的问题导致的,如果是可以通过添加索引来解决问题
mongodb写入数据时会使用到CPU,但是mongodb写入时间一次只用到一个核,如果有频繁的写入行为,可以通过分片来解决这个问题
(3)内存
大内存是mongodb的保障,如果工作集大小超过内存,将会导致性能下降,因为这将会增加数据加载入内存的动作
(4)硬盘
mongodb默认每60s会与磁盘强制同步一次,称为后台刷新,会产生I/O操作。在重启时mongodb会将磁盘里面的数据加载至内存,高速磁盘将会减少同步的时间
(5)文件系统
使用ext4 和 xfs 文件系统
禁用最后访问时间
(6)文件描述符
linux 默认文件描述符是1024,需要大额度的提升这个额度
(7)时钟
mongodb各个节点服务器之间使用ntp服务器
(1)绑定IP
启动时使用 - -bind_ip 命令
(2)身份验证
启动时使用 - -auth 命令
(3)副本集身份认证
使用keyFile,注意keyFile文件的权限必须是600,不然会启动不起来
(1)拓扑结构
搭建副本集至少需要两个节点,其中仲裁结点不需要有自己的服务器
(2)Journaling日志
写数据时会先写入日志,而此时的数据也不是直接写入硬盘,而是写入内存
但是Journaling日志会消耗内存,所以可以在主库上面关闭,在从库上面启动
可以单独为Journaling日志使用一块固态硬盘
在插入时,可以通过驱动确保Journaling插入后再反馈,但是会非常影响性能。
logpath 选项指定日志存储地址
-vvvvv 选项(v越多,输出越详细)
db.runCommand({logrotare:1}) 开启滚动日志
(1)serverStatus
这里写图片描述
(2)top
(3)db.currentOp()
动态展示mongodb活动数据
占用当前mongodb监听端口往上1000号的端口
(1)mongomp
把数据库内容导出成BSON文件,而mongorestore能读取并还原这些文件
(2)mongorestore
把导出的BSON文件还原到数据库
(3)备份原始数据文件
可以这么做,但是,操作之前需要进行锁库处理 db.runCommand({fsync:1,lock:true})
db.$cmd.sys.unlock.findOne() 请求解锁操作,但是数据库不会立刻解锁,需要使用db.currentOp()验证。
(1)修复
mongd --repair 修复所有数据库
db.runCommand({repairDatabase:1}) 修复单个数据库
修复就是根据Jourling文件读取和重写所有数据文件并重建各个索引
(2)压紧
压紧,会重写数据文件,并重建集合的全部索引,需要停机或者在从库上面运行,如果需要在主库上面运行,需要添加force参数 保证加写锁。
(1)监控磁盘状态
(2)为提升性能检查索引和查询
总的来说,扫描尽可能少的文档。
保证没有冗余的索引,冗余的索引会占用磁盘空间、消耗更多的内存,在每次写入时还需做更多工作
(3)添加内存
dataSize 数据大小 和 indexSize 索引大小,如果两者的和大于内存,那么将会影响性能。
storageSize超过dataSize 数据大小 两倍以上,就会因磁盘碎片而影响性能,需要压缩。
❸ 数据库系统的组成,及各自的作用
1、数据库(database,DB)
作用是数据库中的数据按一定的数学模型组织、描述和存储,有组织,可共享的数据的集合。具有较小的冗余,较高的数据独立性和易扩展性,并可为各种用户共享。
2、硬件
构成计算机系统的各种物理设备,包括存储所需的外部设备。作用是硬件的配置应满足整个数据库系统的需要。
3、软件
包括操作系统、数据库管理系统及应用程序。数据库管理系统是数据库系统的核心软件,作用是在操作系统的支持下工作,科学地组织和存储数据,高效获取和维护数据的系统软件。其主要功能包括数据定义功能、数据操纵功能、数据库的运行管理和数据库的建立与维护。
4、人员
主要分类及其作用是系统分析员和数据库设计人员,负责应用系统的需求分析和规范说明,确定系统的硬件配置,并参与数据库系统的概要设计;应用程序员,负责编写使用数据库的应用程序,利用系统的接口或查询语言访问数据库;数据库管理员负责数据库的总体信息控制。
(3)数据库操作类dbbase简介和使用扩展阅读:
数据库系统的模型
1、层次模型:用一颗“有向树”的数据结构来表示各类实体以及实体间的联系,树中每一个节点代表一个记录类型,树状结构表示实体型之间的联系。层次数据模型的提出,首先是为了模拟这种按层次组织起来的事物。层次数据库也是按记录来存取数据的。
2、网状模型:取消了层次模型的不能表示非数状结构的限制,两个或两个以上的结点都可以有多个双亲结点,则此时有向树变成了有向图,该有向图描述了网状模型。网状模型中以记录为数据的存储单位。记录包含若干数据项。
3、关系模型:基本假定是所有数据都表示为数学上的关系。关系数据模型以集合论中的关系概念为基础发展起来的。关系模型中无论是实体还是实体间的联系均由单一的结构类型关系来表示。
❹ 与文件管理数据相比,数据库管理系统有哪些优点
与文件管理数据相比,数据库管理系统具有以下优点:
1、控制数据冗余。
数据库管理应尽可能地消除了冗余,但是并没有完全消除,而是控制大量数据库固有的冗余。例如,为了表现数据间的关系,数据项的重复一般是必要的,有时为了提高性能也会重复一些数据项。
2、保证数据一致性。
通过消除或控制冗余,可降低不一致性产生的危险。如果数据项在数据库中只存储了一次,则任何对该值的更新均只需进行一次,而且新的值立即就被所有用户获得。如果数据项不只存储了一次,而且系统意识到这点,系统将可以确保该项的所有拷贝都保持一致。
3、提高数据共享。
数据库应该被有权限的用户共享。数据库管理系统的引入使更多的用户可以更方便的共享更多的数据。新的应用程序可以依赖于数据库中已经存在的数据,并且只增加没有存储的数据,而不用重新定义所有的数据需求。
(4)数据库操作类dbbase简介和使用扩展阅读
技术特点
(1)采用复杂的数据模型表示数据结构,数据冗余小,易扩充,实现了数据共享。
(2)具有较高的数据和程序独立性,数据库的独立性有物理独立性和逻辑独立性。
(3)数据库系统为用户提供了方便的用户接口。
(4)数据库系统提供4个方面的数据控制功能,分别是并发控制、恢复、完整性和安全性。数据库中各个应用程序所使用的数据由数据库系统统一规定,按照一定的数据模型组织和建立,由系统统一管理和集中控制。
(5)增加了系统的灵活性。
❺ 什么是数据库 怎么用
数据库
数据库发展阶段大致划分为如下几个阶段:
人工管理阶段;
文件系统阶段;
数据库系统阶段;
高级数据库阶段。
当人们从不同的角度来描述这一概念时就有不同的定义(当然是描述性的)。例如,称数据库是一个“记录保存系统”(该定义强调了数据库是若干记录的集合)。又如称数据库是“人们为解决特定的任务,以一定的组织方式存储在一起的相关的数据的集合”(该定义侧重于数据的组织)。更有甚者称数据库是“一个数据仓库”。当然,这种说法虽然形象,但并不严谨。
严格地说,数据库是“按照数据结构来组织、存储和管理数据的仓库”。在经济管理的日常工作中,常常需要把某些相关的数据放进这样“仓库”,并根据管理的需要进行相应的处理。例如,企业或事业单位的人事部门常常要把本单位职工的基本情况(职工号、姓名、年龄、性别、籍贯、工资、简历等)存放在表20.6.3中,这张表就可以看成是一个数据库。有了这个"数据仓库"我们就可以根据需要随时查询某职工的基本情况,也可以查询工资在某个范围内的职工人数等等。这些工作如果都能在计算机上自动进行,那我们的人事管理就可以达到极高的水平。此外,在财务管理、仓库管理、生产管理中也需要建立众多的这种"数据库",使其可以利用计算机实现财务、仓库、生产的自动化管理。
J.Martin给数据库下了一个比较完整的定义:数据库是存储在一起的相关数据的集合,这些数据是结构化的,无有害的或不必要的冗余,并为多种应用服务;数据的存储独立于使用它的程序;对数据库插入新数据,修改和检索原有数据均能按一种公用的和可控制的方式进行。当某个系统中存在结构上完全分开的若干个数据库时,则该系统包含一个“数据库集合”。
· 数据库的优点
使用数据库可以带来许多好处:如减少了数据的冗余度,从而大大地节省了数据的存储空间;实现数据资源的充分共享等等。此外,数据库技术还为用户提供了非常简便的使用手段使用户易于编写有关数据库应用程序。特别是近年来推出的微型计算机关系数据库管理系统dBASELL,操作直观,使用灵活,编程方便,环境适应广泛(一般的十六位机,如IBM/PC/XT,国产长城0520等均可运行种软件),数据处理能力极强。数据库在我国正得到愈来愈广泛的应用,必将成为经济管理的有力工具。
数据库是通过数据库管理系统(DBMS-DATA BASE MANAGEMENT SYSTEM)软件来实现数据的存储、管理与使用的dBASELL就是一种数据库管理系统软件。
· 数据库结构与数据库种类
数据库通常分为层次式数据库、网络式数据库和关系式数据库三种。而不同的数据库是按不同的数据结构来联系和组织的。
1.数据结构模型
(1)数据结构
所谓数据结构是指数据的组织形式或数据之间的联系。如果用D表示数据,用R表示数据对象之间存在的关系集合,则将DS=(D,R)称为数据结构。例如,设有一个电话号码簿,它记录了n个人的名字和相应的电话号码。为了方便地查找某人的电话号码,将人名和号码按字典顺序排列,并在名字的后面跟随着对应的电话号码。这样,若要查找某人的电话号码(假定他的名字的第一个字母是Y),那么只须查找以Y开头的那些名字就可以了。该例中,数据的集合D就是人名和电话号码,它们之间的联系R就是按字典顺序的排列,其相应的数据结构就是DS=(D,R),即一个数组。(2)数据结构种类
数据结构又分为数据的逻辑结构和数据的物理结构。数据的逻辑结构是从逻辑的角度(即数据间的联系和组织方式)来观察数据,分析数据,与数据的存储位置无关。数据的物理结构是指数据在计算机中存放的结构,即数据的逻辑结构在计算机中的实现形式,所以物理结构也被称为存储结构。本节只研究数据的逻辑结构,并将反映和实现数据联系的方法称为数据模型。
目前,比较流行的数据模型有三种,即按图论理论建立的层次结构模型和网状结构模型以及按关系理论建立的关系结构模型。
2.层次、网状和关系数据库系统
(1)层次结构模型
层次结构模型实质上是一种有根结点的定向有序树(在数学中"树"被定义为一个无回的连通图)。例如图20.6.4是一个高等学校的组织结构图。这个组织结构图像一棵树,校部就是树根(称为根结点),各系、专业、教师、学生等为枝点(称为结点),树根与枝点之间的联系称为边,树根与边之比为1:N,即树根只有一个,树枝有N个。这种数据结构模型的一般结构见图20.6.5所示。
图20.6.4 高等学校的组织结构图 图20.6.5 层次结构模型
图20.6.5中,Ri(i=1,2,…6)代表记录(即数据的集合),其中R1就是根结点(如果Ri看成是一个家族,则R1就是祖先,它是R2、R3、R4的双亲,而R2、R3、R4互为兄弟),R5、R6也是兄弟,且其双亲为R3。R2、R4、R5、R6又被称为叶结点(即无子女的结点)。这样,Ri(i=1,2,…6)就组成了以R1为树根的一棵树,这就是一个层次数据结构模型。
按照层次模型建立的数据库系统称为层次模型数据库系统。IMS(Information Manage-mentSystem)是其典型代表。
(2)网状结构模型
在图20.6.6中,给出了某医院医生、病房和病人之间的联系。即每个医生负责治疗三个病人,每个病房可住一到四个病人。如果将医生看成是一个数据集合,病人和病房分别是另外两个数据集合,那么医生、病人和病房的比例关系就是M:N:P(即M个医生,N个病人,P间病房)。这种数据结构就是网状数据结构,它的一般结构模型如图20.6.7所示。在图中,记录Ri(i=1,2,8)满足以下条件:
①可以有一个以上的结点无双亲(如R1、R2、R3)。
②至少有一个结点有多于一个以上的双亲。在"医生、病人、病房"例中,"医生集合有若干个结点(M个医生结点)无"双亲",而"病房"集合有P个结点(即病房),并有一个以上的"双亲"(即病人)。
图20.6.6 医生、病房和病人之间的关系
图20.6.7 网状结构模型
按照网状数据结构建立的数据库系统称为网状数据库系统,其典型代表是DBTG(Data Base Task Group)。用数学方法可将网状数据结构转化为层次数据结构。
(3)关系结构模型
关系式数据结构把一些复杂的数据结构归结为简单的二元关系(即二维表格形式)。例如某单位的职工关系就是一个二元关系(见表20.6.8)。这个四行六列的表格的每一列称为一个字段(即属性),字段名相当于标题栏中的标题(属性名称);表的每一行是包含了六个属性(工号、姓名、年龄、性别、职务、工资)的一个六元组,即一个人的记录。这个表格清晰地反映出该单位职工的基本情况。
表20.6.8 职工基本情况
通常一个m行、n列的二维表格的结构如表20.6.9所示。
表中每一行表示一个记录值,每一列表示一个属性(即字段或数据项)。该表一共有m个记录。每个记录包含n个属性。
作为一个关系的二维表,必须满足以下条件:
(1)表中每一列必须是基本数据项(即不可再分解)。(2)表中每一列必须具有相同的数据类型(例如字符型或数值型)。(3)表中每一列的名字必须是唯一的。(4)表中不应有内容完全相同的行。(5)行的顺序与列的顺序不影响表格中所表示的信息的含义。
由关系数据结构组成的数据库系统被称为关系数据库系统。
在关系数据库中,对数据的操作几乎全部建立在一个或多个关系表格上,通过对这些关系表格的分类、合并、连接或选取等运算来实现数据的管理。dBASEII就是这类数据库管理系统的典型代表。对于一个实际的应用问题(如人事管理问题),有时需要多个关系才能实现。用dBASEII建立起来的一个关系称为一个数据库(或称数据库文件),而把对应多个关系建立起来的多个数据库称为数据库系统。dBASEII的另一个重要功能是通过建立命令文件来实现对数据库的使用和管理,对于一个数据库系统相应的命令序列文件,称为该数据库的应用系统。因此,可以概括地说,一个关系称为一个数据库,若干个数据库可以构成一个数据库系统。数据库系统可以派生出各种不同类型的辅助文件和建立它的应用系统。
· 数据库的要求与特性
为了使各种类型的数据库系统能够充分发挥它们的优越性,必须对数据库管理系统的使用提出一些明确的要求。
1.建立数据库文件的要求
(1)尽量减少数据的重复,使数据具有最小的冗余度。计算机早期应用中的文件管理系统,由于数据文件是用户各自建立的,几个用户即使有许多相同的数据也得放在各自的文件中,因而造成存储的数据大量重复,浪费存储空间。数据库技术正是为了克服这一缺点而出现的,所以在组织数据的存储时应避免出现冗余。
(2)提高数据的利用率,使众多用户都能共享数据资源。
(3)注意保持数据的完整性。这对某些需要历史数据来进行预测、决策的部门(如统计局、银行等)特别重要。
(4)注意同一数据描述方法的一致性,使数据操作不致发生混乱。如一个人的学历在人事档案中是大学毕业,而在科技档案中却是大学程度,这样就容易造成混乱。
(5)对于某些需要保密的数据,必须增设保密措施。
(6)数据的查找率高,根据需要数据应能被及时维护。
2.数据库文件的特征
无论使用哪一种数据库管理系统,由它们所建立的数据库文件都可以看成是具有相同性质的记录的集合,因而这些数据库文件都有相同的特性:
(1)文件的记录格式相同,长度相等。
(2)不同的行是不同的记录,因而具有不同的内容。
(3)不同的列表示不同的字段名,同一列中的数据的性质(属性)相同。
(4)每一行各列的内容是不能分割的,但行的顺序和列的顺序不影响文件内容的表达。
3.文件的分类
对文件引用最多的是主文件和事物文件。其他的文件分类还包括表文件、备份文件、档案的输出文件等。下面将讲述这些文件。
(1)主文件。主文件是某特定应用领域的永久性的数据资源。主文件包含那些被定期存取以提供信息和经常更新以反映最新状态的记录。典型的主文件有库存文件、职工主文件和收帐主文件等。
(2)事务文件。事务文件包含着作为一个信息系统的数据活动(事务)的那些记录。这些事务被分批以构成事务文件。例如,从每周工资卡上录制下来的数分批存放在一个事务文件上,然后对照工资清单文件进行处理以便打印出工资支票和工资记录簿。
(3)表文件。表文件是一些表格。之所以单独建立表文件而不把表设计在程序中是为了便于修改。例如,一个公用事业公司的税率表或国内税务局的税率就可以存储在表中文件。
(4)备用文件。备用文件是现有生产性文件的一个复制品。一旦生产性文件受到破坏,利用备用文件就可以重新建立生产性文件。
(5)档案文件。档案文件不是提供当前处理使用的,而是保存起来作为历史参照的。例如,国内税务局(IRS)可能要求检查某个人最近15年的历史。实际上,档案文件恰恰是在给定时间内工作的一个"快照"。
(6)输出文件。输出文件包含将要打印在打印机上的、显在屏幕上的或者绘制在绘图仪上的那些信息的数值映象。输出文件可以是"假脱机的"(存储在辅存设备上),当输出设备可用时才进行实际的输出。
❻ 数据库DB、数据库系统DBS、数据库管理系统DBMS三者之间的关系是
DBS包括DB和DBMS,数据库系统包括数据库与数据库管理系统。
数据库系统(Database System),是由数据库及其管理软件组成的系统。
数据库系统是为适应数据处理的需要而发展起来的一种较为理想的数据处理系统,也是一个为实际可运行的存储、维护和应用系统提供数据的软件系统,是存储介质 、处理对象和管理系统的集合体。
拓展资料:
数据库系统DBS(Data Base System,简称DBS)通常由软件、数据库和数据管理员组成。其软件主要包括操作系统、各种宿主语言、实用程序以及数据库管理系统。
数据库由数据库管理系统统一管理,数据的插入、修改和检索均要通过数据库管理系统进行。数据管理员负责创建、监控和维护整个数据库,使数据能被任何有权使用的人有效使用。数据库管理员一般是由业务水平较高、资历较深的人员担任。
❼ 数据库是干什么用的呢
数据库是以一定方式储存在一起、能与多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合,可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进行新增、查询、更新、删除等操作。
数据库是存放数据的仓库。它的存储空间很大,可以存放百万条、千万条、上亿条数据。但是数据库并不是随意地将数据进行存放,是有一定的规则的,否则查询的效率会很低。当今世界是一个充满着数据的互联网世界,充斥着大量的数据。即这个互联网世界就是数据世界。数据的来源有很多,比如出行记录、消费记录、浏览的网页、发送的消息等等。除了文本类型的数据,图像、音乐、声音都是数据。
(7)数据库操作类dbbase简介和使用扩展阅读:
数据库发展现状
在数据库的发展历史上,数据库先后经历了层次数据库、网状数据库和关系数据库等各个阶段的发展,数据库技术在各个方面的快速的发展。特别是关系型数据库已经成为目前数据库产品中最重要的一员,80年代以来, 几乎所有的数据库厂商新出的数据库产品都支持关系型数据库,即使一些非关系数据库产品也几乎都有支持关系数据库的接口。