但下面这个情况常常遇到:
顺序是我录入的先后顺序(台帐中的先后顺序),在我录入的过程中,
可能录丢了某条记录,当然要设法补到原记录位置,,这就是"插入"功能,
象这种情况,大家怎么去处理?
肯定要借助于索引了,可偏偏又没有合适的关键字对应于录入的先后顺序.
有无高招?!
50 个解决方案
#1
嗯
不是很好办
台账有没有时间日期呢
如果有的话就好办多了
如果没有……
听听大家的意见 如何
@_@
不是很好办
台账有没有时间日期呢
如果有的话就好办多了
如果没有……
听听大家的意见 如何
@_@
#2
严格意义上说,关系数据库中的记录并没有顺序的概念,其实Append和Insert实际上是同一个操作,数据库管理系统缺省是按记录的生成顺序,也就是说,没有索引的数据表,索引就是记录创建时间。你所所说的情况,可以定义一个字段(数字,时间)来记录产生的时间。就解决了!
#3
不要借助于物理序, 在表中加一个顺序号,在你的程序中自动编号, 在需要插入时, 比如
新纪录想插在原来的顺序号(SeqNo)为1000的记录前, 则,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1000;
再把新纪录的SeqNo设为1000.
新纪录想插在原来的顺序号(SeqNo)为1000的记录前, 则,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1000;
再把新纪录的SeqNo设为1000.
#4
同意ALNG(至饶远势波千倾,渐满清辉月上弦) :
不借助物理顺序。在表中加一顺序号。
但不能使用自动编号,在数据库中自动编号是不可以更改的,既UPDATE语句对自动产生的内容无法更改。
你可以加一个字段,记载流水号,用触发器来实现,他默认是字符型的当前日期加时间
不借助物理顺序。在表中加一顺序号。
但不能使用自动编号,在数据库中自动编号是不可以更改的,既UPDATE语句对自动产生的内容无法更改。
你可以加一个字段,记载流水号,用触发器来实现,他默认是字符型的当前日期加时间
#5
过江项羽兄,
我是说在程序中自动编号(不是采用自增型,用插入触发器也不错), 把这个字段对用户而言隐藏起来。
我是说在程序中自动编号(不是采用自增型,用插入触发器也不错), 把这个字段对用户而言隐藏起来。
#6
严格意义上说,关系数据库中的记录物理顺序是不能更改的,否则会破坏数据库的结构,平时可通过索引或查询来达到要求,根据插入记录的条件,人为定义一个字段,进行索引即可。
#7
加上一个顺序号做索引是大家的共识,有两个方案:
1.用时间做索引
2.用数字做索引,
插入的那条记录的这个顺序号怎么定? 这就是"算法"了,
对于1. "时间",也有麻烦,时间相同就费事了,看起来简单,实现起来烦;
对于2. "数字"要有间隔,极端情况,插入多了,一旦间隔变成1,就麻烦了,
我喜欢用2,
大家看法呢?
1.用时间做索引
2.用数字做索引,
插入的那条记录的这个顺序号怎么定? 这就是"算法"了,
对于1. "时间",也有麻烦,时间相同就费事了,看起来简单,实现起来烦;
对于2. "数字"要有间隔,极端情况,插入多了,一旦间隔变成1,就麻烦了,
我喜欢用2,
大家看法呢?
#8
哈哈,我理解错你的意思了。
那用顺序号也不好,假如他插入的号,在你的顺序中已经有了,即已经是连续的了。
例如:想在1000,1001之间插入一条记录,顺序号就解决不了。所以用当前日期加时间来实现。
那用顺序号也不好,假如他插入的号,在你的顺序中已经有了,即已经是连续的了。
例如:想在1000,1001之间插入一条记录,顺序号就解决不了。所以用当前日期加时间来实现。
#9
没有哇, 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001;
然后把新纪录的SeqNo设为1001, 插入到表里
insert into MyTable(SeqNo, bla, bla1)values(1001, "a;df","a;ddf");
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001;
然后把新纪录的SeqNo设为1001, 插入到表里
insert into MyTable(SeqNo, bla, bla1)values(1001, "a;df","a;ddf");
#10
算法 :
1。 Get the SeqNo of the record before which I intend to insert the new record;
2. Execute query states:
update MyTable set SeqNo = seqNo +1 where seqno >= thatNumber;
3. Insert my new record
insert into MyTable(seqNo, bla, bla1)
values(thatNumber, "bla","bla1");
over.
A seqNo of width 32 bits would be more than sufficient.
1。 Get the SeqNo of the record before which I intend to insert the new record;
2. Execute query states:
update MyTable set SeqNo = seqNo +1 where seqno >= thatNumber;
3. Insert my new record
insert into MyTable(seqNo, bla, bla1)
values(thatNumber, "bla","bla1");
over.
A seqNo of width 32 bits would be more than sufficient.
#11
记录插入情况的确用得很多,特别是在企业中,
先有帐本后有数据据库,数据库跟着帐本走,
所以插入记录问题涉及得很多
先有帐本后有数据据库,数据库跟着帐本走,
所以插入记录问题涉及得很多
#12
to ALNG(至饶远势波千倾,渐满清辉月上弦):
主要考虑极端情况,
你的算法也有问题,在同一处插入多了,"顺序号"就有相同的情况,
一旦在相同的顺序号中间再插入,麻烦又来了,没法控制了;
主要考虑极端情况,
你的算法也有问题,在同一处插入多了,"顺序号"就有相同的情况,
一旦在相同的顺序号中间再插入,麻烦又来了,没法控制了;
#13
取日期和顺序号的组合做为序号
当前日期的顺序号是有限的,不容易发生"在相同的顺序号中间再插入"
而日期也能明确说明顺序
#14
取日期和顺序号的组合做为序号
当前日期的顺序号是有限的,不容易发生"在相同的顺序号中间再插入"
而日期也能明确说明顺序
#15
例子:
original data:
SeqNo Name
1 Wang
2 Li
3 Zhao
4 Feng
5 Xiao
6 Lu
7 Fang
Now I intend to insert a "Zan" before Feng,
1. the seqno for feng is 4;
2. update mytable set seqno=seqno+1 where seqno >= 4; you get
1 Wang
2 Li
3 Zhao
5 Feng
6 Xiao
7 Lu
8 Fang
3. Insert the new record, you get
1 Wang
2 Li
3 Zhao
4 Zan
5 Feng
6 Xiao
7 Lu
8 Fang
Now again insert a "Wu" before Zan, the same process as above, no room for confliction, AFAIK.
original data:
SeqNo Name
1 Wang
2 Li
3 Zhao
4 Feng
5 Xiao
6 Lu
7 Fang
Now I intend to insert a "Zan" before Feng,
1. the seqno for feng is 4;
2. update mytable set seqno=seqno+1 where seqno >= 4; you get
1 Wang
2 Li
3 Zhao
5 Feng
6 Xiao
7 Lu
8 Fang
3. Insert the new record, you get
1 Wang
2 Li
3 Zhao
4 Zan
5 Feng
6 Xiao
7 Lu
8 Fang
Now again insert a "Wu" before Zan, the same process as above, no room for confliction, AFAIK.
#16
>>BCB兄
请举出可能发生问题的情况
请举出可能发生问题的情况
#17
取日期和顺序号的组合做为序号
当前日期的顺序号是有限的,不容易发生"在相同的顺序号中间再插入"
而日期也能明确说明顺序
#18
这么多的回复呀~~~~~~
不好意思,csdn这两天问题多多,回复老出问题.
那些搞攻击的家伙也太无聊了~~~~~~~~~~~
不好意思,csdn这两天问题多多,回复老出问题.
那些搞攻击的家伙也太无聊了~~~~~~~~~~~
#19
确实, 这种无聊的行为应该受到抵制和谴责!
#20
to ALNG(至饶远势波千倾,渐满清辉月上弦):
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
#21
to ALNG(至饶远势波千倾,渐满清辉月上弦):
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
#22
to ALNG(至饶远势波千倾,渐满清辉月上弦):
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
#23
据我所知通常录入顺序是没有意义的,如果是货物通常都有货物编号,编号作关键码。如果是记账则可以通过时间查找。
#24
BCB,
比你想象的要快, 而且这个工作在后端作, 速度飞快。 你可以用一个大表作测试, 比你想象得要快。
如果你还是觉得不妥, 那就用这样吧
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
插入时把 SubIndex 加1, 比如要插在J前
SeqNo SubNo Name
1 0 V
2 0 M
2 1 x
3 0 J
4 0 K
5 0 L
6 0 N
可以满足你的要求吗? 等subindex满了(==max(unsigned))在调整SeqNo.
比你想象的要快, 而且这个工作在后端作, 速度飞快。 你可以用一个大表作测试, 比你想象得要快。
如果你还是觉得不妥, 那就用这样吧
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
插入时把 SubIndex 加1, 比如要插在J前
SeqNo SubNo Name
1 0 V
2 0 M
2 1 x
3 0 J
4 0 K
5 0 L
6 0 N
可以满足你的要求吗? 等subindex满了(==max(unsigned))在调整SeqNo.
#25
时间取当天时间(需要的话好可以取到小时)
当前日期+顺序号
如:
20010626+100
20010626+101
20010627+100
20010627+101
孤独兄说的货物编号据我所知就是以当前的日期加上一个顺序号来生成的
#26
顺序号需要整理的
如果将来删除
所以我建议尽量避免使用这个东西
@_@
如果将来删除
所以我建议尽量避免使用这个东西
@_@
#27
to songhtao(三十年孤独):
大型的用于数据查询的数据库的确顺序不重要,
但我偏偏要有录入顺序,企业里的报表全都有顺序,没有顺序就是不行
大型的用于数据查询的数据库的确顺序不重要,
但我偏偏要有录入顺序,企业里的报表全都有顺序,没有顺序就是不行
#28
顺序号不需要连续, 尽管删除, 不需要整理。
因为取数时是:
select * from mytable order by seqno, subno;
不联号根本不是问题。
#29
我的想法是,就是用整数做顺序编号,编号之间间隔较大,比如取step=1000,
每当插入一条时,取上下两条号的平均值做为新的顺序号,
坏的情况(间隔已为1):
从要插的位置往下找有间隙的顺序号,找到后,求新的平均间隔,
倒着往上调整顺序号,就可插入;
最极端坏的情况,到末尾间隔都为1就是大调整了, 间隔号改为step,
大家分析一下,怎样?!
每当插入一条时,取上下两条号的平均值做为新的顺序号,
坏的情况(间隔已为1):
从要插的位置往下找有间隙的顺序号,找到后,求新的平均间隔,
倒着往上调整顺序号,就可插入;
最极端坏的情况,到末尾间隔都为1就是大调整了, 间隔号改为step,
大家分析一下,怎样?!
#30
>>BCB
可以, 与这个方法实出一辙:
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
步长的选择比较关键, 我觉得对一般的应用而言, 100 足够, 当然, 越大需要调整的可能九越小, 1000也不错, 绝对可以解决你的问题了。(建议100)。
可以, 与这个方法实出一辙:
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
步长的选择比较关键, 我觉得对一般的应用而言, 100 足够, 当然, 越大需要调整的可能九越小, 1000也不错, 绝对可以解决你的问题了。(建议100)。
#31
求平均值的办法,所以在同一处插入约 log2(Step)次,就要面临小调整,
若取step=100,同一处6次左右就要调整了,step取1000,10次
根据需要了
若取step=100,同一处6次左右就要调整了,step取1000,10次
根据需要了
#32
说说我的管见。
首先,我觉得大型数据库中,数据行号的概念是很模糊的,记录的物理存储位置也很模糊,对于用户来说,任务是安排数据的录入而不是强迫数据库按照我们的思路进行操作。
我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际发生的情况决定,而流水号用存储过程/触发器的方法解决。
如果采用预留一定间隔的流水号的方式,一是很难确定间隔,二是很难排除极端情况。在大型数据库中,选择一个合理的流水号,甚至可能会引起若干个数据库物理文件的操作,从这点看,预留号带来的好处是微不足道的。而且,这样做也破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢?
首先,我觉得大型数据库中,数据行号的概念是很模糊的,记录的物理存储位置也很模糊,对于用户来说,任务是安排数据的录入而不是强迫数据库按照我们的思路进行操作。
我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际发生的情况决定,而流水号用存储过程/触发器的方法解决。
如果采用预留一定间隔的流水号的方式,一是很难确定间隔,二是很难排除极端情况。在大型数据库中,选择一个合理的流水号,甚至可能会引起若干个数据库物理文件的操作,从这点看,预留号带来的好处是微不足道的。而且,这样做也破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢?
#33
请不要使用连续号,要使用离散号。
应该这样:日期+时间+三位序号。
第一次生成时序号自动为000。
例如生成这样一组熟:(ABC)20001201100908000,20001201100912000,20001201100913000要在BC之间插入一个数字就可以为20001201100912100
应该这样:日期+时间+三位序号。
第一次生成时序号自动为000。
例如生成这样一组熟:(ABC)20001201100908000,20001201100912000,20001201100913000要在BC之间插入一个数字就可以为20001201100912100
#34
TR@SOE,
>>我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际
>>发生的情况决定,而流水号用存储过程/触发器的方法解决。
你在触发器里做了什么? 调整流水号以使新增的纪录逻辑上位于用户为它选定的位置, 是吗?
那么这个纪录的插入是不是也"破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢? "
实际上我觉得需要牵涉其他记录甚至其他表的机会是现实存在的, 不需要刻意回避。
>>我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际
>>发生的情况决定,而流水号用存储过程/触发器的方法解决。
你在触发器里做了什么? 调整流水号以使新增的纪录逻辑上位于用户为它选定的位置, 是吗?
那么这个纪录的插入是不是也"破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢? "
实际上我觉得需要牵涉其他记录甚至其他表的机会是现实存在的, 不需要刻意回避。
#35
>>请不要使用连续号,要使用离散号。
>>应该这样:日期+时间+三位序号。
这个与BCB的以1000为步长的得离散序号方式基本一致。
>>求平均值的办法,所以在同一处插入约 log2(Step)次,就要面临小调整,
>>若取step=100,同一处6次左右就要调整了,step取1000,10次
>>根据需要了
你这样在需要调整时反而更复杂, 如果插入是如此频繁的操作, 还不如:
MyTable:
SeqNo SubNo Name
把SeqNo和SubNo都设为32位整数, 如果要在SeqNo=1000, SubNo= 50的纪录前
插一个记录:
update MyTable set subno=subno+1 where SeqNo=1000 and SubNo >=50
这样的好处是通过SeqNo 尽可能缩小了需要调整的纪录的范围。 32位尽够你插入记录了,
所以不存在SeqNo调整的问题。
>>应该这样:日期+时间+三位序号。
这个与BCB的以1000为步长的得离散序号方式基本一致。
>>求平均值的办法,所以在同一处插入约 log2(Step)次,就要面临小调整,
>>若取step=100,同一处6次左右就要调整了,step取1000,10次
>>根据需要了
你这样在需要调整时反而更复杂, 如果插入是如此频繁的操作, 还不如:
MyTable:
SeqNo SubNo Name
把SeqNo和SubNo都设为32位整数, 如果要在SeqNo=1000, SubNo= 50的纪录前
插一个记录:
update MyTable set subno=subno+1 where SeqNo=1000 and SubNo >=50
这样的好处是通过SeqNo 尽可能缩小了需要调整的纪录的范围。 32位尽够你插入记录了,
所以不存在SeqNo调整的问题。
#36
用'日期/时间' 解决不了关键字唯一问题,也不要由用户自已决定值
#37
to ALNG:
你用两个关键字更不好,两个关键字其本质 跟加大Step是一回事!
你用两个关键字更不好,两个关键字其本质 跟加大Step是一回事!
#38
两个关键字(每个32b)相当于 step=65535
#39
ALNG,
我没有要求在触发器中调整流水号以确定位置啊,那是单纯的流水号而已。
BCB,
你应该定出你的记录物理定位的最小标准,如果日期+时间还不能够满足你的要求,那么继续增加判定标准,如单据的流水号等。这样的话,即使2001/06/26 13:00的记录在2001/06/26 08:00的记录之前登录,也有办法根据根据单据的流水号来进一步判断先后次序。这里当然还有个实际工作中的操作问题,例如,如果你的单据分发时是1-100给一个人,101-200给另一个业务员,那么可能会出现2001/06/26 12:00 101的记录发生在2001/06/26 12:00 99记录之前的情况。但是,我觉得这种可能性不会太多了。
我还是建议不要用预留号的方法。总之,你要自己定出完全可以物理上确定你的记录的先后次序的字段集。否则,任何方法都不能解决你的问题。
我没有要求在触发器中调整流水号以确定位置啊,那是单纯的流水号而已。
BCB,
你应该定出你的记录物理定位的最小标准,如果日期+时间还不能够满足你的要求,那么继续增加判定标准,如单据的流水号等。这样的话,即使2001/06/26 13:00的记录在2001/06/26 08:00的记录之前登录,也有办法根据根据单据的流水号来进一步判断先后次序。这里当然还有个实际工作中的操作问题,例如,如果你的单据分发时是1-100给一个人,101-200给另一个业务员,那么可能会出现2001/06/26 12:00 101的记录发生在2001/06/26 12:00 99记录之前的情况。但是,我觉得这种可能性不会太多了。
我还是建议不要用预留号的方法。总之,你要自己定出完全可以物理上确定你的记录的先后次序的字段集。否则,任何方法都不能解决你的问题。
#40
我主要是完整的讨论算法,所以要考虑极端情况,
step稍更大一点,基本就不会要多次调整更多的顺序号了,
当然,编了程序你就得考虑极端情况,"万一"出现呢.
step稍更大一点,基本就不会要多次调整更多的顺序号了,
当然,编了程序你就得考虑极端情况,"万一"出现呢.
#41
你用时间作辅助关键字就不代表极端情况不出现,
处理极端情况更复杂了,
就用间隔数字+调整的办法
最简单,我已试好.能满足一般要求,顺序号对用户
是透明的.
处理极端情况更复杂了,
就用间隔数字+调整的办法
最简单,我已试好.能满足一般要求,顺序号对用户
是透明的.
#42
总会有一天,你编数据库时,用户要求能随意"插入"记录,
(而你说,我只能插在末尾,顺序并不重要)
所以讨论这个问题是很有必要的
(而你说,我只能插在末尾,顺序并不重要)
所以讨论这个问题是很有必要的
#43
>>两个关键字其本质 跟加大Step是一回事!
>>两个关键字(每个32b)相当于 step=65535 (65536^2-1)
没错, 也才相当于一个INT64啊。
而且我反对在插入时搞复杂的算法, 因为你不是在操作内存, 你需要和DBMS通讯越少,速度就
越快。
看看你的算法:
Seq Name
1 A
1001 B
2001 C
在B之前插入,
1。 get the seq no of the one immediately before 1001, 1
2. the intended position 1+10001/2=501;
3. Insert the new record
This works pretty nice, but when you come accross such a positon as:
1 A
501 D
751 E
876 F
938 G
...
1000 P
1001 B
2001 C
the adjustment won't be an easy task.
So I 'd suggest that you KISS. Design a sophisticated algorithm for such a job may not be worthwhile, IMHO.
>>两个关键字(每个32b)相当于 step=65535 (65536^2-1)
没错, 也才相当于一个INT64啊。
而且我反对在插入时搞复杂的算法, 因为你不是在操作内存, 你需要和DBMS通讯越少,速度就
越快。
看看你的算法:
Seq Name
1 A
1001 B
2001 C
在B之前插入,
1。 get the seq no of the one immediately before 1001, 1
2. the intended position 1+10001/2=501;
3. Insert the new record
This works pretty nice, but when you come accross such a positon as:
1 A
501 D
751 E
876 F
938 G
...
1000 P
1001 B
2001 C
the adjustment won't be an easy task.
So I 'd suggest that you KISS. Design a sophisticated algorithm for such a job may not be worthwhile, IMHO.
#44
!
#45
并没有复杂的算法: 上、下记录编号相加/2为新插入的顺序编号,
稍复杂的部分就是处理极端情况(不能不考虑呀)
给分了!
稍复杂的部分就是处理极端情况(不能不考虑呀)
给分了!
#46
你说的顺序已经有商业含义了,应该用程序保证,即在表中加一个字段,
并且用程序来维护。最好不要用数据库来实现。
并且用程序来维护。最好不要用数据库来实现。
#47
在数据库设计的时间,增加个时间字段,如datetimestamp
以此为索引,就可以插入了。插入时构造个时间,就行了
不是很简单的//hehe
以此为索引,就可以插入了。插入时构造个时间,就行了
不是很简单的//hehe
#48
谁能告诉我win98下的vtoolsd开发工具包到哪里下载?email: mylanchat@163.com
#49
用链表可以解决
#50
to xiaoyu():
插多了,就没有中间"时间"可插了,你同样会遇到极端情况;
我说哑了,也没人听得进去.
插多了,就没有中间"时间"可插了,你同样会遇到极端情况;
我说哑了,也没人听得进去.
#1
嗯
不是很好办
台账有没有时间日期呢
如果有的话就好办多了
如果没有……
听听大家的意见 如何
@_@
不是很好办
台账有没有时间日期呢
如果有的话就好办多了
如果没有……
听听大家的意见 如何
@_@
#2
严格意义上说,关系数据库中的记录并没有顺序的概念,其实Append和Insert实际上是同一个操作,数据库管理系统缺省是按记录的生成顺序,也就是说,没有索引的数据表,索引就是记录创建时间。你所所说的情况,可以定义一个字段(数字,时间)来记录产生的时间。就解决了!
#3
不要借助于物理序, 在表中加一个顺序号,在你的程序中自动编号, 在需要插入时, 比如
新纪录想插在原来的顺序号(SeqNo)为1000的记录前, 则,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1000;
再把新纪录的SeqNo设为1000.
新纪录想插在原来的顺序号(SeqNo)为1000的记录前, 则,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1000;
再把新纪录的SeqNo设为1000.
#4
同意ALNG(至饶远势波千倾,渐满清辉月上弦) :
不借助物理顺序。在表中加一顺序号。
但不能使用自动编号,在数据库中自动编号是不可以更改的,既UPDATE语句对自动产生的内容无法更改。
你可以加一个字段,记载流水号,用触发器来实现,他默认是字符型的当前日期加时间
不借助物理顺序。在表中加一顺序号。
但不能使用自动编号,在数据库中自动编号是不可以更改的,既UPDATE语句对自动产生的内容无法更改。
你可以加一个字段,记载流水号,用触发器来实现,他默认是字符型的当前日期加时间
#5
过江项羽兄,
我是说在程序中自动编号(不是采用自增型,用插入触发器也不错), 把这个字段对用户而言隐藏起来。
我是说在程序中自动编号(不是采用自增型,用插入触发器也不错), 把这个字段对用户而言隐藏起来。
#6
严格意义上说,关系数据库中的记录物理顺序是不能更改的,否则会破坏数据库的结构,平时可通过索引或查询来达到要求,根据插入记录的条件,人为定义一个字段,进行索引即可。
#7
加上一个顺序号做索引是大家的共识,有两个方案:
1.用时间做索引
2.用数字做索引,
插入的那条记录的这个顺序号怎么定? 这就是"算法"了,
对于1. "时间",也有麻烦,时间相同就费事了,看起来简单,实现起来烦;
对于2. "数字"要有间隔,极端情况,插入多了,一旦间隔变成1,就麻烦了,
我喜欢用2,
大家看法呢?
1.用时间做索引
2.用数字做索引,
插入的那条记录的这个顺序号怎么定? 这就是"算法"了,
对于1. "时间",也有麻烦,时间相同就费事了,看起来简单,实现起来烦;
对于2. "数字"要有间隔,极端情况,插入多了,一旦间隔变成1,就麻烦了,
我喜欢用2,
大家看法呢?
#8
哈哈,我理解错你的意思了。
那用顺序号也不好,假如他插入的号,在你的顺序中已经有了,即已经是连续的了。
例如:想在1000,1001之间插入一条记录,顺序号就解决不了。所以用当前日期加时间来实现。
那用顺序号也不好,假如他插入的号,在你的顺序中已经有了,即已经是连续的了。
例如:想在1000,1001之间插入一条记录,顺序号就解决不了。所以用当前日期加时间来实现。
#9
没有哇, 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001;
然后把新纪录的SeqNo设为1001, 插入到表里
insert into MyTable(SeqNo, bla, bla1)values(1001, "a;df","a;ddf");
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001;
然后把新纪录的SeqNo设为1001, 插入到表里
insert into MyTable(SeqNo, bla, bla1)values(1001, "a;df","a;ddf");
#10
算法 :
1。 Get the SeqNo of the record before which I intend to insert the new record;
2. Execute query states:
update MyTable set SeqNo = seqNo +1 where seqno >= thatNumber;
3. Insert my new record
insert into MyTable(seqNo, bla, bla1)
values(thatNumber, "bla","bla1");
over.
A seqNo of width 32 bits would be more than sufficient.
1。 Get the SeqNo of the record before which I intend to insert the new record;
2. Execute query states:
update MyTable set SeqNo = seqNo +1 where seqno >= thatNumber;
3. Insert my new record
insert into MyTable(seqNo, bla, bla1)
values(thatNumber, "bla","bla1");
over.
A seqNo of width 32 bits would be more than sufficient.
#11
记录插入情况的确用得很多,特别是在企业中,
先有帐本后有数据据库,数据库跟着帐本走,
所以插入记录问题涉及得很多
先有帐本后有数据据库,数据库跟着帐本走,
所以插入记录问题涉及得很多
#12
to ALNG(至饶远势波千倾,渐满清辉月上弦):
主要考虑极端情况,
你的算法也有问题,在同一处插入多了,"顺序号"就有相同的情况,
一旦在相同的顺序号中间再插入,麻烦又来了,没法控制了;
主要考虑极端情况,
你的算法也有问题,在同一处插入多了,"顺序号"就有相同的情况,
一旦在相同的顺序号中间再插入,麻烦又来了,没法控制了;
#13
取日期和顺序号的组合做为序号
当前日期的顺序号是有限的,不容易发生"在相同的顺序号中间再插入"
而日期也能明确说明顺序
#14
取日期和顺序号的组合做为序号
当前日期的顺序号是有限的,不容易发生"在相同的顺序号中间再插入"
而日期也能明确说明顺序
#15
例子:
original data:
SeqNo Name
1 Wang
2 Li
3 Zhao
4 Feng
5 Xiao
6 Lu
7 Fang
Now I intend to insert a "Zan" before Feng,
1. the seqno for feng is 4;
2. update mytable set seqno=seqno+1 where seqno >= 4; you get
1 Wang
2 Li
3 Zhao
5 Feng
6 Xiao
7 Lu
8 Fang
3. Insert the new record, you get
1 Wang
2 Li
3 Zhao
4 Zan
5 Feng
6 Xiao
7 Lu
8 Fang
Now again insert a "Wu" before Zan, the same process as above, no room for confliction, AFAIK.
original data:
SeqNo Name
1 Wang
2 Li
3 Zhao
4 Feng
5 Xiao
6 Lu
7 Fang
Now I intend to insert a "Zan" before Feng,
1. the seqno for feng is 4;
2. update mytable set seqno=seqno+1 where seqno >= 4; you get
1 Wang
2 Li
3 Zhao
5 Feng
6 Xiao
7 Lu
8 Fang
3. Insert the new record, you get
1 Wang
2 Li
3 Zhao
4 Zan
5 Feng
6 Xiao
7 Lu
8 Fang
Now again insert a "Wu" before Zan, the same process as above, no room for confliction, AFAIK.
#16
>>BCB兄
请举出可能发生问题的情况
请举出可能发生问题的情况
#17
取日期和顺序号的组合做为序号
当前日期的顺序号是有限的,不容易发生"在相同的顺序号中间再插入"
而日期也能明确说明顺序
#18
这么多的回复呀~~~~~~
不好意思,csdn这两天问题多多,回复老出问题.
那些搞攻击的家伙也太无聊了~~~~~~~~~~~
不好意思,csdn这两天问题多多,回复老出问题.
那些搞攻击的家伙也太无聊了~~~~~~~~~~~
#19
确实, 这种无聊的行为应该受到抵制和谴责!
#20
to ALNG(至饶远势波千倾,渐满清辉月上弦):
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
#21
to ALNG(至饶远势波千倾,渐满清辉月上弦):
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
#22
to ALNG(至饶远势波千倾,渐满清辉月上弦):
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
" 先把>=1001的序号往后挪一位,
update MyTable set SeqNo =SeqNo+1 where SeqNo >=1001; "
记录不太多时较简单,
但记录较多时,从算法上来讲效率不高,
每当在最上端插入一条,所以记录的顺序号都要集体加1(株联太多);
to wjzhuang:
时间说穿了也是数字,插多了,也会相同的,
新插入的记录的'时间'怎么定呢?! 时间不定性更厉害
#23
据我所知通常录入顺序是没有意义的,如果是货物通常都有货物编号,编号作关键码。如果是记账则可以通过时间查找。
#24
BCB,
比你想象的要快, 而且这个工作在后端作, 速度飞快。 你可以用一个大表作测试, 比你想象得要快。
如果你还是觉得不妥, 那就用这样吧
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
插入时把 SubIndex 加1, 比如要插在J前
SeqNo SubNo Name
1 0 V
2 0 M
2 1 x
3 0 J
4 0 K
5 0 L
6 0 N
可以满足你的要求吗? 等subindex满了(==max(unsigned))在调整SeqNo.
比你想象的要快, 而且这个工作在后端作, 速度飞快。 你可以用一个大表作测试, 比你想象得要快。
如果你还是觉得不妥, 那就用这样吧
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
插入时把 SubIndex 加1, 比如要插在J前
SeqNo SubNo Name
1 0 V
2 0 M
2 1 x
3 0 J
4 0 K
5 0 L
6 0 N
可以满足你的要求吗? 等subindex满了(==max(unsigned))在调整SeqNo.
#25
时间取当天时间(需要的话好可以取到小时)
当前日期+顺序号
如:
20010626+100
20010626+101
20010627+100
20010627+101
孤独兄说的货物编号据我所知就是以当前的日期加上一个顺序号来生成的
#26
顺序号需要整理的
如果将来删除
所以我建议尽量避免使用这个东西
@_@
如果将来删除
所以我建议尽量避免使用这个东西
@_@
#27
to songhtao(三十年孤独):
大型的用于数据查询的数据库的确顺序不重要,
但我偏偏要有录入顺序,企业里的报表全都有顺序,没有顺序就是不行
大型的用于数据查询的数据库的确顺序不重要,
但我偏偏要有录入顺序,企业里的报表全都有顺序,没有顺序就是不行
#28
顺序号不需要连续, 尽管删除, 不需要整理。
因为取数时是:
select * from mytable order by seqno, subno;
不联号根本不是问题。
#29
我的想法是,就是用整数做顺序编号,编号之间间隔较大,比如取step=1000,
每当插入一条时,取上下两条号的平均值做为新的顺序号,
坏的情况(间隔已为1):
从要插的位置往下找有间隙的顺序号,找到后,求新的平均间隔,
倒着往上调整顺序号,就可插入;
最极端坏的情况,到末尾间隔都为1就是大调整了, 间隔号改为step,
大家分析一下,怎样?!
每当插入一条时,取上下两条号的平均值做为新的顺序号,
坏的情况(间隔已为1):
从要插的位置往下找有间隙的顺序号,找到后,求新的平均间隔,
倒着往上调整顺序号,就可插入;
最极端坏的情况,到末尾间隔都为1就是大调整了, 间隔号改为step,
大家分析一下,怎样?!
#30
>>BCB
可以, 与这个方法实出一辙:
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
步长的选择比较关键, 我觉得对一般的应用而言, 100 足够, 当然, 越大需要调整的可能九越小, 1000也不错, 绝对可以解决你的问题了。(建议100)。
可以, 与这个方法实出一辙:
SeqNo SubNo Name
1 0 V
2 0 M
3 0 J
4 0 K
5 0 L
6 0 N
步长的选择比较关键, 我觉得对一般的应用而言, 100 足够, 当然, 越大需要调整的可能九越小, 1000也不错, 绝对可以解决你的问题了。(建议100)。
#31
求平均值的办法,所以在同一处插入约 log2(Step)次,就要面临小调整,
若取step=100,同一处6次左右就要调整了,step取1000,10次
根据需要了
若取step=100,同一处6次左右就要调整了,step取1000,10次
根据需要了
#32
说说我的管见。
首先,我觉得大型数据库中,数据行号的概念是很模糊的,记录的物理存储位置也很模糊,对于用户来说,任务是安排数据的录入而不是强迫数据库按照我们的思路进行操作。
我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际发生的情况决定,而流水号用存储过程/触发器的方法解决。
如果采用预留一定间隔的流水号的方式,一是很难确定间隔,二是很难排除极端情况。在大型数据库中,选择一个合理的流水号,甚至可能会引起若干个数据库物理文件的操作,从这点看,预留号带来的好处是微不足道的。而且,这样做也破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢?
首先,我觉得大型数据库中,数据行号的概念是很模糊的,记录的物理存储位置也很模糊,对于用户来说,任务是安排数据的录入而不是强迫数据库按照我们的思路进行操作。
我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际发生的情况决定,而流水号用存储过程/触发器的方法解决。
如果采用预留一定间隔的流水号的方式,一是很难确定间隔,二是很难排除极端情况。在大型数据库中,选择一个合理的流水号,甚至可能会引起若干个数据库物理文件的操作,从这点看,预留号带来的好处是微不足道的。而且,这样做也破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢?
#33
请不要使用连续号,要使用离散号。
应该这样:日期+时间+三位序号。
第一次生成时序号自动为000。
例如生成这样一组熟:(ABC)20001201100908000,20001201100912000,20001201100913000要在BC之间插入一个数字就可以为20001201100912100
应该这样:日期+时间+三位序号。
第一次生成时序号自动为000。
例如生成这样一组熟:(ABC)20001201100908000,20001201100912000,20001201100913000要在BC之间插入一个数字就可以为20001201100912100
#34
TR@SOE,
>>我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际
>>发生的情况决定,而流水号用存储过程/触发器的方法解决。
你在触发器里做了什么? 调整流水号以使新增的纪录逻辑上位于用户为它选定的位置, 是吗?
那么这个纪录的插入是不是也"破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢? "
实际上我觉得需要牵涉其他记录甚至其他表的机会是现实存在的, 不需要刻意回避。
>>我还是推荐用台帐发生的日期和时间的方式来解决,并结合流水号。日期/时间由用户根据实际
>>发生的情况决定,而流水号用存储过程/触发器的方法解决。
你在触发器里做了什么? 调整流水号以使新增的纪录逻辑上位于用户为它选定的位置, 是吗?
那么这个纪录的插入是不是也"破坏了插入一个数据这么个简单操作的简单本质:为什么一个记录的操作要牵涉到另外两个记录呢? "
实际上我觉得需要牵涉其他记录甚至其他表的机会是现实存在的, 不需要刻意回避。
#35
>>请不要使用连续号,要使用离散号。
>>应该这样:日期+时间+三位序号。
这个与BCB的以1000为步长的得离散序号方式基本一致。
>>求平均值的办法,所以在同一处插入约 log2(Step)次,就要面临小调整,
>>若取step=100,同一处6次左右就要调整了,step取1000,10次
>>根据需要了
你这样在需要调整时反而更复杂, 如果插入是如此频繁的操作, 还不如:
MyTable:
SeqNo SubNo Name
把SeqNo和SubNo都设为32位整数, 如果要在SeqNo=1000, SubNo= 50的纪录前
插一个记录:
update MyTable set subno=subno+1 where SeqNo=1000 and SubNo >=50
这样的好处是通过SeqNo 尽可能缩小了需要调整的纪录的范围。 32位尽够你插入记录了,
所以不存在SeqNo调整的问题。
>>应该这样:日期+时间+三位序号。
这个与BCB的以1000为步长的得离散序号方式基本一致。
>>求平均值的办法,所以在同一处插入约 log2(Step)次,就要面临小调整,
>>若取step=100,同一处6次左右就要调整了,step取1000,10次
>>根据需要了
你这样在需要调整时反而更复杂, 如果插入是如此频繁的操作, 还不如:
MyTable:
SeqNo SubNo Name
把SeqNo和SubNo都设为32位整数, 如果要在SeqNo=1000, SubNo= 50的纪录前
插一个记录:
update MyTable set subno=subno+1 where SeqNo=1000 and SubNo >=50
这样的好处是通过SeqNo 尽可能缩小了需要调整的纪录的范围。 32位尽够你插入记录了,
所以不存在SeqNo调整的问题。
#36
用'日期/时间' 解决不了关键字唯一问题,也不要由用户自已决定值
#37
to ALNG:
你用两个关键字更不好,两个关键字其本质 跟加大Step是一回事!
你用两个关键字更不好,两个关键字其本质 跟加大Step是一回事!
#38
两个关键字(每个32b)相当于 step=65535
#39
ALNG,
我没有要求在触发器中调整流水号以确定位置啊,那是单纯的流水号而已。
BCB,
你应该定出你的记录物理定位的最小标准,如果日期+时间还不能够满足你的要求,那么继续增加判定标准,如单据的流水号等。这样的话,即使2001/06/26 13:00的记录在2001/06/26 08:00的记录之前登录,也有办法根据根据单据的流水号来进一步判断先后次序。这里当然还有个实际工作中的操作问题,例如,如果你的单据分发时是1-100给一个人,101-200给另一个业务员,那么可能会出现2001/06/26 12:00 101的记录发生在2001/06/26 12:00 99记录之前的情况。但是,我觉得这种可能性不会太多了。
我还是建议不要用预留号的方法。总之,你要自己定出完全可以物理上确定你的记录的先后次序的字段集。否则,任何方法都不能解决你的问题。
我没有要求在触发器中调整流水号以确定位置啊,那是单纯的流水号而已。
BCB,
你应该定出你的记录物理定位的最小标准,如果日期+时间还不能够满足你的要求,那么继续增加判定标准,如单据的流水号等。这样的话,即使2001/06/26 13:00的记录在2001/06/26 08:00的记录之前登录,也有办法根据根据单据的流水号来进一步判断先后次序。这里当然还有个实际工作中的操作问题,例如,如果你的单据分发时是1-100给一个人,101-200给另一个业务员,那么可能会出现2001/06/26 12:00 101的记录发生在2001/06/26 12:00 99记录之前的情况。但是,我觉得这种可能性不会太多了。
我还是建议不要用预留号的方法。总之,你要自己定出完全可以物理上确定你的记录的先后次序的字段集。否则,任何方法都不能解决你的问题。
#40
我主要是完整的讨论算法,所以要考虑极端情况,
step稍更大一点,基本就不会要多次调整更多的顺序号了,
当然,编了程序你就得考虑极端情况,"万一"出现呢.
step稍更大一点,基本就不会要多次调整更多的顺序号了,
当然,编了程序你就得考虑极端情况,"万一"出现呢.
#41
你用时间作辅助关键字就不代表极端情况不出现,
处理极端情况更复杂了,
就用间隔数字+调整的办法
最简单,我已试好.能满足一般要求,顺序号对用户
是透明的.
处理极端情况更复杂了,
就用间隔数字+调整的办法
最简单,我已试好.能满足一般要求,顺序号对用户
是透明的.
#42
总会有一天,你编数据库时,用户要求能随意"插入"记录,
(而你说,我只能插在末尾,顺序并不重要)
所以讨论这个问题是很有必要的
(而你说,我只能插在末尾,顺序并不重要)
所以讨论这个问题是很有必要的
#43
>>两个关键字其本质 跟加大Step是一回事!
>>两个关键字(每个32b)相当于 step=65535 (65536^2-1)
没错, 也才相当于一个INT64啊。
而且我反对在插入时搞复杂的算法, 因为你不是在操作内存, 你需要和DBMS通讯越少,速度就
越快。
看看你的算法:
Seq Name
1 A
1001 B
2001 C
在B之前插入,
1。 get the seq no of the one immediately before 1001, 1
2. the intended position 1+10001/2=501;
3. Insert the new record
This works pretty nice, but when you come accross such a positon as:
1 A
501 D
751 E
876 F
938 G
...
1000 P
1001 B
2001 C
the adjustment won't be an easy task.
So I 'd suggest that you KISS. Design a sophisticated algorithm for such a job may not be worthwhile, IMHO.
>>两个关键字(每个32b)相当于 step=65535 (65536^2-1)
没错, 也才相当于一个INT64啊。
而且我反对在插入时搞复杂的算法, 因为你不是在操作内存, 你需要和DBMS通讯越少,速度就
越快。
看看你的算法:
Seq Name
1 A
1001 B
2001 C
在B之前插入,
1。 get the seq no of the one immediately before 1001, 1
2. the intended position 1+10001/2=501;
3. Insert the new record
This works pretty nice, but when you come accross such a positon as:
1 A
501 D
751 E
876 F
938 G
...
1000 P
1001 B
2001 C
the adjustment won't be an easy task.
So I 'd suggest that you KISS. Design a sophisticated algorithm for such a job may not be worthwhile, IMHO.
#44
!
#45
并没有复杂的算法: 上、下记录编号相加/2为新插入的顺序编号,
稍复杂的部分就是处理极端情况(不能不考虑呀)
给分了!
稍复杂的部分就是处理极端情况(不能不考虑呀)
给分了!
#46
你说的顺序已经有商业含义了,应该用程序保证,即在表中加一个字段,
并且用程序来维护。最好不要用数据库来实现。
并且用程序来维护。最好不要用数据库来实现。
#47
在数据库设计的时间,增加个时间字段,如datetimestamp
以此为索引,就可以插入了。插入时构造个时间,就行了
不是很简单的//hehe
以此为索引,就可以插入了。插入时构造个时间,就行了
不是很简单的//hehe
#48
谁能告诉我win98下的vtoolsd开发工具包到哪里下载?email: mylanchat@163.com
#49
用链表可以解决
#50
to xiaoyu():
插多了,就没有中间"时间"可插了,你同样会遇到极端情况;
我说哑了,也没人听得进去.
插多了,就没有中间"时间"可插了,你同样会遇到极端情况;
我说哑了,也没人听得进去.