那么可以在客户端远程打开服务端的数据库,再用_RecordsetPtr的GetCollect()方法可以取得数据库中对应表中的数据,
并通过客户端的控件将数据显示出来,也可以用_RecordsetPtr的PutCollect()修改服务端的数据库中表的能容,感觉很方便。
问题:如果有几万甚至几十万的客户端程序,通过IP地址操作服务端的数据库,我感觉这样访问数据库的效率肯定会低下,
就像大型网游我想客户端应该不是通过IP操作服务端的数据库的吧?那不通过IP怎么操作数据库呢?
能给个具体的方法吗?
14 个解决方案
#1
一般的客户端并不是直接去访问数据库的,中间通过服务器端程序转
#2
中间通过服务器端程序转,怎么转?能说的具体点吗?
#3
一般客户端不去连接数据库。
客户端的请求发给服务器程序后,服务器区数据库中进行操作,
并将结果放回给客户端。
客户端的请求发给服务器程序后,服务器区数据库中进行操作,
并将结果放回给客户端。
#4
写一个服务器程序,所有的客户端都连接它,把要操作的命令发给服务器程序,由服务器程序去操作数据库,再将结果发回给客户端
#5
回4L大致了解,不过还有些具体的细节,我还要问下。
我现在要在客户端显示服务端数据库中表Table1的内容
Table1内容如下:
No Name
1 Li Ming
2 Wang
根据4L的方法,是不是应该这样:
客户端程序:
通过socket连接服务端后,send(“select * from Table1”);
服务端程序:
_ _RecordsetPtr m_Recordset
1.接收操作命令:Recv(&buf);
2.收到命令后用打开记录集:m_Recordset->Open(buf);
3.用一个while循环读取每条记录
_variant_t varNo,varName; //用于读取一条记录的各项
CString strSend=””; //用于将发送个客户端的内容组成一个字符串
While(!m_Recordset.IsEOF())
{
m_Recordset.GetCollect(“No”,varNo);//取得No
strSend+=(LPCTSTR)(_bstr_t)varNo;//转换成字符型
m_Recordset.GetCollect(“Name”,varName);
strSend+=(LPCTSTR)(_bstr_t)varName; //取得Name
m_Recordset.MoveNext();
}
4:将读取的字符串(strSend)数据发送给客户端:send(strSend);
客户端程序:
1. 接收数据,recv(&buf);
2. 将buf拆分成一个个No,Name,以数据表的形式将内容显示在客户端
4L你觉得我的方法正确吗?有没有什么改进或注意的地方?
我现在要在客户端显示服务端数据库中表Table1的内容
Table1内容如下:
No Name
1 Li Ming
2 Wang
根据4L的方法,是不是应该这样:
客户端程序:
通过socket连接服务端后,send(“select * from Table1”);
服务端程序:
_ _RecordsetPtr m_Recordset
1.接收操作命令:Recv(&buf);
2.收到命令后用打开记录集:m_Recordset->Open(buf);
3.用一个while循环读取每条记录
_variant_t varNo,varName; //用于读取一条记录的各项
CString strSend=””; //用于将发送个客户端的内容组成一个字符串
While(!m_Recordset.IsEOF())
{
m_Recordset.GetCollect(“No”,varNo);//取得No
strSend+=(LPCTSTR)(_bstr_t)varNo;//转换成字符型
m_Recordset.GetCollect(“Name”,varName);
strSend+=(LPCTSTR)(_bstr_t)varName; //取得Name
m_Recordset.MoveNext();
}
4:将读取的字符串(strSend)数据发送给客户端:send(strSend);
客户端程序:
1. 接收数据,recv(&buf);
2. 将buf拆分成一个个No,Name,以数据表的形式将内容显示在客户端
4L你觉得我的方法正确吗?有没有什么改进或注意的地方?
#6
这个方法也可以。
不过客户端通常不会直接发送SQL过去,
应该是逻辑抽象,类似于下面的。
1 C->S 请求用户列表
2 S 从数据库取得列表
3 S->C 返回取得的用户列表
不过客户端通常不会直接发送SQL过去,
应该是逻辑抽象,类似于下面的。
1 C->S 请求用户列表
2 S 从数据库取得列表
3 S->C 返回取得的用户列表
#7
你这种方法也是可以的,服务器只管中转,由客户端处理,服务器的负载不会太大.
一般的做法正如六楼所讲,不会直接发送数据库命令的.客户端将所需要的参数信息发给服务器,服务器处理完后将给果返回给客户端
#8
6L的三步讲的有点抽象,我不太明白(老实说是不明白)各步具体做些什么?
能结合我给的具体例子讲讲吗?
在这先谢谢6L。
能结合我给的具体例子讲讲吗?
在这先谢谢6L。
#9
7L说发送参数是指(以我的例子为例)只要发送表名(Table1),
send("Table1")
不要直接发送SQL语句是吧?
send("Table1")
不要直接发送SQL语句是吧?
#10
#11
在5L的例子上做进一步的补充。
现在服务端数据库中变成了两个表:
Table1 Table2
No Name ID PassWord
1 LiMing 01 1234
2 Wang 02 5678
现在客户端在一个页面中单击按钮1显示Tabel1的能容,
在另一个页面中单击按钮2显示Table2的内容。
由于现在增加到了两个表,我想到在发送的结构体中加入
一个nType来标记从哪个表中度数据。
程序实现
构造发送的数据结构
Struct Data
{
UINT nType; //判断从哪个数据表中读取内容
//可以取值TABLE1 和TABEL2
CString strTable;//要读取的数据表名称
}
客户端:
单击按钮1:send(Data(TABLE1,”Table1”);recv();
单击按钮2:send(Data(TABLE2,"Table2"
服务端:
Recv(&data);
_variant_t var;
Switch(data.nType)
{
Case TABLE1: 用m_Recorset->GetCollect(“No”,var)
读取Table1中信息,发送读取内容到客户端 break;
Case TABLE2: 用m_Recorset->GetCollect(“ID”,var)
读取TableL2中信息,发送读取内容到客户端 break;
}
但是如果要从服务端的几十个表中读取数据,就要设置几十个case,现在但是读要设置几十个case,
如果要写如数据库的话又要设置几十个case,感觉这样做case设置的太多了。
是不是我的方法不好啊?
大家有什么好方法吗?
现在服务端数据库中变成了两个表:
Table1 Table2
No Name ID PassWord
1 LiMing 01 1234
2 Wang 02 5678
现在客户端在一个页面中单击按钮1显示Tabel1的能容,
在另一个页面中单击按钮2显示Table2的内容。
由于现在增加到了两个表,我想到在发送的结构体中加入
一个nType来标记从哪个表中度数据。
程序实现
构造发送的数据结构
Struct Data
{
UINT nType; //判断从哪个数据表中读取内容
//可以取值TABLE1 和TABEL2
CString strTable;//要读取的数据表名称
}
客户端:
单击按钮1:send(Data(TABLE1,”Table1”);recv();
单击按钮2:send(Data(TABLE2,"Table2"
服务端:
Recv(&data);
_variant_t var;
Switch(data.nType)
{
Case TABLE1: 用m_Recorset->GetCollect(“No”,var)
读取Table1中信息,发送读取内容到客户端 break;
Case TABLE2: 用m_Recorset->GetCollect(“ID”,var)
读取TableL2中信息,发送读取内容到客户端 break;
}
但是如果要从服务端的几十个表中读取数据,就要设置几十个case,现在但是读要设置几十个case,
如果要写如数据库的话又要设置几十个case,感觉这样做case设置的太多了。
是不是我的方法不好啊?
大家有什么好方法吗?
#12
简单一点儿的,自定义一个数据传输格式:@@表名(动作)#字段名:值#字段名:值....
动作表示要操作数据库的命令
@@Table1(1)#No:*#Name:*#ID:*#Password:*
发送这个数据到服务器,服务器解析这个数据后生成sql命令,然后执行.
只需要这一个解析的东东就行了.
if(string头两字==@@)
{
解析这个字符串
sprintf(select 解析的值...)
}
执行这个语句
返回结果
客户端多的话,就一个线程接收生成命令,一个线程执行命令,生成结果,一个传送结果
动作表示要操作数据库的命令
@@Table1(1)#No:*#Name:*#ID:*#Password:*
发送这个数据到服务器,服务器解析这个数据后生成sql命令,然后执行.
只需要这一个解析的东东就行了.
if(string头两字==@@)
{
解析这个字符串
sprintf(select 解析的值...)
}
执行这个语句
返回结果
客户端多的话,就一个线程接收生成命令,一个线程执行命令,生成结果,一个传送结果
#13
回水无痕
这方法不错,比我的好太多了。
多谢你的认真回答。
PS:你是不是从事这方面开发的啊。
这方法不错,比我的好太多了。
多谢你的认真回答。
PS:你是不是从事这方面开发的啊。
#14
结贴了,再次感谢水无痕
#1
一般的客户端并不是直接去访问数据库的,中间通过服务器端程序转
#2
中间通过服务器端程序转,怎么转?能说的具体点吗?
#3
一般客户端不去连接数据库。
客户端的请求发给服务器程序后,服务器区数据库中进行操作,
并将结果放回给客户端。
客户端的请求发给服务器程序后,服务器区数据库中进行操作,
并将结果放回给客户端。
#4
写一个服务器程序,所有的客户端都连接它,把要操作的命令发给服务器程序,由服务器程序去操作数据库,再将结果发回给客户端
#5
回4L大致了解,不过还有些具体的细节,我还要问下。
我现在要在客户端显示服务端数据库中表Table1的内容
Table1内容如下:
No Name
1 Li Ming
2 Wang
根据4L的方法,是不是应该这样:
客户端程序:
通过socket连接服务端后,send(“select * from Table1”);
服务端程序:
_ _RecordsetPtr m_Recordset
1.接收操作命令:Recv(&buf);
2.收到命令后用打开记录集:m_Recordset->Open(buf);
3.用一个while循环读取每条记录
_variant_t varNo,varName; //用于读取一条记录的各项
CString strSend=””; //用于将发送个客户端的内容组成一个字符串
While(!m_Recordset.IsEOF())
{
m_Recordset.GetCollect(“No”,varNo);//取得No
strSend+=(LPCTSTR)(_bstr_t)varNo;//转换成字符型
m_Recordset.GetCollect(“Name”,varName);
strSend+=(LPCTSTR)(_bstr_t)varName; //取得Name
m_Recordset.MoveNext();
}
4:将读取的字符串(strSend)数据发送给客户端:send(strSend);
客户端程序:
1. 接收数据,recv(&buf);
2. 将buf拆分成一个个No,Name,以数据表的形式将内容显示在客户端
4L你觉得我的方法正确吗?有没有什么改进或注意的地方?
我现在要在客户端显示服务端数据库中表Table1的内容
Table1内容如下:
No Name
1 Li Ming
2 Wang
根据4L的方法,是不是应该这样:
客户端程序:
通过socket连接服务端后,send(“select * from Table1”);
服务端程序:
_ _RecordsetPtr m_Recordset
1.接收操作命令:Recv(&buf);
2.收到命令后用打开记录集:m_Recordset->Open(buf);
3.用一个while循环读取每条记录
_variant_t varNo,varName; //用于读取一条记录的各项
CString strSend=””; //用于将发送个客户端的内容组成一个字符串
While(!m_Recordset.IsEOF())
{
m_Recordset.GetCollect(“No”,varNo);//取得No
strSend+=(LPCTSTR)(_bstr_t)varNo;//转换成字符型
m_Recordset.GetCollect(“Name”,varName);
strSend+=(LPCTSTR)(_bstr_t)varName; //取得Name
m_Recordset.MoveNext();
}
4:将读取的字符串(strSend)数据发送给客户端:send(strSend);
客户端程序:
1. 接收数据,recv(&buf);
2. 将buf拆分成一个个No,Name,以数据表的形式将内容显示在客户端
4L你觉得我的方法正确吗?有没有什么改进或注意的地方?
#6
这个方法也可以。
不过客户端通常不会直接发送SQL过去,
应该是逻辑抽象,类似于下面的。
1 C->S 请求用户列表
2 S 从数据库取得列表
3 S->C 返回取得的用户列表
不过客户端通常不会直接发送SQL过去,
应该是逻辑抽象,类似于下面的。
1 C->S 请求用户列表
2 S 从数据库取得列表
3 S->C 返回取得的用户列表
#7
你这种方法也是可以的,服务器只管中转,由客户端处理,服务器的负载不会太大.
一般的做法正如六楼所讲,不会直接发送数据库命令的.客户端将所需要的参数信息发给服务器,服务器处理完后将给果返回给客户端
#8
6L的三步讲的有点抽象,我不太明白(老实说是不明白)各步具体做些什么?
能结合我给的具体例子讲讲吗?
在这先谢谢6L。
能结合我给的具体例子讲讲吗?
在这先谢谢6L。
#9
7L说发送参数是指(以我的例子为例)只要发送表名(Table1),
send("Table1")
不要直接发送SQL语句是吧?
send("Table1")
不要直接发送SQL语句是吧?
#10
#11
在5L的例子上做进一步的补充。
现在服务端数据库中变成了两个表:
Table1 Table2
No Name ID PassWord
1 LiMing 01 1234
2 Wang 02 5678
现在客户端在一个页面中单击按钮1显示Tabel1的能容,
在另一个页面中单击按钮2显示Table2的内容。
由于现在增加到了两个表,我想到在发送的结构体中加入
一个nType来标记从哪个表中度数据。
程序实现
构造发送的数据结构
Struct Data
{
UINT nType; //判断从哪个数据表中读取内容
//可以取值TABLE1 和TABEL2
CString strTable;//要读取的数据表名称
}
客户端:
单击按钮1:send(Data(TABLE1,”Table1”);recv();
单击按钮2:send(Data(TABLE2,"Table2"
服务端:
Recv(&data);
_variant_t var;
Switch(data.nType)
{
Case TABLE1: 用m_Recorset->GetCollect(“No”,var)
读取Table1中信息,发送读取内容到客户端 break;
Case TABLE2: 用m_Recorset->GetCollect(“ID”,var)
读取TableL2中信息,发送读取内容到客户端 break;
}
但是如果要从服务端的几十个表中读取数据,就要设置几十个case,现在但是读要设置几十个case,
如果要写如数据库的话又要设置几十个case,感觉这样做case设置的太多了。
是不是我的方法不好啊?
大家有什么好方法吗?
现在服务端数据库中变成了两个表:
Table1 Table2
No Name ID PassWord
1 LiMing 01 1234
2 Wang 02 5678
现在客户端在一个页面中单击按钮1显示Tabel1的能容,
在另一个页面中单击按钮2显示Table2的内容。
由于现在增加到了两个表,我想到在发送的结构体中加入
一个nType来标记从哪个表中度数据。
程序实现
构造发送的数据结构
Struct Data
{
UINT nType; //判断从哪个数据表中读取内容
//可以取值TABLE1 和TABEL2
CString strTable;//要读取的数据表名称
}
客户端:
单击按钮1:send(Data(TABLE1,”Table1”);recv();
单击按钮2:send(Data(TABLE2,"Table2"
服务端:
Recv(&data);
_variant_t var;
Switch(data.nType)
{
Case TABLE1: 用m_Recorset->GetCollect(“No”,var)
读取Table1中信息,发送读取内容到客户端 break;
Case TABLE2: 用m_Recorset->GetCollect(“ID”,var)
读取TableL2中信息,发送读取内容到客户端 break;
}
但是如果要从服务端的几十个表中读取数据,就要设置几十个case,现在但是读要设置几十个case,
如果要写如数据库的话又要设置几十个case,感觉这样做case设置的太多了。
是不是我的方法不好啊?
大家有什么好方法吗?
#12
简单一点儿的,自定义一个数据传输格式:@@表名(动作)#字段名:值#字段名:值....
动作表示要操作数据库的命令
@@Table1(1)#No:*#Name:*#ID:*#Password:*
发送这个数据到服务器,服务器解析这个数据后生成sql命令,然后执行.
只需要这一个解析的东东就行了.
if(string头两字==@@)
{
解析这个字符串
sprintf(select 解析的值...)
}
执行这个语句
返回结果
客户端多的话,就一个线程接收生成命令,一个线程执行命令,生成结果,一个传送结果
动作表示要操作数据库的命令
@@Table1(1)#No:*#Name:*#ID:*#Password:*
发送这个数据到服务器,服务器解析这个数据后生成sql命令,然后执行.
只需要这一个解析的东东就行了.
if(string头两字==@@)
{
解析这个字符串
sprintf(select 解析的值...)
}
执行这个语句
返回结果
客户端多的话,就一个线程接收生成命令,一个线程执行命令,生成结果,一个传送结果
#13
回水无痕
这方法不错,比我的好太多了。
多谢你的认真回答。
PS:你是不是从事这方面开发的啊。
这方法不错,比我的好太多了。
多谢你的认真回答。
PS:你是不是从事这方面开发的啊。
#14
结贴了,再次感谢水无痕