注册 登录
编程论坛 VFP论坛

老车认为CURSOR表在磁盘

惬意_甬车 发布于 2024-02-19 21:29, 1639 次点击
  ___2021年10月17日

  CURSOR表在哪里存放由于没有权威的明确说明,VFP业界大师们时常讨论,有说在内存的,有说在磁盘的,还有说数据量小时在内存,大时转磁盘。老车认为CURSOR表必须在磁盘,理由如下:
  一、首先要确定CURSOR表的主要作用是什么。老车认为CURSOR表主要是为作为远程表与VFP的链接表(也叫视图)而设计的。老车在学用CA 与SQL 时发现、用CA从远程SQL检索到VFP中的视图,也就是CURSOR表,与SQL中的源表结合的相当牢固,老车曾经设想需要切开时随时切开,需要链接时随时链接,然而花了几天时间都切不开,至今也没能切开,觉得除非退出VFP、断电或拨下网线,否则无法切开。说这些老车是想说明作为视图的CURSOR表与远程SQL中的源表结合是相当紧密复杂的,怎么可以忽而内存忽而磁盘的随时折腾呢?还有数据在内存与磁盘的存放方式应该是不同的,关联方式也就不同,来来回回折腾需要改变链接方式,必然是很要命的;还有正在折腾时发生断电等导致数据表损坏的机率徒增,且很难预防和处理;还有计算机操作都是瞬息万变的,总是那么来来回回折腾不仅费机时,判断也是很累的。如果是老车编写VFP不会那么整的。
  二、我们都知道电脑内存或VFP所能管理的内存是有限的,不足以容纳特大的SQL源表,而磁盘对操作SQL数据表而言可以视为足够大,所以VFP不会将CURSOR表放在内存,而要放在磁盘。
  三、CURSOR表不作为SQL等远程源表的视图,而作为VFP自身数据载体只是该表的附属功能,VFP不会因附属功能而另设计存放方式的。并且如果放入内存,也同样存在内存容量不足来回折腾的问题。
  四、用 DBF() 函数获取的CURSOR 表所在位置无一不在磁盘更能说明问题,也不知道为什么DBF() 获取的位置明明是在磁盘上,还有硬说在内存的。
  五、 CURSOR 关闭就没有了,在机子里总是找不到CURSOR是因为VFP有删除它的机制,关闭时删除、退出VFP删除、启动VFP删除。想象一下CURSOR作为远程SQL源表的视图,该表关闭后再打开,远程SQL源表是否可能发生变化,这个表再打开还能用吗,保留它不就垃圾吗?老车也见样学样、学着VFP专门设了一个存放垃圾文件的文件夹,可能成为垃圾的表就往那个文件夹放,每当软件退出与重启都清理一下那个文件夹。

  可能也会有说讨论这个没意义,CURSOR保存在哪不关我的事,其实是有意义的。之前老车认为CURSOR在内存运行速度能快些,还不产生垃圾,有时宁可舍去某种功能、例如CURSOR表不能PACK也绕着用它。自认定CURSOR在磁盘运行速度不会快,若再因此舍去功能用它就不划算了,所以除作为远程SQL源表的视图,CURSOR表的应用就减少了。

  以上仅是老车个人观点,也无真凭实据,欢迎持不同观点的大师提反面意见,但也要说出一、二、三、……道理,不可简单的只说就是就不是。


[此贴子已经被作者于2024-2-19 21:33编辑过]

20 回复
#2
老去的流星雨2024-02-20 08:04
不用怀疑,用DBF('CURSOR名')可以知道是在临时文件夹里
#3
惬意_甬车2024-02-20 09:35
是的,那个临时文件夹在磁盘上,不是在内存。
#4
kangss2024-02-20 10:13
只有本站会员才能查看附件,请 登录


只有本站会员才能查看附件,请 登录
#5
kangss2024-02-20 10:15
回复 2楼 老去的流星雨
有“临时文件名”,不一定“真实存在”
还有一个“虚拟内存”,硬盘“仿真”的内存
#6
kangss2024-02-20 10:18
以下是引用惬意_甬车在2024-2-20 09:35:53的发言:

是的,那个临时文件夹在磁盘上,不是在内存。

只有本站会员才能查看附件,请 登录
#7
惬意_甬车2024-02-20 11:24
欢迎 4-6 楼 kangss大师的认真讨论!也欢迎更多大师参与讨论!老车不怕被驳倒,甚至希望被驳倒,能讨论清楚狐友们共同有收获就好。
#8
kangss2024-02-20 11:35
“数据量小时在内存,大时转磁盘”可能是我说的,这是由windows内存管理机制自动控制的。
当内存不足时,windows会把当前“物理内存”中的部分数据转存到“虚拟内存”中,虚拟内存是硬盘上的文件Pagefile.sys,转存的不是“表”是“内存”。

就像笔记本合盖之后的休眠,windows会把内存、包括打开的各个软件、各个窗口界面等信息保存到Hiberfil.sys文件中,当再次打开系统时候,windows把Hiberfil.sys加载到内存中,开机后的界面跟之前合上笔记本盖子的界面“一模一样”
#9
惬意_甬车2024-02-20 12:04
猜想:VFP在处理DBF表或CURSOR表的某些过程中、如某条记录的某字段值、某条记录、再扩大一点也可能将表中记录分批放入内存处理,或者说必须放入内存处理是合乎逻辑的。但如果将表的数万、数十万百万千万,甚至上亿条记录都放入内存处理,老车觉得这不是VFP的强项,VFP的强项是处理DBF表,也就是猜想VFP不会那么整。
老车编程非常喜欢用数组,甚至可以说用的走火入魔。有大师说方法不好,因为数组用多占据内存。那么编程用的数组与可能上亿条记录的CURSOR表放入内存,谁更占用内存呢?
#10
chychychy2024-02-20 16:11
#11
老去的流星雨2024-02-20 17:16
以下是引用kangss在2024-2-20 10:15:15的发言:

有“临时文件名”,不一定“真实存在”
还有一个“虚拟内存”,硬盘“仿真”的内存


表肯定是在内存中缓存的,查询cursor应该是从内存,数据库都有缓存机制,但是数据是写入磁盘的

CREATE CURSOR temp(test C(10))
INSERT INTO temp (test) values('aaa')
_cliptext = DBF('temp')
SELECT * FROM C:\USERS\ADMINI~1\APPDATA\LOCAL\TEMP\0000QHAH0030.TMP
#12
惬意_甬车2024-02-20 18:14
老车只能认为这是将 temp 存到 C:\USERS\ADMINI~1\APPDATA\LOCAL 文件夹了,如果说还是在内存理解不了了。
只有本站会员才能查看附件,请 登录
#13
kangss2024-02-20 19:19
以下是引用老去的流星雨在2024-2-20 17:16:26的发言:



表肯定是在内存中缓存的,查询cursor应该是从内存,数据库都有缓存机制,但是数据是写入磁盘的

CREATE CURSOR temp(test C(10))
INSERT INTO temp (test) values('aaa')
_cliptext = DBF('temp')
SELECT * FROM C:\USERS\ADMINI~1\APPDATA\LOCAL\TEMP\0000QHAH0030.TMP


重新启动一个干净的VFP,执行以上代码,看看有没有“0000QHAH0030.TMP”在硬盘上?

只有本站会员才能查看附件,请 登录

windows有“重定向”功能,你看到的“我的文档”“我的电脑”“我的图片”,事实上文件夹名称并不是这些汉字

虽然你执行“SELECT ... 0000QHAH0030.TM”成功,但它并不是从“C盘”上读取的。你可以看看“0000QHAH0030.TMP”在不在C盘
#14
kangss2024-02-20 19:22
以下是引用惬意_甬车在2024-2-20 18:14:58的发言:

老车只能认为这是将 temp 存到 C:\USERS\ADMINI~1\APPDATA\LOCAL 文件夹了,如果说还是在内存理解不了了。


你要在这个文件夹里面找到那个文件,才能证明它不在内存
#15
惬意_甬车2024-02-20 19:35
#16
惬意_甬车2024-02-21 19:29
以下是引用kangss在2024-2-20 19:19:31的发言:



重新启动一个干净的VFP,执行以上代码,看看有没有“0000QHAH0030.TMP”在硬盘上?


windows有“重定向”功能,你看到的“我的文档”“我的电脑”“我的图片”,事实上文件夹名称并不是这些汉字

虽然你执行“SELECT ... 0000QHAH0030.TM”成功,但它并不是从“C盘”上读取的。你可以看看“0000QHAH0030.TMP”在不在C盘
kangss兄弟暨家人过年好!
以上老车之言也都是个人认识,无任何真凭实据,觉得这个议题应该很难讨论清楚,建议打住!
在2024年新年之际能与兄弟认真友好的讨论议题深感荣幸,我们多楼的讨论无任何互相 贬低、攻击 之言,更无人身攻击之语,难能可贵。体现了兄弟为人平易友好,老车愿与兄弟交朋友,欢迎以后更多讨论议题,互相学习、互相帮助、共同进步。

[此贴子已经被作者于2024-2-21 19:42编辑过]

#17
shenlancwz2024-05-01 21:40
路过
#18
hsfisher2025-06-30 08:15
学习了
#19
nikon2025-07-17 00:15
首先,车同学理解的CURSOR表本身就有偏差,导致后续的理解不正确,CURSOR表是临时表,用作远程表和链接表只是一方面的应用,但是他本身是当做临时表存在的。
临时表的使用范围很广,主要用于过渡表,机制就是先在内存产生,然后在磁盘镜像,使用临时表的好处就是不用考虑表放在磁盘的哪个位置,后续怎么处理,全部交给vfp本身。
如果程序是配合远端数据库使用的话,那尽量用临时表,这样就可以做到“片叶不沾身”的效果,也可以实现多开客户端的功能,如果过渡表是使用dbf的实际表,那多开客户端首先就面临实际表冲突的可能,当年我不会使用临时表的时候,为了能多开客户端,着实为了处理这个实际表头疼了一阵。
临时表确实好用,而且确实存在于内存,这个在内存的开销中可以很容易的看出来,做个简单的实验就可以:开100个各自含有1万条数据的临时表和开100个各自含有1万条数据的dbf所使用的内存开销是不一样的。
实际上,数组也是一个表,和临时表性质是一样的,只是运作机理略有不同,数组是foxpro从c那边学来的。
虽然vfp已经老旧,好多东西不支持,但为什么好用,就是3大法宝:
1.本身有数据表(table)不像c没有,只能使用数组,或者干脆去远端操作数据库。
2.本身支持sql语言,虽然和mssql略有不同,但是谁能说mssql就是标准了?mysql和oracle就不同意。你可以直接在本地欢乐地使用sql语言操作数据,不用去远端搞,要知道以现在的pc性能,好多小数据处理可以直接在本地弄的。
3,支持各种api,fll,ocx,甚至多任务多线程,而且嵌合度比较高,使用起来很顺滑,可以弥补自身老旧的问题。
总之,小小临时表的设计就可以知道当年微软大哥是想把他搞大的,然而后来发现sql更香。前后差了2年就发现sybase更好谈,fox这边太执着,所以就放弃使用vfp搞大型数据库了呗,但是vfp好用是事实,所以微软也是很良心的给vfp留了很多的财富。

[此贴子已经被作者于2025-7-17 00:17编辑过]

#20
ccb20002025-07-23 11:12
参考SYS(3050) - 设置缓冲内存大小。
如果使用内存<=缓冲内存,cursor数据保存在内存中。
如果使用内存>缓冲内存,vfp把cursor数据及dbf数据刷新到磁盘中,增加可用内存。

#21
schtg2025-07-23 15:13
回复 20楼 ccb2000
学习啦,谢谢!
1