Pregunta

I have users that enter some data and each time they do that they also enter a keyword. One. Now what I would like to do is to store the last N keywords they entered because it seems that they tend to enter the regular few more frequently than not.

I could just create a SQL table to store these

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

But then this table would have a lot of data in time. I could delete outdated records, but I would like to implement it as a smaller table that doesn't really grow with time but rather with users.

Another possibility would be to have this kind of table

create table UserKeywordsUsed (
    UserId int not null references...,
    Keyword1 nvarchar(50) not null,
    Keyword2 nvarchar(50) not null,
    ...
    KeywordN nvarchar(50) not null
)

But I really don't know how to implement to update the correct column of this table. I could add an additional tinyint column that would store the head of the queue, but then again I would need to make a select + an update to make this to work.

Is there any other (possibly better) way of doing this?

Edit

I would also like to avoid duplicates of course and if possible making existing ones (when duplicate would need to be inserted) most recent...

¿Fue útil?

Solución

Wide table approach

It feels a bit kludgy and probably not terribly efficient but you could update all the columns in your update e.g.

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

From an efficiency standpoint, you might want to think about datatypes (might want to consider CHAR over VARCHAR because you can be certain rows will not need to be resized).

Multi-row Approach

You could simply issue an update on the oldest record in the table such as (I think this is the correct SQL server TOP syntax, but TSQL is my least-known dialect) :

update UserKeyWordsUsed set keyword=?
 where userid=?
   and CreatedOn = (SELECT TOP 1 CreatedOn
                      FROM UserKeyWordsUsed
                     WHERE userId= ?
                  ORDER BY CreatedOn);

In this case you would probably want to create your 10 records when you create the user or perform the preflight check before issuing updates.

You could also have a post-insert trigger delete the older record, but it seems like it would be simpler if you just handled via an update.

Depending on your usage, you could also move this to the application layer and have the DB just store a text representation of a token-separated keyword list.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top