Is auto increment guaranteed to keep incrementing? - sql

If I have a integer column in h2 and use auto increment for it, is it guaranteed to always increment the last inserted value?
-- If some intermediate row is deleted.
-- If last inserted row is deleted.
-- If all rows are deleted using delete from myTable
EDIT: The reason I need the numbering continued (and I would expect this to be the normal behavior) is I am looking to archive older data to keep current tables short.

The auto-incremented value is guaranteed to always be larger than the previous value. It is not guaranteed to always be exactly one more than the last successfully inserted value.
The latter requires much more overhead and is not (generally) worth the additional effort.

Related

TTL on table: what about updates?

I have a table in which rows must expire after a month or so. When a row is created, it can be updated. I was curious if the update would bypass the TTL and would exist forever, since the update does not contain any TTL. This is what the docs are saying:
https://docs.scylladb.com/stable/cql/time-to-live.html
Here a TTL of 10 minutes is applied to all rows, however, keep in mind
that TTL is stored on a per column level for non-primary key columns.
I don't understand what this means. What does setting a TTL means for primary key columns? I just want my rows to be deleted after a certain time.
My question is: will an insert/update without TTL overwrite the tables TTL? Will setting a TTL simply delete the row after a certain time? Will the TTL reset for the row after an update statement (without ttl)?
Thanks.
This is an interesting question, and answering it accurately requires some subtleties.
First you need to know that in CQL, the expiration time is stored together with each cell (column value), not for an entire row. So if you INSERT a row with a=1, b=2 and c=3 with some TTL X, the TTL isn't stored once for the entire row - rather, each of the three columns will be stored with TTL X separately. If you later UPDATE only column a with TTL Y, you'll now have the a value expiring at one time and b and c expiring at a different time (this is fine for CQL - you are allowed to have a row where some of its columns are undefined (null)). If you update a column without specifying the TTL, the new value will never expire - it will not remember the previous TTL.
You may be asking yourself why doesn't updating one column (or all of the columns) of an existing row just keep the previous TTL value. Well, this is because one of the design goals of Scylla (and Cassandra) is to make writes are fast as possible. Scylla does writes fast precisely because it does not need to read the old value first. When you update x=1 Scylla just writes down that update ("mutation"), and doesn't need to read the previous value. Scylla will only needs to reconcile the different versions of the value (the one with the highest timestamp wins) during read or on a special "compaction" step that happens periodically. With this in mind, when you set x=1 with TTL y (or if TTL not set at all, infinity), this will be the new value of this column - the older TTL value isn't available during this update.
To answer your question about primary keys there's something else you need to know: In CQL, a row "exists" by virtue of having some live non-key columns. For example if your primary key is p, when you insert p=1,x=2 you basically inserting x=2 (non-key) into the row at p=1. If the x=2 expires, the entire row disappears. That's why the TTL is relevant only to non-key columns.
Well, I actually cheated a little bit in the last paragraph, and there's another subtlety here that I didn't explain. Maybe you noticed that it is possible to INSERT a row and then use UPDATE to delete each one of its columns individually, and you are left with an empty row, which still exists but is empty. How does this work, when I said that a row needs non-key cells to exist? Well, the trick is that the INSERT not only adds the specific columns you asked for (x=2), it also adds another invisible empty-named column (called the "CQL row marker"). When you later delete the individual columns, the row-marker column remains undeleted and keeps the row alive. When you INSERT a row with a TTL x, this command not only sets the TTL of each specified column to x, it also sets the TTL of the hidden row-marker column to x, so when x comes the entire row disappears because all its columns (including the row-marker column) have disappeared. Note that only INSERT, not UPDATE, adds this row marker. This means that if you want to change the TTL of the row marker, you must do this by doing an INSERT, not an UPDATE. For example, if you INSERT data with TTL x, and later UPDATE overwriting all its columns to an earlier expiration time, you'll end up with the data columns expiring early but the row marker remaining until its original expiration - and until then an empty row is visible.

Questions about increment operator

I have a table with a field that increments. The values for that field are 1, 2, 3...60 and then the field is 1060.
I don't know why?
The next value for id must be 61.
This is a new feature of SQL Server 2012. Identity columns use Sequences and values are cashed by default to speed up when inserting new rows. When unplanned shutdown of SQL Server occurs, cache is lost and Identity values continue with gap (of usually 1000 or 10000) created.
There could be several reasons - some of the most likely:
999 records were deleted
999 inserts were attempted and failed
Something reset the identity value using DBCC CHECKIDENT ({table}, RESEED, {value});
Something inserted a record with a specific ID using SET IDENTITY_INSERT ON
Autoincrement fields are not guaranteed to be consecutive. Thy are guaranteed to be unique. If you need them to be consecutive, then I would recommend keeping track of the next ID yourself, which will require you to think about concurrency, foreign key references, etc.
Am assuming you mean an IDENTITY field with an increment of 1.
This increases the value by 1 each time a new record is inserted.
To quote:
If an identity column exists for a table with frequent deletions, gaps
can occur between identity values. If this is a concern, do not use
the IDENTITY property. However, to ensure that no gaps have been
created or to fill an existing gap, evaluate the existing identity
values before explicitly entering one with SET IDENTITY_INSERT ON.
As alluded to in the comments it's likely this table once had data populated with all the missing values but these were deleted. (As this is quite a big chunk maybe this was done in bulk?)

DB2 auto increment changed by itself after restarted

Each time I restart my DB2 services, the auto increment field, always change by itself,
for example : before I restart, the auto increment value is at 13, and it's incremented by 1, and after I restart it's always become 31 and it's always incremented by 20
Any idea what may cause this?
Each time I restarted my Db2 service, I have to execute this command
ALTER TABLE <table> ALTER COLUMN <column> RESTART WITH 1
DB2 has a cache of generated values in order to reduce the overhead of generating values (Reduce the IO). This cache in memory, and assign the values as requested.
Take a look at the cache option when creating / altering the table. By default the cache value is 20.
It is important to understand how the sequeneces work in DB2. Sequences share many concepts with generated values / identity column.
Create table http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000927.html
Alter table http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000888.html
Sequences http://publib.boulder.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.admin.dbobj.doc/doc/c0023175.html
From W3schools:
"Auto-increment allows a unique number to be generated when a new record is inserted into a table."
This is the only thing you may expect: unique (=non-conflicting) numbers. How these are generated is left to the DBMS. You must not expect a number sequence without any gaps.
For instance, a DBMS might choose to "pre-allocate" blocks of ten numbers (23..32, 33..42, ...) for performance reasons, so that the auto-increment field must only be incremented for every (up to) ten records. If you have an INSERT statement that inserts only 5 records into a newly created table, it can "acquire a block of 10 numbers" (0..9), use the first five values (0..4) of it and leave the rest unused. By acquiring this one block of numbers, the counter was incremented from 0 to 10. So the next INSERT statement that fetches a block will get the numbers ranging from 10 to 19.

Postgresql wrong auto-increment for serial

I have a problem on postgresql which I think there is a bug in the postgresql, I wrongly implement something.
There is a table including colmn1(primary key), colmn2(unique), colmn3, ...
After an insertion of a row, if I try another insertion with an existing colmn2 value I am getting a duplicate value error as I expected. But after this unsuccesful try, colmn1's next value is
incremented by 1 although there is no insertion so i am getting rows with id sequences like , 1,2,4,6,9.(3,5,6,7,8 goes for unsuccessful trials).
I need help from the ones who can explain this weird behaviour.
This information may be useful: I used "create unique index on tableName (lower(column1)) " query to set unique constraint.
See the PostgreSQL sequence FAQ:
Sequences are intended for generating unique identifiers — not
necessarily identifiers that are strictly sequential. If two
concurrent database clients both attempt to get a value from a
sequence (using nextval()), each client will get a different sequence
value. If one of those clients subsequently aborts their transaction,
the sequence value that was generated for that client will be unused,
creating a gap in the sequence.
This can't easily be fixed without incurring a significant performance
penalty. For more information, see Elein Mustein's "Gapless Sequences for Primary Keys" in the General Bits Newsletter.
From the manual:
Important: Because sequences are non-transactional, changes made by
setval are not undone if the transaction rolls back.
In other words, it's normal to have gaps. If you don't want gaps, don't use a sequence.

Custom sequence in postgres

I need to have a custom unique identifier (sequence). In my table there is a field ready_to_fetch_id that will be null by default and when my message is ready to be delivered then i make it update with unique max id, this is quite heavy process as load increasing.
So it it possible to have some sequence in postgres that allow null and unique ids.
Allowing NULL values has nothing todo with sequences. If your column definition allows NULLs you can put NULL values in the column. When you update the column you take the nextval from the sequence.
Notice that if you plan to use the ids to keep track of which rows you have already processed that it won't work perfectly. When two transactions are going to update the ready_to_fetch_id column simultaneous the transaction that started last might commit first which means that the higher id of the last transaction to start will become visible before the lower id the earlier transaction is using.