Sql server 在SQL中实现循环列表式结构

Sql server 在SQL中实现循环列表式结构,sql-server,tsql,circular-list,Sql Server,Tsql,Circular List,我有一些用户输入一些数据,每次输入数据时,他们也会输入一个关键字。一个。现在我想做的是存储他们输入的最后N个关键字,因为他们似乎倾向于更频繁地输入常规的几个关键字 我可以创建一个SQL表来存储这些数据 create table UserKeywordsUsed ( UserId int not null references..., Keyword nvarchar(50) not null, CreatedOn datetime not null default get

我有一些用户输入一些数据,每次输入数据时,他们也会输入一个关键字。一个。现在我想做的是存储他们输入的最后N个关键字,因为他们似乎倾向于更频繁地输入常规的几个关键字

我可以创建一个SQL表来存储这些数据

create table UserKeywordsUsed (
    UserId int not null references...,
    Keyword nvarchar(50) not null,
    CreatedOn datetime not null default getdate()
)

但是这张表会及时有很多数据。我可以删除过时的记录,但我想将其实现为一个较小的表,它不会真正随着时间而增长,而是随着用户而增长

另一种可能是有这种桌子

create table UserKeywordsUsed (
    UserId int not null references...,
    Keyword1 nvarchar(50) not null,
    Keyword2 nvarchar(50) not null,
    ...
    KeywordN nvarchar(50) not null
)
但是我真的不知道如何实现更新这个表的正确列。我可以添加一个额外的
tinyint
列来存储队列的头部,但是我需要再次进行select+an更新才能使其正常工作

还有其他(可能更好的)方法吗?

编辑 当然,我也希望避免重复,如果可能的话,使用最新的…

宽表方法制作现有的(当需要插入重复项时) 这感觉有点笨拙,可能效率不太高,但你可以更新更新中的所有列,例如

UPDATE userkeywords SET key3=key2, key2=key1, key1=? where userid=?

从效率的角度来看,您可能需要考虑数据类型(可能需要考虑VARCHAR上的字符,因为您可以确定某些行不需要调整大小)。 多行法 您可以简单地对表中最旧的记录进行更新,例如(我认为这是正确的SQL server TOP语法,但TSQL是我最不熟悉的方言):

在这种情况下,您可能希望在创建用户或在发布更新之前执行飞行前检查时创建10条记录

您还可以使用插入后触发器来删除旧记录,但如果您只是通过更新来处理,则似乎会更简单


根据您的使用情况,您还可以将其移动到应用程序层,让DB只存储令牌分隔关键字列表的文本表示。

一个后插入触发器,删除每个用户的所有行,但每个用户最后N行除外???@M.Ali:Performance?缓慢(er)插入…“但是这个表会及时有很多数据”-你确定这会给你带来问题吗?将会有多少用户,每秒钟使用多少关键字(秒、小时、天、月等?)。数据库是定期建立的,可以处理数百万行而没有问题。@Damien_The_unsiever:你说得对。此表行将非常小(两个整数和一个datetime=4+4+8字节=16字节),拥有所有历史记录仍将执行得很快。我希望用户只操作有限数量的关键字,而不是整个关键字集。否则,表大小将为关键字×用户。我预计该表在未来几年内保存的记录将少于1000万条,这意味着每百万条记录中有16MB的记录(仅数据不包括索引)。使用多行方法,使用
merge
语句可以避免准备好的“空白”吗?但除此之外,我喜欢这两种方法,尽管多行方法似乎更通用。请注意我编辑的问题中的额外要求。
update UserKeyWordsUsed set keyword=?
 where userid=?
   and CreatedOn = (SELECT TOP 1 CreatedOn
                      FROM UserKeyWordsUsed
                     WHERE userId= ?
                  ORDER BY CreatedOn);