关系型数据库的局限性有哪些难以满足高并发读写的需求

关系型数据库的局限性有哪些难以满足高并发读写的需求,第1张

随着互联网web20网站的兴起,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速。而传统的关系数据库在应付web20网站,特别是超大规模和高并发的SNS类型的web20纯动态网站已经显得力不从心,暴露了很多难以克服的问题,例如:

1、High performance——对数据库高并发读写的需求

Web20网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。其实对于普通的BBS网站,往往也存在对高并发写请求的需求,例如像JavaEye网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求。

2、Huge Storage——对海量数据的高效率存储和访问的需求

类似Facebook,twitter,Friendfeed这样的SNS网站,每天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了25亿条用户动态,对于关系数据库来说,在一张25亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付。

3、High Scalability && High Availability——对数据库的高可扩展性和高可用性的需求

在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,为什么数据库不能通过不断的添加服务器节点来实现扩展呢?

在上面提到的“三高”需求面前,关系数据库遇到了难以克服的障碍,而对于web20网站来说,关系数据库的很多主要特性却往往无用武之地,例如:

1 数据库事务一致性需求

很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高。因此数据库事务管理成了数据库高负载下一个沉重的负担。

2 数据库的写实时性和读实时性需求

对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说我(JavaEye的robbin)发一条消息之后,过几秒乃至十几秒之后,我的订阅者才看到这条动态是完全可以接受的。

3、对复杂的SQL查询,特别是多表关联查询的需求

任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品设计角度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。

因此,关系数据库在这些越来越多的应用场景下显得不那么合适了,为了解决这类问题的非关系数据库应运而生,现在这两年,各种各样非关系数据库,特别是键值数据库(Key-Value Store DB)风起云涌,多得让人眼花缭乱。前不久国外刚刚举办了NoSQL Conference,各路NoSQL数据库纷纷亮相,加上未亮相但是名声在外的,起码有超过10个开源的NoSQLDB,例如:

Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB,

这些NoSQL数据库,有的是用C/C++编写的,有的是用Java编写的,还有的是用Erlang编写的,每个都有自己的独到之处,看都看不过来了,我(robbin)也只能从中挑选一些比较有特色,看起来更有前景的产品学习和了解一下。

使用Visual C++编程,有如下方法进行文件 *** 作:

(1)使用标准C运行库函数,包括fopen、fclose、fseek等。

(2)使用Win16下的文件和目录 *** 作函数,如lopen、lclose、lseek等。不过,在Win32下,这些函数主要是为了和Win16向后兼容。

(3)使用Win32下的文件和目录 *** 作函数,如CreateFile,CopyFile,DeleteFile,FindNextFile,等等。

Win32下,打开和创建文件都由CreateFile完成,成功的话,得到一个Win32下的句柄,这不同于“C”的fopen返回的句柄。在Win16下,该句柄和C运行库文件 *** 作函数相容。但在Win32下,“C”的文件 *** 作函数不能使用该句柄,如果需要的话,可以使用函数_open_osfhandle从Win32句柄得到一个“C”文件函数可以使用的文件句柄。

关闭文件使用Win32的CloseHandle。

在Win32下,CreateFile可以 *** 作的对象除了磁盘文件外,还包括设备文件如通讯端口、管道、控制台输入、邮件槽等等。

(4)使用CFile和其派生类进行文件 *** 作。CFile从CObject派生,其派生类包括 *** 作文本文件的CStdioFile, *** 作内存文件的CmemFile,等等。

CFile是建立在Win32的文件 *** 作体系的基础上,它封装了部分Win32文件 *** 作函数。

最好是使用CFile类(或派生类)的对象来 *** 作文件,必要的话,可以从这些类派生自己的文件 *** 作类。统一使用CFile的界面可以得到好的移植性。

MFC的文件类

MFC用一些类来封装文件访问的Win32 API。以CFile为基础,从CFile派生出几个类,如CStdioFile,CMemFile,MFC内部使用的CMiororFile,等等。

CFile的结构

CFile定义的枚举类型

CFile类定义了一些和文件 *** 作相关的枚举类型,主要有四种:OpenFlags,Attribute,SeekPosition,hFileNull。下面,分别解释这些枚举类型。

OpenFlags

OpenFlags定义了13种文件访问和共享模式:

enum OpenFlags {

//第一(从右,下同)至第二位,打开文件时访问模式,读/写/读写

modeRead = 0x0000,

modeWrite = 0x0001,

modeReadWrite = 0x0002,

shareCompat = 0x0000, //32位MFC中没用

//第五到第七位,打开文件时的共享模式

shareExclusive = 0x0010,//独占方式,禁止其他进程读写

shareDenyWrite = 0x0020,//禁止其他进程写

shareDenyRead = 0x0030,//禁止其他进程读

shareDenyNone = 0x0040,//允许其他进程写

//第八位,打开文件时的文件继承方式

modeNoInherit = 0x0080,//不允许子进程继承

//第十三、十四位,是否创建新文件和创建方式

modeCreate = 0x1000,//创建新文件,文件长度0

modeNoTruncate = 0x2000,//创建新文件时如文件已存在则打开

//第十五、十六位,文件以二进制或者文本方式打开,在派生类CStdioFile中用

typeText = 0x4000,

typeBinary = (int)0x8000

};

Attribute

Attribute定义了文件属性:正常、只读、隐含、系统文件,文件或者目录等。

enum Attribute {

normal = 0x00,

readOnly = 0x01,

hidden = 0x02,

system = 0x04,

volume = 0x08,

directory = 0x10,

archive = 0x20

}

SeekPosition

SeekPosition定义了三种文件位置:头、尾、当前:

enum SeekPosition{

begin = 0x0,

current = 0x1,

end = 0x2

};

hFileNull

hFileNull定义了空文件句柄

enum { hFileNull = -1 };

CFile的其他一些成员变量

CFile除了定义枚举类型,还定义了一些成员变量。例如:

UINT m_hFile

该成员变量是public访问属性,保存::CreateFile返回的 *** 作系统的文件句柄。MFC重载了运算符号HFILE来返回m_hFile,这样在使用HFILE类型变量的地方可以使用CFile对象。

BOOL m_bCloseOnDelete;

CString m_strFileName;

这两个成员变量是protected访问属性。m_bCloseOnDelete用来指示是否在关闭文件时删除CFile对象;m_strFileName用来保存文件名。

CFile的成员函数

CFile的成员函数实现了对Win32文件 *** 作函数的封装,完成以下动作:打开、创建、关闭文件,文件指针定位,文件的锁定与解锁,文件状态的读取和修改,等等。其中,用到了m_hFile文件句柄的一般是虚拟函数,和此无关的一般是静态成员函数。一般地,成员函数被映射到对应的Win32函数,如表11-1所示。

表11-1 CFile函数对Win32文件函数的封装

虚拟

静态

成员函数

对应的Win32函数

文件的创建、打开、关闭

Abort

CloseHandle

Duplicate

DuplicateHandle

Open

CreateFile

Close

CloseHandle

文件的读写

Read

ReadFile

ReadHuge(向后兼容)

调用Read成员函数

Write

WriteFile

WriteHuage(向后兼容)

调用Write成员函数

Flush

FlushFileBuffers

文件定位

Seek

SetFilePointer

SeekToBegin

调用Seek成员函数

SeekToEnd

调用Seek成员函数

GetLength

调用Seek成员函数

SetLength

SetEndOfFile

文件的锁定/解锁

LockRange

LockFile

UnlockRange

UnlockFile

文件状态 *** 作函数

GetPosition

SetFilePointer

GetStatus(CFileStatus&)

GetFileTime,GetFileSize等

GetStatus(LPSTR lpszFileName CFileStatus&)

FindFirstFile

GetFileName

不是简单地映射到某个函数

GetFileTitle

GetFilePath

SetFilePath

SetStatus

改名和删除

Rename

MoveFile

Remove

DeleteFile

CFile的部分实现

这里主要讨论CFile对象的构造函数和文件的打开/创建的过程。

构造函数

CFile有如下几个构造函数:

CFile()

缺省构造函数,仅仅构造一个CFile对象,还必须使用Open成员函数来打开文件。

CFile(int hFile)

已经打开了一个文件hFile,在此基础上构造一个CFile对象来给它打包。HFile将被赋值给CFile的成员变量m_hFile。

CFile(LPCTSTR lpszFileName, UINT nOpenFlags)

指定一个文件名和文件打开方式,构造CFile对象,调用Open打开/创建文件,把文件句柄保存到m_hFile。

打开/创建文件

Open的原型如下:

BOOL CFile::Open(LPCTSTR lpszFileName, UINT nOpenFlags,

CFileException pException)

Open调用Win32函数::CreateFile打开文件,并把文件句柄保存到成员变量m_hFile中。

CreateFile函数的原型如下:

HANDLE CreateFile(

LPCTSTR lpFileName,// pointer to name of the file

DWORD dwDesiredAccess,// access (read-write) mode

DWORD dwShareMode,// share mode

LPSECURITY_ATTRIBUTES lpSecurityAttributes, //pointer to security descriptor

DWORD dwCreationDistribution,// how to create

DWORD dwFlagsAndAttributes,// file attributes

HANDLE hTemplateFile// handle to file with attributes to copy

);

显然,Open必须把自己的两个参数lpszFileName和nOpenFlags映射到CreateFile的七个参数上。

从OpenFlags的定义可以看出,(nOpenFlags & 3)表示了读写标识,映射成变量dwAccess,可以取值为Win32的GENERIC_READ、GENERIC_WRITE、GENERIC_READ|GENERIC_WRITE。

(nOpenFlags & 0x70)表示了共享模式,映射成变量dwShareMode,可以取值为Win32的FILE_SHARE_READ、FILE_SHARE_WRITE、FILE_SHARE_WRITE|FILE_SHARE_READ。

Open定义了一个局部的SECURITY_ATTRIBUTES变量sa,(nOpenFlags & 0x80)被赋值给sabInheritHandle。

(nOpenFlags & modeCreate)表示了创建方式,映射成变量dwCreateFlag,可以取值为Win32的OPEN_ALWAYS、CREATE_ALWAYS、OPEN_EXISTING。

在生成了上述参数之后,先调用::CreateFile:

HANDLE hFile =::CreateFile(lpszFileName,

dwAccess, dwShareMode, &sa,

dwCreateFlag, FILE_ATTRIBUTE_NORMAL, NULL);

然后,hFile被赋值给成员变量m_hFile,m_bCloseOnDelete被设置为TRUE。

由上可以看出,CFile打开(创建)一个文件时大大简化了:: CreateFile函数的复杂性,即只需要指定一个文件名、一个打开文件的参数即可。若该参数指定为0,则表示以只读方式打开一个存在的文件,独占使用,不允许子进程继承。

在CFile对象使用时,如果它是在堆中分配的,则应该销毁它;如果在栈中分配的,则CFile对象将被自动销毁。销毁时析构函数被调用,析构函数是虚拟函数。若m_bCloseOnDelete为真且m_hFile非空,则析构函数调用Close关闭文件。

至于其他CFile成员函数的实现,这里不作分析了。

CFile的派生类

这里主要简要地介绍CStdioFile和CmemFile及CFileFind。

CStdioFile

CStdioFile对文本文件进行 *** 作。

CStdioFile定义了新的成员变量m_pStream,类型是FILE。在打开或者创建文件时,使用_open_osfhandle从m_hFile(Win32文件句柄)得到一个“C”的FILE类型的文件指针,然后,在文件 *** 作中,使用“C”的文件 *** 作函数。例如,读文件使用_fread,而不是::ReadFile,写文件使用了_fwrite,而不是::WriteFile,等等。m_hFile是CFile的成员变量。

另外,CStdioFile不支持CFile的Dumplicate、LockRange、UnlockRange *** 作,但是实现了两个新的 *** 作ReadString和WriteString。

CMemFile

CMemFile把一块内存当作一个文件来 *** 作,所以,它没有打开文件的 *** 作,而是设计了Attach和Detach用来分配或者释放一块内存。相应地,它提供了Alloc、Free虚拟函数来 *** 作内存文件,它覆盖了Read、Write来读写内存文件。

CFileFind

为了方便文件查找,MFC把有关功能归结成为一个类CFileFind。CFileFind派生于CObject类。首先,它使用FindFile和FineNextFile包装了Win32函数::FindFirstFile和::FindNextFile;其次,它提供了许多函数用来获取文件的状态或者属性。

使用CFileStatus结构来描述文件的属性,其定义如下:

struct CFileStatus

{

CTime m_ctime; // 文件创建时间

CTime m_mtime; // 文件最近一次修改时间

CTime m_atime; // 文件最近一次访问时间

LONG m_size; // 文件大小

BYTE m_attribute; // 文件属性

BYTE _m_padding; // 没有实际含义,用来增加一个字节

TCHAR m_szFullName[_MAX_PATH]; //绝对路径

#ifdef _DEBUG

//实现Dump虚拟函数,输出文件属性

void Dump(CDumpContext& dc) const;

#endif

};

例如:

CFileStatus status;

pFile->GetStatus(status);

#ifdef _DEBUG

statusdump(afxDump);

#endif

如果你要使用数据同步功能,请仔细阅读以下内容

一、基本概念

数据集 - 指同步的对象,对于数据库,一个表,就是一个数据集;

记录 - 组成数据集的数据条目,与数据库里的记录是同等概念;

字段 - 一条记录的各个属性数据,与数据库里的字段是同等概念;

"关键字段" - 一个特殊的字段,它的值具有唯一性,在一个表中,不会有两条记录的关键字段有相同值。关键字段应该是字符型或方便转换成字符串的。一旦记录写入完成,关键字段的值不可以被修改。关键字段不支持 Unicode。表的主键可以作为关键字段。为了提高同步效率,关键字段应该有索引。为什么要有关键字段?因为同步是根据关键字段来识别一条记录的,没有关键字段就不能区分各条记录,也就谈不上同步了。

"修改时间" - 这是一个字段,对新加的记录,该字段保存添加记录的日期时间,如果记录被修改,该字段保存记录最后被修改的日期时间。要实现对记录的修改也能进行同步,必须要有"修改时间"字段,即使不需要对修改记录进行同步,为了实现高效的数据同步,也要有"修改时间"字段。该字段支持 DateTime, Date 类型。为了提高同步效率,修改时间字段也应该有索引。如果同步的双方(两个数据集)都有同一条记录,但有一边的该记录修改过了,就要对比“修改时间”字段来判断究竟哪边是修改过的。如果某些表,记录不算多(数百或上千条记录都算是较少的),且只会往里面添加记录,不会修改及删除其中的记录,那么,不需要有修改时间字段。同步专家网络版有一个时间选项,允许只同步最近多少天修改的记录,对于记录数量庞大的情况,经过这一选项的过滤,要扫描的记录就不多了。最大限度地节省同步所需要的时间。

"删除标记" - 这是一个字段, 为了对记录的删除 *** 作也能进行同步,要求应用系统删除记录时,不是立即从表中删除它,而是先将该记录的"删除标记"置为"真"。为什么要这样做?如果没有“删除标记”,删除记录时立即从表中删除,那么,对于双向同步的情况,该记录被删除之前,有可能已经同步到其它主机上了,下次同步时,可能将该记录又从其它主机同步回来了。在应用系统中要增加一个功能模块,用于定期(手工或自动)对表进行清理,删除所有标记为 已删除 的记录。

If you want to use data synchronization functions, please read carefully the following one, the basic concept of data sets - is the object synchronization, For database, a table is a data set; record-component data sets of data entry, and database records is the same concept; field-a record of all the attribute data, and the database field is the same concept; "keyword" - a special field, and its value is unique in a table, there will be no record of the two key words of the same value Keywords should be of the character or facilitate conversion as a string Once complete written record, the value of keywords can not be amended Keyword does not support Unicode The primary key table can be used as keywords To improve synchronization efficiency, should be the keyword of the index Why should there be a keyword Synchronization is because of the keyword to identify a record, not keywords can not distinguish between the various records, would be out of synchronization "Modified" - this is a field, plus the new record, the field record keeping Add the dates and times If the record changes, the field record keeping was last modified dates and times To achieve the right to amend the records can be used for synchronization, have "modified" field Even if no right to amend the records simultaneously, in order to achieve efficient data synchronization, and must have "modified" field The field support DateTime, Date type To improve synchronization efficiency, modified field should also indexed If both synchronous (two data sets) had with a record, but the record side of the revisions, it is necessary to contrast the "modified" to determine whether the field which side is to amend before If certain forms, record low (hundreds or thousands of records are considered less), and will only add records Montaigne, and will not be revised to delete the record, then there is no need for a modified field Synchronous network of experts version of a time option to allow synchronization only recently revised the number of days the record For a huge number of records, the result of this filtering option to scan the records is not a lot Synchronous maximize savings by the time required "Delete markings" - this is a field, in order to delete the records can also operate synchronously, Application requests to delete records, is not immediately deleted from the table it but this first recording of the "delete labeled" home "really" Why would they do this If there is no "delete labeled" delete records immediately deleted from the table, then for a two-way synchronization, the record was deleted before it may have been synchronized to other hosts on the next synchronization, perhaps it recorded simultaneously from other mainframe back Application of the system to increase a functional module, for the periodic (manual or automatic) right table cleared delete all marked as deleted records

连接mysql错误2013是设置错误造成的,解决方法为:

1、回到电脑桌面,找到我的电脑点击右键。找到管理选项双击。

2、点击服务和应用程序。

3、点击服务。

4、找到MySql。发现描述项为空。双击。

5、点击启动,再次打开MySql连接,就能连接成功了。

以上就是关于关系型数据库的局限性有哪些难以满足高并发读写的需求全部的内容,包括:关系型数据库的局限性有哪些难以满足高并发读写的需求、如何批量获取一个文件夹下的文件属性,然后存入数据库、翻译 Database 数据同步功能 中译英啊~~~~ Part I等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9736884.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存