Question

I want to create a table with a field that is unique and limited to a certain value. Lets say that the limit is 100, the table is full, I remove a random row, and when I create a new row it has the value that was freed before. It doesn't need to be the fastest thing in the world (the limit is quite small), I just want to implement it in a DB. Any ideas?

Was it helpful?

Solution 2

This solution does everything in a trigger, so you can just use a normal INSERT.

For the table itself, we use an autoincrementing ID column:

CREATE TABLE MyTable(ID INTEGER PRIMARY KEY, Name);

We need another table to store an ID temporarily:

CREATE TABLE moriturus(ID INTEGER PRIMARY KEY);

And the trigger:

CREATE TRIGGER MyTable_DeleteAndReorder
AFTER INSERT ON MyTable
FOR EACH ROW
WHEN (SELECT COUNT(*) FROM MyTable) > 100
BEGIN
    -- first, select a random record to be deleted, and save its ID
    DELETE FROM moriturus;
    INSERT INTO moriturus
      SELECT ID FROM MyTable
      WHERE ID <> NEW.ID
      ORDER BY random()
      LIMIT 1;

    -- then actually delete it
    DELETE FROM MyTable
      WHERE ID = (SELECT ID
                  FROM moriturus);

    -- then change the just inserted record to have that ID
    UPDATE MyTable
      SET ID = (SELECT ID
                FROM moriturus)
      WHERE ID = NEW.ID;
END;

OTHER TIPS

Create one more column in main table, say deleted (integer, 0 or 1). When you need to delete with certain id, do not really delete it, but simply update deleted to 1:

UPDATE mytable SET deleted=1 WHERE id = <id_to_delete>

When you need to insert, find id to be reused:

SELECT id FROM mytable WHERE deleted LIMIT 1

If this query returns empty result, then use INSERT to create new id. Otherwise, simply update your row:

UPDATE mytable SET deleted=0, name='blah', ... WHERE id=<id_to_reuse>

All queries reading from your main table should have WHERE constraint with NOT deleted condition:

SELECT * FROM mytable WHERE NOT deleted

If you add index on deleted, this method should work fast even for large number of rows.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top