SQL中的链接列表

最好的方法是在mysql数据库中存储一个链表,这样插入就很简单了(也就是说,你不必每次重新编译一堆东西),并且可以很容易地按顺序拖出列表。

在表格中存储一个称为“位置”的整数列。 为列表中的第一个项目logging一个0,为第二个项目logging一个1等等。在数据库中索引该列,并且当您想要将值拉出时,按该列进行sorting。

alter table linked_list add column position integer not null default 0; alter table linked_list add index position_index (position); select * from linked_list order by position; 

要在索引3处插入一个值,请修改第3行和以上的位置,然后插入:

  update linked_list set position = position + 1 where position >= 3; insert into linked_list (my_value, position) values ("new value", 3); 

使用阿德里安的解决scheme,而不是递增1,增加10或甚至100.然后插入可以计算的差异的一半你插入之间,而不必更新插入以下的所有内容。 select一个足够大的数字来处理您的平均插入次数 – 如果它太小,那么在插入过程中,必须重新更新所有具有更高位置的行。

使用两个自引用列PreviousID和NextID创build一个表。 如果该项目是列表中的第一个事件,则PreviousID将为空,如果它是最后一个,那么NextID将为空。 SQL将如下所示:

 create table tblDummy { PKColumn int not null, PreviousID int null, DataColumn1 varchar(50) not null, DataColumn2 varchar(50) not null, DataColumn3 varchar(50) not null, DataColumn4 varchar(50) not null, DataColumn5 varchar(50) not null, DataColumn6 varchar(50) not null, DataColumn7 varchar(50) not null, NextID int null } 

最简单的select是创build一个表,每个列表项有一行,项目位置的列和项目中其他数据的列。 然后,您可以使用位置列上的ORDER BY以所需顺序进行检索。

 create table linked_list ( list_id integer not null , position integer not null , data varchar(100) not null ); alter table linked_list add primary key ( list_id, position ); 

要操纵列表只需更新位置,然后根据需要插入/删除logging。 所以要在索引3处插入一个项目到列表1中:

 begin transaction; update linked_list set position = position + 1 where position >= 3 and list_id = 1; insert into linked_list (list_id, position, data) values (1, 3, "some data"); commit; 

由于列表上的操作可能需要多个命令(例如,插入操作需要INSERT和UPDATE),因此请确保始终在事务中执行命令。

这个简单的选项的一个变种是,每个项目的位置增加一些因素,比如100,这样当你执行一个INSERT时,并不总是需要重新编号以下元素的位置。 但是,这需要花费更多的精力去计算何时增加下列元素,所以如果你有很多插入的话,你会失去简单性,但是获得性能。

根据您的要求,其他选项可能会有吸引力,例如:

  • 如果你想在列表上执行大量的操作,而不是很多的检索,你可能希望有一个ID列指向列表中的下一个项目,而不是使用位置列。 然后,您需要在列表检索中的迭代逻辑,以获得项目的顺序。 这可以相对容易地在存储过程中实现。

  • 如果您有很多列表,将列表序列化并反序列化为文本/二进制文件的快速方法,并且您只想存储和检索整个列表,然后将整个列表作为单个值存储在单个列中。 可能不是你在这里要求的。

链表可以使用表中的recursion指针存储。 这是非常相同的层次结构存储在SQL中,这是使用recursion关联模式。

你可以在这里了解更多。

我希望这有帮助。

这个post是旧的,但仍然会给我0.02美元。 更新表或logging集中的每个logging听起来很疯狂,以解决sorting。 索引量也很疯狂,但是听起来像是大部分都接受了它。

我想出了一个疯狂的解决scheme,以减less更新和索引是创build两个表(并在大多数情况下,你只是在一个表中sorting所有logging)。 表A保存正在sorting的列表的logging,表B列出并将订单的logging保存为string。 订单string表示可用于在网页应用程序的Web服务器或浏览器层上对所选logging进行sorting的数组。

 Create Table A{ Id int primary key identity(1,1), Data varchar(10) not null B_Id int } Create Table B{ Id int primary key Identity(1,1), GroupName varchat(10) not null, Order varchar(max) null } 

命令sting的格式应该是id,position和一些分隔符来分割()你的string。 在jQuery UI的情况下,.sortable('serialize')函数为您输出一个POST友好的命令string,其中包括列表中每个logging的ID和位置。

真正的魔法是您select使用保存的sortingstring重新sorting所选列表的方式。 这将取决于你正在build立的应用程序。 这里是一个例子再次从jQuery重新sorting项目列表: http : //ovisdevelopment.com/oramincite/?p=155

这是我一直想弄清楚的一段时间。 到目前为止,我发现的最好方法是使用以下格式(这是伪代码)为链表创build单个表:

链表(

  • KEY1,
  • 信息,
  • KEY2

key1是起点。 Key2是在下一列中链接到自身的外键。 所以你的专栏将链接这样的东西链接

COL1

  • key1 = 0,
  • 信息='你好'
  • key2 = 1

Key1是col1的主键。 key2是通向col2的key1的外键

COL2

  • key1 = 1,
  • 信息='wassup'
  • key2 = null

col2中的key2被设置为null,因为它不指向任何东西

当你第一次input表格的列时,你需要确保key2被设置为null,否则你会得到一个错误。 进入第二列后,您可以返回并将第一列的key2设置为第二列的主键。

这是最好的方法,一次input许多条目,然后返回并相应地设置外键(或者构build一个GUI,只是为你做)

下面是我准备的一些实际的代码(所有实际的代码都在MSSQL上工作,你可能想对你使用的SQL版本做一些研究):

createtable.sql

 create table linkedlist00 ( key1 int primary key not null identity(1,1), info varchar(10), key2 int ) 

register_foreign_key.sql

 alter table dbo.linkedlist00 add foreign key (key2) references dbo.linkedlist00(key1) 

*我把它们分成两个独立的文件,因为它必须分两步完成。 MSSQL不会让你在一步做到这一点,因为该表还不存在供外键参考。

链接列表在一对多的关系中尤其强大。 所以,如果你曾经想要创build一个外键的数组? 那么这是一个办法呢! 您可以创build一个指向链接表中第一列的主表,然后代替“信息”字段,可以使用外键指定所需的信息表。

例:

假设你有一个保持forms的官僚机构。

比方说,他们有一个名为文件柜的表

文件柜(

  • 内阁ID(PK)
  • 文件ID(fk))

每列包含一个主机键和一个外键的文件。 这些文件可以是税务表格,健康保险文件,实地考察许可证等

文件(

  • 文件ID(PK)

  • 文件ID(fk)

  • 下一个文件ID(fk)

这作为文件的容器

文件(

  • 文件ID(pk)

  • 有关该文件的信息

这是特定的文件

有可能有更好的方法来做到这一点,这取决于你的具体需求。 这个例子只是说明可能的用法。

我可以从中思考几种方法,每种方法都具有不同程度的复杂性和灵活性。 我假设你的目标是维护一个订单检索,而不是要求存储作为一个实际的链表。

最简单的方法是为表中的每个logging分配一个序数值(例如1,2,3,…)。 然后,当您检索logging时,请在序号列上指定一个订单以使其恢复顺序。

这种方法还允许您检索logging,而不考虑列表中的成员资格,但只允许一个列表中的成员资格,并且可能需要额外的“列表编号”列来指示该logging属于哪个列表。

稍微更详细一些,但也更灵活的方法是将关于成员资格的信息存储在列表或列表中的单独表格中。 该表需要3列:列表ID,序号值和数据logging的外键指针。 在这种方法下,基础数据对列表中的成员资格一无所知,并且可以很容易地包含在多个列表中。

我认为它更简单的添加一个创build的Datetimetypes的列和一个int的位置列,所以现在你可以有重复的位置,在select语句使用order by位置的order by ,创builddesc选项,你的列表将按顺序获取。

将SERIAL'索引'增加100,但手动添加'索引'等于Prev + Next / 2的中间值。如果您曾饱和100行,请将索引重新sorting为100秒。

这应该保持主索引的顺序。

一个列表可以通过让一个列包含偏移量(列表索引位置)来存储 – 中间的一个插入然后递增所有在新父项之上,然后进行插入。